ID change enhancements

This commit is contained in:
emanuel 2021-04-21 19:08:40 +01:00
parent 3ff7b812fe
commit e2235a69ec
5 changed files with 95 additions and 32 deletions

View File

@ -90,9 +90,9 @@ static int mk_cam(facilities_t* facilities, uint8_t *cam_oer, uint32_t *cam_len)
cam->header.protocolVersion = 2;
cam->header.messageID = ItsPduHeader__messageID_cam;
pthread_mutex_lock(&facilities->lock);
cam->header.stationID = facilities->station_id;
pthread_mutex_unlock(&facilities->lock);
pthread_mutex_lock(&facilities->id.lock);
cam->header.stationID = facilities->id.value;
pthread_mutex_unlock(&facilities->id.lock);
cam->cam.camParameters.basicContainer.stationType = facilities->station_type;

View File

@ -176,12 +176,15 @@ int facilities_config(void* facilities_s) {
facilities->use_security = config->security.use_security;
facilities->id_random = config->security.identity.random;
if (facilities->id_random) {
pthread_mutex_init(&facilities->id.lock, NULL);
pthread_mutex_init(&facilities->id.change.lock, NULL);
facilities->id.change.random = config->security.identity.random;
if (facilities->id.change.random) {
srand(time(NULL));
facilities->station_id = rand();
facilities->id.value = rand();
} else {
facilities->station_id = config->security.identity.station_id;
facilities->id.value = config->security.identity.station_id;
}
// DENM

View File

@ -209,23 +209,44 @@ static int security_indication(facilities_t *facilities, void* responder_secured
asn_dec_rval_t dec = oer_decode(NULL, &asn_DEF_SecurityIndication, (void**) &si, msg, msg_len);
if (dec.code) {
syslog_err("[networking]<- invalid SIndication received");
syslog_err("[facilities]<- invalid SIndication received");
rv = 1;
goto cleanup;
}
pthread_mutex_lock(&facilities->id.change.lock);
if (facilities->id.change.stage == ID_CHANGE_BLOCKED) {
pthread_mutex_unlock(&facilities->id.change.lock);
syslog_debug("[facilities] identity change is currently blocked");
rv = 1;
goto cleanup;
}
if (facilities->id.change.stage == ID_CHANGE_PREPARE &&
si->choice.idChangeEvent.command != SecurityIdChangeEventType_commit &&
si->choice.idChangeEvent.command != SecurityIdChangeEventType_abort) {
pthread_mutex_unlock(&facilities->id.change.lock);
syslog_debug("[facilities] current identity change state is prepare, but received identity change command is not commit nor abort");
rv = 1;
goto cleanup;
}
switch (si->choice.idChangeEvent.command) {
case SecurityIdChangeEventType_prepare:
pthread_mutex_lock(&facilities->lock);
facilities->id.change.stage = ID_CHANGE_PREPARE;
pthread_mutex_lock(&facilities->id.lock);
pthread_mutex_lock(&facilities->lightship->lock);
facilities->in_idchange = true;
break;
case SecurityIdChangeEventType_commit:
;
facilities->id.change.stage = ID_CHANGE_COMMIT;
// Change Station ID
facilities->station_id = rand();
pthread_mutex_unlock(&facilities->lock);
facilities->id.value = rand();
pthread_mutex_unlock(&facilities->id.lock);
// Reset lightship
for (int i = 0; i < facilities->lightship->pos_history_len; ++i) {
@ -238,22 +259,26 @@ static int security_indication(facilities_t *facilities, void* responder_secured
facilities->lightship->next_cam_max = 0;
facilities->lightship->next_cam_min = 0;
facilities->in_idchange = false;
pthread_mutex_unlock(&facilities->lightship->lock);
facilities->id.change.stage = ID_CHANGE_INACTIVE;
break;
case SecurityIdChangeEventType_abort:
facilities->in_idchange = false;
pthread_mutex_unlock(&facilities->lock);
pthread_mutex_unlock(&facilities->id.lock);
pthread_mutex_unlock(&facilities->lightship->lock);
facilities->id.change.stage = ID_CHANGE_INACTIVE;
break;
default:
pthread_mutex_unlock(&facilities->id.change.lock);
syslog_err("[networking]<- unhandled idChangeEvent command type");
rv = 1;
goto cleanup;
}
pthread_mutex_unlock(&facilities->id.change.lock);
sr->present = SecurityResponse_PR_idChangeEvent;
sr->choice.idChangeEvent.returnCode = 0;
@ -267,9 +292,9 @@ cleanup:
sr->choice.idChangeEvent.returnCode = 1;
enc = oer_encode_to_buffer(&asn_DEF_SecurityResponse, NULL, sr, buffer, 64);
zmq_send(responder_secured, buffer, enc.encoded, 0);
zmq_recv(responder_secured, buffer, 64, 0);
}
pthread_mutex_unlock(&facilities->id.change.lock);
ASN_STRUCT_FREE(asn_DEF_SecurityResponse, sr);
ASN_STRUCT_FREE(asn_DEF_SecurityIndication, si);
@ -382,7 +407,7 @@ int main() {
syslog_info("[facilities] starting");
facilities_t facilities;
facilities.exit = false;
memset(&facilities, 0x00, sizeof(facilities_t));
facilities.zmq.ctx = zmq_ctx_new();
facilities.lightship = lightship_init();
@ -391,15 +416,12 @@ int main() {
facilities.den = calloc(1, sizeof(den_t));
facilities.infrastructure = calloc(1, sizeof(infrastructure_t));
pthread_mutex_init(&facilities.lock, NULL);
time_t t;
srand((unsigned) time(&t));
if (facilities_config(&facilities)) return 1;
facilities.lightship->type = facilities.station_type;
facilities.in_idchange = false;
// Tx
pthread_create(&facilities.transmitting, NULL, tx, (void*) &facilities);
@ -420,6 +442,7 @@ int main() {
uint8_t buffer[PACKET_MAX_LEN];
syslog_info("[facilities] listening");
uint8_t code;
bool in_idchange;
while (!facilities.exit) {
zmq_poll(facilities.zmq.responders, facilities.zmq.n_responders, -1);
@ -430,8 +453,20 @@ int main() {
switch (buffer[0]) {
case 3:
if (!facilities.in_idchange) {
in_idchange = true;
pthread_mutex_lock(&facilities.id.change.lock);
if (facilities.id.change.stage == ID_CHANGE_INACTIVE) {
in_idchange = false;
facilities.id.change.stage = ID_CHANGE_BLOCKED;
}
pthread_mutex_unlock(&facilities.id.change.lock);
if (!in_idchange) {
transport_indication(&facilities, facilities.zmq.responders[i].socket, buffer+1, PACKET_MAX_LEN-1);
pthread_mutex_lock(&facilities.id.change.lock);
facilities.id.change.stage = ID_CHANGE_INACTIVE;
pthread_mutex_unlock(&facilities.id.change.lock);
} else {
code = 1;
zmq_send(facilities.zmq.responders[i].socket, &code, 1, 0);
@ -439,12 +474,25 @@ int main() {
break;
case 5:
if (!facilities.in_idchange) {
in_idchange = true;
pthread_mutex_lock(&facilities.id.change.lock);
if (facilities.id.change.stage == ID_CHANGE_INACTIVE) {
in_idchange = false;
facilities.id.change.stage = ID_CHANGE_BLOCKED;
}
pthread_mutex_unlock(&facilities.id.change.lock);
if (!in_idchange) {
facilities_request(&facilities, facilities.zmq.responders[i].socket, buffer+1, PACKET_MAX_LEN-1);
pthread_mutex_lock(&facilities.id.change.lock);
facilities.id.change.stage = ID_CHANGE_INACTIVE;
pthread_mutex_unlock(&facilities.id.change.lock);
} else {
code = 1;
zmq_send(facilities.zmq.responders[i].socket, &code, 1, 0);
}
break;
case 6:

View File

@ -11,6 +11,13 @@
#include "queue.h"
#include "cpm.h"
enum ID_CHANGE_STAGE {
ID_CHANGE_INACTIVE,
ID_CHANGE_BLOCKED,
ID_CHANGE_PREPARE,
ID_CHANGE_COMMIT
};
typedef struct epv {
pthread_mutex_t lock;
@ -61,10 +68,15 @@ typedef struct facilities {
bool use_security;
bool replay;
struct {
pthread_mutex_t lock;
uint64_t station_id;
bool id_random;
bool in_idchange;
uint64_t value;
struct {
pthread_mutex_t lock;
bool random;
int stage;
} change;
} id;
epv_t epv;

View File

@ -138,9 +138,9 @@ int facilities_request_single_message(facilities_t* facilities, void* responder,
if (fwd) {
// set stationID
pthread_mutex_lock(&facilities->lock);
((DENM_t*)its_msg)->header.stationID = facilities->station_id;
pthread_mutex_unlock(&facilities->lock);
pthread_mutex_lock(&facilities->id.lock);
((DENM_t*)its_msg)->header.stationID = facilities->id.value;
pthread_mutex_unlock(&facilities->id.lock);
// Set only one trace
if (facilities->station_type != 15) {
@ -409,9 +409,9 @@ int facilities_request_attribute_types(facilities_t* facilities, void* responder
fdres->result->choice.attributes.list.array[j] = calloc(1, sizeof(FacilitiesAttribute_t) );
fdres->result->choice.attributes.list.array[j]->data.size = 8;
fdres->result->choice.attributes.list.array[j]->data.buf = malloc(8);
pthread_mutex_lock(&facilities->lock);
*((uint64_t*) fdres->result->choice.attributes.list.array[j]->data.buf) = facilities->station_id;
pthread_mutex_unlock(&facilities->lock);
pthread_mutex_lock(&facilities->id.lock);
*((uint64_t*) fdres->result->choice.attributes.list.array[j]->data.buf) = facilities->id.value;
pthread_mutex_unlock(&facilities->id.lock);
break;
default: