diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d633507..ca34548 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -11,7 +11,6 @@ ADD_EXECUTABLE(it2s-itss-facilities tpm.c vcm.c evm.c - tls.c ) TARGET_LINK_LIBRARIES(it2s-itss-facilities diff --git a/src/facilities.c b/src/facilities.c index f4ad1d8..1f769b7 100644 --- a/src/facilities.c +++ b/src/facilities.c @@ -41,21 +41,18 @@ #include "saem.h" #include "tpm.h" #include "vcm.h" -#include "tls.h" facilities_t facilities = {0}; static int transport_indication(void *responder, void **security_socket, uint8_t *msg, uint32_t msg_len) { int rv = 0; uint8_t code = 0; - bool handled_msg = false; FacilitiesIndication_t *fi = NULL; SecurityRequest_t *sreq = NULL; SecurityReply_t *srep = NULL; TransportRequest_t *tr = NULL; + bool stored = false; - uint16_t buf_len = 2048; - uint8_t buf[2048]; TransportIndication_t *ti = calloc(1, sizeof(TransportIndication_t)); @@ -85,283 +82,29 @@ static int transport_indication(void *responder, void **security_socket, uint8_t TransportPacketIndication_t *tpi = &ti->choice.packet; // TODO // - bool fwd = false; - - uint64_t id = 0; - - asn_TYPE_descriptor_t *its_msg_descriptor = NULL; - void *its_msg = NULL; - int its_msg_type = 0; - uint8_t *packet = NULL; - uint16_t packet_len = 0; switch (tpi->present) { case TransportPacketIndication_PR_btp: - id = tpi->choice.btp.id; - log_debug("<- TI.packet.btp | id:%08x size:%dB", (uint32_t)id, msg_len); - // Parse message - switch (tpi->choice.btp.destinationPort) { - case Port_cam: - its_msg_descriptor = &asn_DEF_CAM; - its_msg = calloc(1, sizeof(CAM_t)); - its_msg_type = messageID_cam; - handled_msg = true; - break; - - case Port_denm: - its_msg_descriptor = &asn_DEF_DENM; - its_msg = calloc(1, sizeof(DENM_t)); - its_msg_type = messageID_denm; - handled_msg = true; - break; - - case Port_ivim: - its_msg_descriptor = &asn_DEF_IVIM; - its_msg = calloc(1, sizeof(IVIM_t)); - its_msg_type = messageID_ivim; - handled_msg = true; - break; - - case Port_cpm: - its_msg_descriptor = &asn_DEF_CPM; - its_msg = calloc(1, sizeof(CPM_t)); - its_msg_type = 14; - handled_msg = true; - break; - - case Port_saem: - its_msg_descriptor = &asn_DEF_SAEM; - its_msg = calloc(1, sizeof(SAEM_t)); - its_msg_type = messageID_saem; - handled_msg = true; - break; - - case 7011: /* tolling */ - its_msg_descriptor = &asn_DEF_TPM; - its_msg = calloc(1, sizeof(TPM_t)); - its_msg_type = 117; - handled_msg = true; - break; - - case 2043: /* maneuvers */ - its_msg_descriptor = &asn_DEF_VCM; - its_msg = calloc(1, sizeof(VCM_t)); - its_msg_type = 43; - handled_msg = true; - break; - - case 2044: /* VERCOe */ - its_msg_descriptor = &asn_DEF_VERCOe; - its_msg = calloc(1, sizeof(VERCOe_t)); - its_msg_type = 44; - handled_msg = true; - fwd = true; - break; - - case Port_poi: /* EVCSNM */ - its_msg_descriptor = &asn_DEF_EvcsnPdu; - its_msg = calloc(1, sizeof(EvcsnPdu_t)); - its_msg_type = messageID_evcsn; - handled_msg = true; - fwd = true; - break; - - case Port_evrsr: /* EVRSRM */ - its_msg_descriptor = &asn_DEF_EV_RSR; - its_msg = calloc(1, sizeof(EV_RSR_t)); - its_msg_type = messageID_evcsn; - handled_msg = true; - fwd = true; - break; - - default: - log_debug("messsage with unhandled BTP port received (%lld), ignoring", tpi->choice.btp.destinationPort); - goto cleanup; - } - - packet = tpi->choice.btp.data.buf; - packet_len = tpi->choice.btp.data.size; - - dec = uper_decode_complete(NULL, its_msg_descriptor, (void **)&its_msg, tpi->choice.btp.data.buf, tpi->choice.btp.data.size); - if (dec.code) { - log_debug("<- invalid %s received", its_msg_descriptor->name); - rv = 1; - goto cleanup; - } - - // Get permisisons - uint8_t *ssp = NULL; - uint16_t ssp_len; - if (tpi->choice.btp.gn.securityPermissions) { - ssp = tpi->choice.btp.gn.securityPermissions->ssp.buf; - ssp_len = tpi->choice.btp.gn.securityPermissions->ssp.size; - } - - // Get neighbour certificate ID - uint8_t *neighbour_cert = tpi->choice.btp.gn.securityNeighbour ? tpi->choice.btp.gn.securityNeighbour->buf : NULL; - - // Manage message - switch (tpi->choice.btp.destinationPort) { - case Port_cam: - switch (check_cam(&tpi->choice.btp, its_msg, ssp, ssp_len)) { - case CAM_OK: - fwd = true; - break; - case CAM_INVALID: - case CAM_BAD_PERMISSIONS: - default: - break; - } - break; - - case Port_denm:; -#ifdef DEBUG - uint8_t *xml_denm = malloc(32768); - asn_enc_rval_t rve = xer_encode_to_buffer(xml_denm, 32768, 0x02, &asn_DEF_DENM, its_msg); - log_debug("DENM XER %d: %.*s", (int)rve.encoded, (int)rve.encoded, xml_denm); - free(xml_denm); -#endif - switch (event_manage(its_msg, &id, ssp, ssp_len)) { - case EVENT_NEW: - case EVENT_CANCELLATION: - case EVENT_NEGATION: - case EVENT_UPDATE: - case EVENT_NUMBER_EXCEEDED: - fwd = true; - break; - case EVENT_INVALID: - case EVENT_PASSED: - case EVENT_REPEATED: - case EVENT_BAD_PERMISSIONS: - break; - } - break; - - case Port_ivim: - switch (service_eval(SERVICE_IVI, its_msg, &id, ssp, ssp_len)) { - case SERVICE_NEW: - case SERVICE_CANCELLATION: - case SERVICE_NEGATION: - case SERVICE_UPDATE: - case SERVICE_NUMBER_EXCEEDED: - fwd = true; - break; - case SERVICE_INVALID: - case SERVICE_REPEATED: - case SERVICE_PASSED: - case SERVICE_BAD_PERMISSIONS: - default: - break; - } - break; - - case Port_saem: - switch (saem_check(its_msg, neighbour_cert)) { - case SAEM_NEW: - fwd = true; - break; - default: - break; - } - break; - - case 7011: - if (facilities.tolling.enabled) { - tpm_recv(its_msg, security_socket, neighbour_cert, NULL); - fwd = true; - } - break; - - case 2043: - if (facilities.coordination.active) { - vcm_check(its_msg); - } - fwd = true; - break; - case Port_poi: - if (facilities.evm_args.activate) { - evcsnm_check(its_msg); - fwd = true; - } - break; - - case Port_evrsr: - if (facilities.evm_args.activate) { - evrsrm_check(its_msg); - fwd = true; - EV_RSR_t *evrsr_request = (EV_RSR_t *)its_msg; - evrsrm_recv(evrsr_request); - } - default: - break; - } + log_debug("<- TI.packet.btp | id:%08x size:%dB", tpi->choice.btp.id, msg_len); + transport_indication_btp(&tpi->choice.btp, security_socket); break; case TransportPacketIndication_PR_tcp: log_debug("<- TI.packet.tcp | id:%ld size:%dB", tpi->choice.tcp.id, msg_len); - tls_recv(&tpi->choice.tcp, security_socket); + transport_indication_tcp(&tpi->choice.tcp, security_socket); break; case TransportPacketIndication_PR_udp: - id = tpi->choice.udp.id; - log_debug("<- TI.packet.udp | id:%ld size:%dB", id, msg_len); + log_debug("<- TI.packet.udp | id:%ld size:%dB", tpi->choice.udp.id, msg_len); + // TODO break; default: break; } - // Forward to [applications] - if (fwd) { - fi = calloc(1, sizeof(FacilitiesIndication_t)); - fi->present = FacilitiesIndication_PR_message; - FacilitiesMessageIndication_t *fmi = &fi->choice.message; - - fmi->id = id; - - fmi->itsMessageType = tpi->choice.btp.destinationPort; - - fmi->data.size = tpi->choice.btp.data.size; - fmi->data.buf = malloc(tpi->choice.btp.data.size); - memcpy(fmi->data.buf, tpi->choice.btp.data.buf, tpi->choice.btp.data.size); - - uint8_t buffer[ITSS_SDU_MAX_LEN]; - buffer[0] = 4; // Facilities - asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_FacilitiesIndication, NULL, fi, buffer + 1, ITSS_SDU_MAX_LEN - 1); - - itss_queue_send(facilities.tx_queue, buffer, enc.encoded + 1, ITSS_APPLICATIONS, id, "FI.message"); - } - - // Logging - if (facilities.logging.dbms) { - pthread_mutex_lock(&facilities.id.lock); - uint32_t station_id = facilities.id.station_id; - pthread_mutex_unlock(&facilities.id.lock); - itss_db_add(facilities.logging.dbms, station_id, id, false, its_msg_type, NULL, packet, packet_len); - } - if (facilities.logging.recorder) { - int e = itss_management_record_packet_sdu( - buf, - buf_len, - tpi->choice.btp.data.buf, - tpi->choice.btp.data.size, - tpi->choice.btp.id, - itss_time_get(), - ITSS_FACILITIES, - false); - if (e != -1) { - itss_queue_send(facilities.tx_queue, buf, e, ITSS_MANAGEMENT, tpi->choice.btp.id, "MReq.packet.set"); - } - } cleanup: - if (handled_msg && tpi->choice.btp.destinationPort != Port_denm && tpi->choice.btp.destinationPort != Port_ivim) { - ASN_STRUCT_FREE(*its_msg_descriptor, its_msg); - } - ASN_STRUCT_FREE(asn_DEF_TransportIndication, ti); - ASN_STRUCT_FREE(asn_DEF_FacilitiesIndication, fi); - ASN_STRUCT_FREE(asn_DEF_SecurityRequest, sreq); - ASN_STRUCT_FREE(asn_DEF_SecurityReply, srep); ASN_STRUCT_FREE(asn_DEF_TransportRequest, tr); return rv; diff --git a/src/requests.c b/src/requests.c index 7fe3ff0..8cdc18b 100644 --- a/src/requests.c +++ b/src/requests.c @@ -3,6 +3,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -601,3 +604,432 @@ cleanup: return rv; } + + +int transport_indication_btp(BTPPacketIndication_t* bpi, void** security_socket) { + int rv = 0; + + FacilitiesIndication_t *fi = NULL; + + asn_TYPE_descriptor_t *its_msg_descriptor = NULL; + void *its_msg = NULL; + int its_msg_type = 0; + + bool fwd = false; + bool stored = false; + + uint16_t buf_len = 2048; + uint8_t buf[buf_len]; + + uint64_t id = 0; + + // Parse message + switch (bpi->destinationPort) { + case Port_cam: + its_msg_descriptor = &asn_DEF_CAM; + its_msg = calloc(1, sizeof(CAM_t)); + its_msg_type = messageID_cam; + break; + + case Port_denm: + its_msg_descriptor = &asn_DEF_DENM; + its_msg = calloc(1, sizeof(DENM_t)); + its_msg_type = messageID_denm; + break; + + case Port_ivim: + its_msg_descriptor = &asn_DEF_IVIM; + its_msg = calloc(1, sizeof(IVIM_t)); + its_msg_type = messageID_ivim; + break; + + case Port_cpm: + its_msg_descriptor = &asn_DEF_CPM; + its_msg = calloc(1, sizeof(CPM_t)); + its_msg_type = 14; + break; + + case Port_saem: + its_msg_descriptor = &asn_DEF_SAEM; + its_msg = calloc(1, sizeof(SAEM_t)); + its_msg_type = messageID_saem; + break; + + case 7011: /* tolling */ + its_msg_descriptor = &asn_DEF_TPM; + its_msg = calloc(1, sizeof(TPM_t)); + its_msg_type = 117; + break; + + case 2043: /* maneuvers */ + its_msg_descriptor = &asn_DEF_VCM; + its_msg = calloc(1, sizeof(VCM_t)); + its_msg_type = 43; + break; + + case 2044: /* VERCOe */ + its_msg_descriptor = &asn_DEF_VERCOe; + its_msg = calloc(1, sizeof(VERCOe_t)); + its_msg_type = 44; + fwd = true; + break; + + case Port_poi: /* EVCSNM */ + its_msg_descriptor = &asn_DEF_EvcsnPdu; + its_msg = calloc(1, sizeof(EvcsnPdu_t)); + its_msg_type = messageID_evcsn; + break; + + case Port_evrsr: /* EVRSRM */ + its_msg_descriptor = &asn_DEF_EV_RSR; + its_msg = calloc(1, sizeof(EV_RSR_t)); + its_msg_type = messageID_evcsn; + break; + + default: + log_debug("messsage with unhandled BTP port received (%lld), ignoring", bpi->destinationPort); + goto cleanup; + } + + asn_dec_rval_t dec = uper_decode_complete(NULL, its_msg_descriptor, (void **)&its_msg, bpi->data.buf, bpi->data.size); + if (dec.code) { + log_debug("<- invalid %s received", its_msg_descriptor->name); + rv = 1; + goto cleanup; + } + + // Get permisisons + uint8_t *ssp = NULL; + uint16_t ssp_len; + if (bpi->gn.securityPermissions) { + ssp = bpi->gn.securityPermissions->ssp.buf; + ssp_len = bpi->gn.securityPermissions->ssp.size; + } + + // Get neighbour certificate ID + uint8_t *neighbour_cert = bpi->gn.securityNeighbour ? bpi->gn.securityNeighbour->buf : NULL; + + // Manage message + switch (bpi->destinationPort) { + case Port_cam: + switch (check_cam(bpi, its_msg, ssp, ssp_len)) { + case CAM_OK: + fwd = true; + break; + case CAM_INVALID: + case CAM_BAD_PERMISSIONS: + default: + break; + } + break; + + case Port_denm: +#ifdef DEBUG + uint8_t *xml_denm = malloc(32768); + asn_enc_rval_t rve = xer_encode_to_buffer(xml_denm, 32768, 0x02, &asn_DEF_DENM, its_msg); + log_debug("DENM XER %d: %.*s", (int)rve.encoded, (int)rve.encoded, xml_denm); + free(xml_denm); +#endif + stored = true; + switch (event_manage(its_msg, &id, ssp, ssp_len)) { + case EVENT_NEW: + case EVENT_CANCELLATION: + case EVENT_NEGATION: + case EVENT_UPDATE: + case EVENT_NUMBER_EXCEEDED: + fwd = true; + break; + case EVENT_INVALID: + case EVENT_PASSED: + case EVENT_REPEATED: + case EVENT_BAD_PERMISSIONS: + break; + } + break; + + case Port_ivim: + stored = true; + switch (service_eval(SERVICE_IVI, its_msg, &id, ssp, ssp_len)) { + case SERVICE_NEW: + case SERVICE_CANCELLATION: + case SERVICE_NEGATION: + case SERVICE_UPDATE: + case SERVICE_NUMBER_EXCEEDED: + fwd = true; + break; + case SERVICE_INVALID: + case SERVICE_REPEATED: + case SERVICE_PASSED: + case SERVICE_BAD_PERMISSIONS: + default: + break; + } + break; + + case Port_saem: + switch (saem_check(its_msg, neighbour_cert)) { + case SAEM_NEW: + fwd = true; + break; + default: + break; + } + break; + + case 7011: + if (facilities.tolling.enabled) { + tpm_recv(its_msg, security_socket, neighbour_cert, NULL); + fwd = true; + } + break; + + case 2043: + if (facilities.coordination.active) { + vcm_check(its_msg); + } + fwd = true; + break; + + case Port_poi: + if (facilities.evm_args.activate) { + evcsnm_check(its_msg); + fwd = true; + } + break; + + case Port_evrsr: + if (facilities.evm_args.activate) { + evrsrm_check(its_msg); + fwd = true; + EV_RSR_t *evrsr_request = (EV_RSR_t *)its_msg; + evrsrm_recv(evrsr_request); + } + break; + + default: + break; + } + + // Forward to [applications] + if (fwd) { + fi = calloc(1, sizeof(FacilitiesIndication_t)); + fi->present = FacilitiesIndication_PR_message; + FacilitiesMessageIndication_t *fmi = &fi->choice.message; + + fmi->id = id; + + fmi->itsMessageType = bpi->destinationPort; + + fmi->data.size = bpi->data.size; + fmi->data.buf = malloc(bpi->data.size); + memcpy(fmi->data.buf, bpi->data.buf, bpi->data.size); + + uint8_t buffer[ITSS_SDU_MAX_LEN]; + buffer[0] = 4; // Facilities + asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_FacilitiesIndication, NULL, fi, buffer + 1, ITSS_SDU_MAX_LEN - 1); + + itss_queue_send(facilities.tx_queue, buffer, enc.encoded + 1, ITSS_APPLICATIONS, id, "FI.message"); + } + + // Logging + if (facilities.logging.dbms) { + pthread_mutex_lock(&facilities.id.lock); + uint32_t station_id = facilities.id.station_id; + pthread_mutex_unlock(&facilities.id.lock); + itss_db_add(facilities.logging.dbms, station_id, id, false, its_msg_type, NULL, bpi->data.buf, bpi->data.size); + } + if (facilities.logging.recorder) { + int e = itss_management_record_packet_sdu( + buf, + buf_len, + bpi->data.buf, + bpi->data.size, + bpi->id, + itss_time_get(), + ITSS_FACILITIES, + false); + if (e != -1) { + itss_queue_send(facilities.tx_queue, buf, e, ITSS_MANAGEMENT, bpi->id, "MReq.packet.set"); + } + } + +cleanup: + if (its_msg && !stored) { + ASN_STRUCT_FREE(*its_msg_descriptor, its_msg); + } + ASN_STRUCT_FREE(asn_DEF_FacilitiesIndication, fi); + + return rv; +} + + +int transport_indication_tcp(TCPPacketIndication_t* tpi, void** security_socket) { + int rv = 0; + + uint16_t buf_len = 2048; + uint8_t buf[buf_len]; + + SecurityRequest_t* sreq = NULL; + SecurityReply_t* srep = NULL; + TransportRequest_t* tr = NULL; + FacilitiesIndication_t* fi = NULL; + + void* its_msg; + + sreq = calloc(1, sizeof(SecurityRequest_t)); + sreq->present = SecurityRequest_PR_tlsRecv; + sreq->choice.tlsRecv.data.size = tpi->data.size; + sreq->choice.tlsRecv.data.buf = malloc(tpi->data.size); + memcpy(sreq->choice.tlsRecv.data.buf, tpi->data.buf, tpi->data.size); + + uint64_t id = tpi->id; + pthread_mutex_lock(&facilities.tolling.lock); + tlsc_t *tlsc = tolling_tlsc_get(tpi->sourceAddress->buf, 7011); + if (tlsc) { + id = tlsc->id; + } else { + tlsc = tolling_tlsc_new(tpi->sourceAddress->buf, 7011); + id = tlsc->id; + } + ++tlsc->nmsg; + pthread_mutex_unlock(&facilities.tolling.lock); + sreq->choice.tlsSend.connId = id; + + uint8_t b_tx[2048], b_rx[2048]; + b_tx[0] = 4; + asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_SecurityRequest, NULL, sreq, b_tx + 1, 2047); + + log_debug("->[security] SecurityRequest.tlsRecv (%ldB)", enc.encoded + 1); + itss_0send(*security_socket, b_tx, enc.encoded + 1); + int32_t rl = itss_0recv_rt(security_socket, b_rx, 2048, b_tx, enc.encoded + 1, 1000); + log_debug("<-[security] SecurityReply.tlsRecv (%dB)", rl); + + if (oer_decode(NULL, &asn_DEF_SecurityReply, (void **)&srep, b_rx, rl).code) { + log_error("SecurityReply.tlsRecv decode failure"); + rv = 1; + goto cleanup; + } + + if (srep->returnCode == SecurityReplyReturnCode_rejected) { + log_error("SecurityReply.tlsRecv rejected"); + + SecurityRequest_t *sREQ = calloc(1, sizeof(SecurityRequest_t)); + sREQ->present = SecurityRequest_PR_tlsShutdown; + sREQ->choice.tlsShutdown.connId = id; + b_tx[0] = 4; + asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_SecurityRequest, NULL, sREQ, b_tx + 1, 2047); + log_debug("->[security] SecurityRequest.tlsShutdown (%ldB)", enc.encoded + 1); + itss_0send(*security_socket, b_tx, enc.encoded + 1); + int32_t rl = itss_0recv_rt(security_socket, b_rx, 2048, b_tx, enc.encoded + 1, 1000); + log_debug("<-[security] SecurityReply.tlsShutdown (%dB)", rl); + + rv = 1; + goto cleanup; + } + + log_debug("[tolling] tls n-msg:%d state:%d", tlsc->nmsg, tlsc->state); + + // Forward to [transport] + if (srep->data->choice.tlsRecv.state != 1) { + tr = calloc(1, sizeof(TransportRequest_t)); + tr->present = TransportRequest_PR_packet; + tr->choice.packet.present = TransportPacketRequest_PR_tcp; + TCPPacketRequest_t *tpr = &tr->choice.packet.choice.tcp; + tpr->data.size = srep->data->choice.tlsRecv.data.size; + tpr->data.buf = malloc(srep->data->choice.tlsRecv.data.size); + memcpy(tpr->data.buf, srep->data->choice.tlsRecv.data.buf, srep->data->choice.tlsRecv.data.size); + + tpr->sourcePort = tpi->destinationPort; + tpr->destinationPort = tpi->sourcePort; + + tpr->destinationAddress = calloc(1, sizeof(OCTET_STRING_t)); + tpr->destinationAddress->buf = malloc(16); + tpr->destinationAddress->size = 16; + memcpy(tpr->destinationAddress->buf, tpi->sourceAddress->buf, 16); + tpr->destinationPort = 7011; + tpr->sourcePort = 7011; + + if (facilities.tolling.protocol.p == TOLLING_PROTOCOL_TLS_GN || + (facilities.tolling.protocol.p == TOLLING_PROTOCOL_TLS_SHS && tlsc->nmsg < 2)) { + tpr->gn = calloc(1, sizeof(GeonetworkingOutboundOptions_t)); + tpr->gn->packetTransportType = PacketTransportType_shb; + tpr->gn->destinationAddress.buf = calloc(1, 6); + tpr->gn->destinationAddress.size = 6; + } + + tpr->id = itss_id(tpr->data.buf, tpr->data.size); + + buf[0] = 4; + enc = oer_encode_to_buffer(&asn_DEF_TransportRequest, NULL, tr, buf + 1, buf_len - 1); + if (enc.encoded == -1) { + log_error("TransportRequest encoding fail"); + rv = 1; + goto cleanup; + } + + itss_queue_send(facilities.tx_queue, buf, enc.encoded + 1, ITSS_TRANSPORT, tpr->id, "TR.packet.tcp"); + } else { + if (facilities.tolling.enabled && srep->data->choice.tlsRecv.data.size) { + asn_dec_rval_t dec = uper_decode_complete(NULL, &asn_DEF_TPM, (void **)&its_msg, srep->data->choice.tlsRecv.data.buf, srep->data->choice.tlsRecv.data.size); + if (dec.code) { + log_debug("<- invalid TPM received"); + rv = 1; + goto cleanup; + } + if (!dec.code) { + tpm_recv(its_msg, security_socket, NULL, tpi->sourceAddress->buf); + + // Fwd to [applications] + fi = calloc(1, sizeof(FacilitiesIndication_t)); + fi->present = FacilitiesIndication_PR_message; + FacilitiesMessageIndication_t *fmi = &fi->choice.message; + + fmi->id = id; + + fmi->itsMessageType = 7011; + + fmi->data.size = srep->data->choice.tlsRecv.data.size; + fmi->data.buf = malloc(srep->data->choice.tlsRecv.data.size); + memcpy(fmi->data.buf, srep->data->choice.tlsRecv.data.buf, srep->data->choice.tlsRecv.data.size); + + uint8_t buffer[ITSS_SDU_MAX_LEN]; + buffer[0] = 4; // Facilities + asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_FacilitiesIndication, NULL, fi, buffer + 1, ITSS_SDU_MAX_LEN - 1); + + itss_queue_send(facilities.tx_queue, buffer, enc.encoded + 1, ITSS_APPLICATIONS, id, "FI.message"); + + // Logging + if (facilities.logging.dbms) { + pthread_mutex_lock(&facilities.id.lock); + uint32_t station_id = facilities.id.station_id; + pthread_mutex_unlock(&facilities.id.lock); + itss_db_add(facilities.logging.dbms, station_id, id, false, 117, NULL, srep->data->choice.tlsRecv.data.buf, srep->data->choice.tlsRecv.data.size); + } + if (facilities.logging.recorder) { + int e = itss_management_record_packet_sdu( + buf, + buf_len, + srep->data->choice.tlsRecv.data.buf, + srep->data->choice.tlsRecv.data.size, + id, + itss_time_get(), + ITSS_FACILITIES, + false); + if (e != -1) { + itss_queue_send(facilities.tx_queue, buf, e, ITSS_MANAGEMENT, id, "MReq.packet.set"); + } + } + } + } + } + +cleanup: + ASN_STRUCT_FREE(asn_DEF_FacilitiesIndication, fi); + ASN_STRUCT_FREE(asn_DEF_SecurityRequest, sreq); + ASN_STRUCT_FREE(asn_DEF_SecurityReply, srep); + ASN_STRUCT_FREE(asn_DEF_TransportRequest, tr); + + return rv; +} + +int transport_indication_udp() {} diff --git a/src/requests.h b/src/requests.h index cc118eb..7fad584 100644 --- a/src/requests.h +++ b/src/requests.h @@ -15,5 +15,7 @@ int facilities_request_loaded_protected_zones(void* responder, FacilitiesRequest int facilities_request_chaininfo_set(void* responder, ChainInformationSet_t* cis); int transport_indication_data(TransportDataIndication_t* tdi); +int transport_indication_btp(BTPPacketIndication_t* bpi, void** security_socket); +int transport_indication_tcp(TCPPacketIndication_t* tpi, void** security_socket); #endif diff --git a/src/tls.c b/src/tls.c deleted file mode 100644 index dd9d8b0..0000000 --- a/src/tls.c +++ /dev/null @@ -1,154 +0,0 @@ -#include "tls.h" - -#include -#include -#include -#include -#include - -int tls_recv(TCPPacketIndication_t* tpi, void** security_socket) { - int rv = 0; - - uint16_t buf_len = 2048; - uint8_t buf[buf_len]; - - SecurityRequest_t* sreq = NULL; - SecurityReply_t* srep = NULL; - TransportRequest_t* tr = NULL; - FacilitiesIndication_t* fi = NULL; - - void* its_msg; - - sreq = calloc(1, sizeof(SecurityRequest_t)); - sreq->present = SecurityRequest_PR_tlsRecv; - sreq->choice.tlsRecv.data.size = tpi->data.size; - sreq->choice.tlsRecv.data.buf = malloc(tpi->data.size); - memcpy(sreq->choice.tlsRecv.data.buf, tpi->data.buf, tpi->data.size); - - uint64_t id = tpi->id; - pthread_mutex_lock(&facilities.tolling.lock); - tlsc_t *tlsc = tolling_tlsc_get(tpi->sourceAddress->buf, 7011); - if (tlsc) { - id = tlsc->id; - } else { - tlsc = tolling_tlsc_new(tpi->sourceAddress->buf, 7011); - id = tlsc->id; - } - ++tlsc->nmsg; - pthread_mutex_unlock(&facilities.tolling.lock); - sreq->choice.tlsSend.connId = id; - - uint8_t b_tx[2048], b_rx[2048]; - b_tx[0] = 4; - asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_SecurityRequest, NULL, sreq, b_tx + 1, 2047); - - log_debug("->[security] SecurityRequest.tlsRecv (%ldB)", enc.encoded + 1); - itss_0send(*security_socket, b_tx, enc.encoded + 1); - int32_t rl = itss_0recv_rt(security_socket, b_rx, 2048, b_tx, enc.encoded + 1, 1000); - log_debug("<-[security] SecurityReply.tlsRecv (%dB)", rl); - - if (oer_decode(NULL, &asn_DEF_SecurityReply, (void **)&srep, b_rx, rl).code) { - log_error("SecurityReply.tlsRecv decode failure"); - rv = 1; - goto cleanup; - } - - if (srep->returnCode == SecurityReplyReturnCode_rejected) { - log_error("SecurityReply.tlsRecv rejected"); - - SecurityRequest_t *sREQ = calloc(1, sizeof(SecurityRequest_t)); - sREQ->present = SecurityRequest_PR_tlsShutdown; - sREQ->choice.tlsShutdown.connId = id; - b_tx[0] = 4; - asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_SecurityRequest, NULL, sREQ, b_tx + 1, 2047); - log_debug("->[security] SecurityRequest.tlsShutdown (%ldB)", enc.encoded + 1); - itss_0send(*security_socket, b_tx, enc.encoded + 1); - int32_t rl = itss_0recv_rt(security_socket, b_rx, 2048, b_tx, enc.encoded + 1, 1000); - log_debug("<-[security] SecurityReply.tlsShutdown (%dB)", rl); - - rv = 1; - goto cleanup; - } - - log_debug("[tolling] tls n-msg:%d state:%d", tlsc->nmsg, tlsc->state); - - // Forward to [transport] - if (srep->data->choice.tlsRecv.state != 1) { - tr = calloc(1, sizeof(TransportRequest_t)); - tr->present = TransportRequest_PR_packet; - tr->choice.packet.present = TransportPacketRequest_PR_tcp; - TCPPacketRequest_t *tpr = &tr->choice.packet.choice.tcp; - tpr->data.size = srep->data->choice.tlsRecv.data.size; - tpr->data.buf = malloc(srep->data->choice.tlsRecv.data.size); - memcpy(tpr->data.buf, srep->data->choice.tlsRecv.data.buf, srep->data->choice.tlsRecv.data.size); - - tpr->sourcePort = tpi->destinationPort; - tpr->destinationPort = tpi->sourcePort; - - tpr->destinationAddress = calloc(1, sizeof(OCTET_STRING_t)); - tpr->destinationAddress->buf = malloc(16); - tpr->destinationAddress->size = 16; - memcpy(tpr->destinationAddress->buf, tpi->sourceAddress->buf, 16); - tpr->destinationPort = 7011; - tpr->sourcePort = 7011; - - if (facilities.tolling.protocol.p == TOLLING_PROTOCOL_TLS_GN || - (facilities.tolling.protocol.p == TOLLING_PROTOCOL_TLS_SHS && tlsc->nmsg < 2)) { - tpr->gn = calloc(1, sizeof(GeonetworkingOutboundOptions_t)); - tpr->gn->packetTransportType = PacketTransportType_shb; - tpr->gn->destinationAddress.buf = calloc(1, 6); - tpr->gn->destinationAddress.size = 6; - } - - tpr->id = itss_id(tpr->data.buf, tpr->data.size); - - buf[0] = 4; - enc = oer_encode_to_buffer(&asn_DEF_TransportRequest, NULL, tr, buf + 1, buf_len - 1); - if (enc.encoded == -1) { - log_error("TransportRequest encoding fail"); - rv = 1; - goto cleanup; - } - - itss_queue_send(facilities.tx_queue, buf, enc.encoded + 1, ITSS_TRANSPORT, tpr->id, "TR.packet.tcp"); - } else { - if (facilities.tolling.enabled && srep->data->choice.tlsRecv.data.size) { - asn_dec_rval_t dec = uper_decode_complete(NULL, &asn_DEF_TPM, (void **)&its_msg, srep->data->choice.tlsRecv.data.buf, srep->data->choice.tlsRecv.data.size); - if (dec.code) { - log_debug("<- invalid TPM received"); - rv = 1; - goto cleanup; - } - if (!dec.code) { - tpm_recv(its_msg, security_socket, NULL, tpi->sourceAddress->buf); - - // Fwd to [applications] - fi = calloc(1, sizeof(FacilitiesIndication_t)); - fi->present = FacilitiesIndication_PR_message; - FacilitiesMessageIndication_t *fmi = &fi->choice.message; - - fmi->id = id; - - fmi->itsMessageType = 7011; - - fmi->data.size = srep->data->choice.tlsRecv.data.size; - fmi->data.buf = malloc(srep->data->choice.tlsRecv.data.size); - memcpy(fmi->data.buf, srep->data->choice.tlsRecv.data.buf, srep->data->choice.tlsRecv.data.size); - - uint8_t buffer[ITSS_SDU_MAX_LEN]; - buffer[0] = 4; // Facilities - asn_enc_rval_t enc = oer_encode_to_buffer(&asn_DEF_FacilitiesIndication, NULL, fi, buffer + 1, ITSS_SDU_MAX_LEN - 1); - - itss_queue_send(facilities.tx_queue, buffer, enc.encoded + 1, ITSS_APPLICATIONS, id, "FI.message"); - } - } - } - -cleanup: - ASN_STRUCT_FREE(asn_DEF_FacilitiesIndication, fi); - ASN_STRUCT_FREE(asn_DEF_SecurityRequest, sreq); - ASN_STRUCT_FREE(asn_DEF_SecurityReply, srep); - ASN_STRUCT_FREE(asn_DEF_TransportRequest, tr); - - return rv; -} diff --git a/src/tls.h b/src/tls.h deleted file mode 100644 index 33474b8..0000000 --- a/src/tls.h +++ /dev/null @@ -1,4 +0,0 @@ -#include "facilities.h" -#include - -int tls_recv(TCPPacketIndication_t* tpi, void** security_socket);