diff options
Diffstat (limited to 'tinySIP/src/transports/tsip_transport_ipsec.c')
-rwxr-xr-x | tinySIP/src/transports/tsip_transport_ipsec.c | 781 |
1 files changed, 388 insertions, 393 deletions
diff --git a/tinySIP/src/transports/tsip_transport_ipsec.c b/tinySIP/src/transports/tsip_transport_ipsec.c index 390e999..9e4ce95 100755 --- a/tinySIP/src/transports/tsip_transport_ipsec.c +++ b/tinySIP/src/transports/tsip_transport_ipsec.c @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. * @@ -46,318 +46,318 @@ TINYSIP_GEXTERN const tsk_object_def_t *tsip_ipsec_association_def_t; tsip_ipsec_association_t* tsip_ipsec_association_create(const tsip_transport_t* transport) { - return tsk_object_new(tsip_ipsec_association_def_t, transport); + return tsk_object_new(tsip_ipsec_association_def_t, transport); } tsip_transport_ipsec_t* tsip_transport_ipsec_create(struct tsip_stack_s* stack, const char* host, tnet_port_t port, tnet_socket_type_t type, const char* description) { - return tsk_object_new(tsip_transport_ipsec_def_t, stack, host, port, type, description); + return tsk_object_new(tsip_transport_ipsec_def_t, stack, host, port, type, description); } int tsip_transport_ipsec_createTempSAs(tsip_transport_ipsec_t* self) { - int ret = -1; - - /* Check */ - if (!self) { - TSK_DEBUG_ERROR("Invalid parameter"); - goto bail; - } - - /* Already have temporary SAs ? */ - if (self->asso_temporary) { - TSK_DEBUG_ERROR("IPSec transport layer already have temporary SAs"); - ret = -2; - goto bail; - } - - /* Create temporary association */ - if ((self->asso_temporary = tsip_ipsec_association_create(TSIP_TRANSPORT(self)))) { - if (self->asso_temporary->ctx && self->asso_temporary->ctx->state == tipsec_state_inbound) { - ret = 0; - } - else { - TSK_DEBUG_INFO("Failed to create new temporary SAs."); - ret = -3; - goto bail; - } - } - else { - TSK_DEBUG_INFO("Failed to create new temporary SAs."); - - ret = -4; - goto bail; - } + int ret = -1; + + /* Check */ + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + goto bail; + } + + /* Already have temporary SAs ? */ + if (self->asso_temporary) { + TSK_DEBUG_ERROR("IPSec transport layer already have temporary SAs"); + ret = -2; + goto bail; + } + + /* Create temporary association */ + if ((self->asso_temporary = tsip_ipsec_association_create(TSIP_TRANSPORT(self)))) { + if (self->asso_temporary->ctx && self->asso_temporary->ctx->state == tipsec_state_inbound) { + ret = 0; + } + else { + TSK_DEBUG_INFO("Failed to create new temporary SAs."); + ret = -3; + goto bail; + } + } + else { + TSK_DEBUG_INFO("Failed to create new temporary SAs."); + + ret = -4; + goto bail; + } bail: - if (ret && ret != -1) { - TSK_OBJECT_SAFE_FREE(self->asso_temporary); - } - return ret; + if (ret && ret != -1) { + TSK_OBJECT_SAFE_FREE(self->asso_temporary); + } + return ret; } int tsip_transport_ipsec_ensureTempSAs(tsip_transport_ipsec_t* self, const tsip_response_t *r401_407, int64_t expires) { - int ret = -1; - struct sockaddr_storage to; - tsk_size_t index; - const tsip_header_Security_Server_t *ssHdr; - double maxQ = -2.0; /* The Q value in the SIP header will be equal to -1 by default. */ - int match = 0; - - - tipsec_spi_t spi_pc, spi_ps; - tipsec_port_t port_pc, port_ps; - tipsec_lifetime_t lifetime; - - if(!self || expires < 0){ - goto bail; - } - - lifetime = (tipsec_lifetime_t)expires; - - /* Already have temporary SAs ? */ - if(!self->asso_temporary){ - TSK_DEBUG_ERROR("Cannot ensure temporary SAs (No tempSAs)"); - ret = -2; - goto bail; - } - - /* Cleanup old Security-Verifies */ - TSK_OBJECT_SAFE_FREE(self->secVerifies); - - /* RFC 3329 - 2.3.1 Client Initiated - - When the client receives a response with a Security-Server header field, it MUST choose the security mechanism in the server's list - with the highest "q" value among all the mechanisms that are known to the client. - */ - for (index = 0; (ssHdr = (const tsip_header_Security_Server_t *)tsip_message_get_headerAt(r401_407, tsip_htype_Security_Server, index)); index++) { - tsip_header_Security_Verify_t* svHdr; - - if (maxQ > ssHdr->q || !tsk_striequals(ssHdr->mech, "ipsec-3gpp")){ - goto copy; - } - - if ((TIPSEC_ALG_FROM_STR(ssHdr->alg) == self->asso_temporary->ctx->alg) && - (TIPSEC_EALG_FROM_STR(ssHdr->ealg) == self->asso_temporary->ctx->ealg) && - (TIPSEC_PROTOCOL_FROM_STR(ssHdr->prot) == self->asso_temporary->ctx->protocol) && - (TIPSEC_MODE_FROM_STR(ssHdr->mod) == self->asso_temporary->ctx->mode)){ - - match = 1; - - maxQ = (ssHdr->q >= maxQ) ? ssHdr->q : maxQ; - spi_pc = ssHdr->spi_c; - spi_ps = ssHdr->spi_s; - port_pc = ssHdr->port_c; - port_ps = ssHdr->port_s; - } + int ret = -1; + struct sockaddr_storage to; + tsk_size_t index; + const tsip_header_Security_Server_t *ssHdr; + double maxQ = -2.0; /* The Q value in the SIP header will be equal to -1 by default. */ + int match = 0; + + + tipsec_spi_t spi_pc, spi_ps; + tipsec_port_t port_pc, port_ps; + tipsec_lifetime_t lifetime; + + if(!self || expires < 0) { + goto bail; + } + + lifetime = (tipsec_lifetime_t)expires; + + /* Already have temporary SAs ? */ + if(!self->asso_temporary) { + TSK_DEBUG_ERROR("Cannot ensure temporary SAs (No tempSAs)"); + ret = -2; + goto bail; + } + + /* Cleanup old Security-Verifies */ + TSK_OBJECT_SAFE_FREE(self->secVerifies); + + /* RFC 3329 - 2.3.1 Client Initiated + + When the client receives a response with a Security-Server header field, it MUST choose the security mechanism in the server's list + with the highest "q" value among all the mechanisms that are known to the client. + */ + for (index = 0; (ssHdr = (const tsip_header_Security_Server_t *)tsip_message_get_headerAt(r401_407, tsip_htype_Security_Server, index)); index++) { + tsip_header_Security_Verify_t* svHdr; + + if (maxQ > ssHdr->q || !tsk_striequals(ssHdr->mech, "ipsec-3gpp")) { + goto copy; + } + + if ((TIPSEC_ALG_FROM_STR(ssHdr->alg) == self->asso_temporary->ctx->alg) && + (TIPSEC_EALG_FROM_STR(ssHdr->ealg) == self->asso_temporary->ctx->ealg) && + (TIPSEC_PROTOCOL_FROM_STR(ssHdr->prot) == self->asso_temporary->ctx->protocol) && + (TIPSEC_MODE_FROM_STR(ssHdr->mod) == self->asso_temporary->ctx->mode)) { + + match = 1; + + maxQ = (ssHdr->q >= maxQ) ? ssHdr->q : maxQ; + spi_pc = ssHdr->spi_c; + spi_ps = ssHdr->spi_s; + port_pc = ssHdr->port_c; + port_ps = ssHdr->port_s; + } copy: - svHdr = tsip_header_Security_Verify_create_null(); - svHdr->mech = tsk_strdup(ssHdr->mech); - svHdr->alg = tsk_strdup(ssHdr->alg); - svHdr->prot = tsk_strdup(ssHdr->prot); - svHdr->mod = tsk_strdup(ssHdr->mod); - svHdr->ealg = tsk_strdup(ssHdr->ealg); - svHdr->port_c = ssHdr->port_c; - svHdr->port_s = ssHdr->port_s; - svHdr->spi_c = ssHdr->spi_c; - svHdr->spi_s = ssHdr->spi_s; - svHdr->q = ssHdr->q; - TSIP_HEADER_PARAMS(svHdr) = tsk_object_ref(TSIP_HEADER_PARAMS(ssHdr)); - if(!self->secVerifies){ - self->secVerifies = tsk_list_create(); - } - tsk_list_push_back_data(self->secVerifies, (void**)&svHdr); - } - - if(!match){ - TSK_DEBUG_ERROR("Failed to match security server<->security client."); - ret = -3; - goto bail; - } - - /* Set remote parameters received from 401/407 response. */ - if((ret = tipsec_ctx_set_remote(self->asso_temporary->ctx, spi_pc, spi_ps, port_pc, port_ps, lifetime))){ - TSK_DEBUG_ERROR("Failed to set remote IPSec parameters [%d]", ret); - goto bail; - } - - /* Connect Sockets: port_uc to port_ps*/ - if((ret = tnet_sockaddr_init(self->asso_temporary->ip_remote, self->asso_temporary->ctx->port_ps, TSIP_TRANSPORT(self)->type, &to))){ - TSK_DEBUG_ERROR("Invalid HOST/PORT [%s/%u].", (const char*)self->asso_temporary->ctx->addr_remote, self->asso_temporary->ctx->port_ps); - goto bail; - } - if((ret = tnet_sockfd_connectto(self->asso_temporary->socket_uc->fd, &to))){ - TSK_DEBUG_ERROR("Failed to connect port_uc to port_ps."); - goto bail; - } + svHdr = tsip_header_Security_Verify_create_null(); + svHdr->mech = tsk_strdup(ssHdr->mech); + svHdr->alg = tsk_strdup(ssHdr->alg); + svHdr->prot = tsk_strdup(ssHdr->prot); + svHdr->mod = tsk_strdup(ssHdr->mod); + svHdr->ealg = tsk_strdup(ssHdr->ealg); + svHdr->port_c = ssHdr->port_c; + svHdr->port_s = ssHdr->port_s; + svHdr->spi_c = ssHdr->spi_c; + svHdr->spi_s = ssHdr->spi_s; + svHdr->q = ssHdr->q; + TSIP_HEADER_PARAMS(svHdr) = tsk_object_ref(TSIP_HEADER_PARAMS(ssHdr)); + if(!self->secVerifies) { + self->secVerifies = tsk_list_create(); + } + tsk_list_push_back_data(self->secVerifies, (void**)&svHdr); + } + + if(!match) { + TSK_DEBUG_ERROR("Failed to match security server<->security client."); + ret = -3; + goto bail; + } + + /* Set remote parameters received from 401/407 response. */ + if((ret = tipsec_ctx_set_remote(self->asso_temporary->ctx, spi_pc, spi_ps, port_pc, port_ps, lifetime))) { + TSK_DEBUG_ERROR("Failed to set remote IPSec parameters [%d]", ret); + goto bail; + } + + /* Connect Sockets: port_uc to port_ps*/ + if((ret = tnet_sockaddr_init(self->asso_temporary->ip_remote, self->asso_temporary->ctx->port_ps, TSIP_TRANSPORT(self)->type, &to))) { + TSK_DEBUG_ERROR("Invalid HOST/PORT [%s/%u].", (const char*)self->asso_temporary->ctx->addr_remote, self->asso_temporary->ctx->port_ps); + goto bail; + } + if((ret = tnet_sockfd_connectto(self->asso_temporary->socket_uc->fd, &to))) { + TSK_DEBUG_ERROR("Failed to connect port_uc to port_ps."); + goto bail; + } bail: - return ret; + return ret; } int tsip_transport_ipsec_startSAs(tsip_transport_ipsec_t* self, const tipsec_key_t* ik, const tipsec_key_t* ck) { - int ret = -1; - - if (!self) { - TSK_DEBUG_ERROR("Invalid parameter"); - goto bail; - } - - if (!self->asso_temporary) { - TSK_DEBUG_ERROR("Failed to find temporary SAs"); - ret = -2; - goto bail; - } - - /* Promote tempSAs (temp => active) */ - TSK_OBJECT_SAFE_FREE(self->asso_active); /* delete old active SAs */ - self->asso_active = tsk_object_ref((void*)self->asso_temporary); /* promote */ - TSK_OBJECT_SAFE_FREE(self->asso_temporary); /* delete old temp SAs */ - - if ((ret = tipsec_ctx_set_keys(self->asso_active->ctx, ik, ck)) == 0){ - ret = tipsec_ctx_start(self->asso_active->ctx); - } + int ret = -1; + + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + goto bail; + } + + if (!self->asso_temporary) { + TSK_DEBUG_ERROR("Failed to find temporary SAs"); + ret = -2; + goto bail; + } + + /* Promote tempSAs (temp => active) */ + TSK_OBJECT_SAFE_FREE(self->asso_active); /* delete old active SAs */ + self->asso_active = tsk_object_ref((void*)self->asso_temporary); /* promote */ + TSK_OBJECT_SAFE_FREE(self->asso_temporary); /* delete old temp SAs */ + + if ((ret = tipsec_ctx_set_keys(self->asso_active->ctx, ik, ck)) == 0) { + ret = tipsec_ctx_start(self->asso_active->ctx); + } bail: - return ret; + return ret; } int tsip_transport_ipsec_cleanupSAs(tsip_transport_ipsec_t* self) { - int ret = -1; + int ret = -1; - if(!self){ - goto bail; - } + if(!self) { + goto bail; + } - TSK_OBJECT_SAFE_FREE(self->asso_temporary); - TSK_OBJECT_SAFE_FREE(self->asso_active); + TSK_OBJECT_SAFE_FREE(self->asso_temporary); + TSK_OBJECT_SAFE_FREE(self->asso_active); bail: - return ret; + return ret; } int tsip_transport_ipsec_updateMSG(tsip_transport_ipsec_t* self, tsip_message_t *msg) { - int ret = -1; - const tsip_ipsec_association_t* asso; - - if (!self) { - TSK_DEBUG_ERROR("Invalid parameter"); - goto bail; - } - - asso = (self->asso_temporary && TSIP_REQUEST_IS_REGISTER(msg)) ? self->asso_temporary : self->asso_active; - if (!asso || !asso->ctx) { - TSK_DEBUG_ERROR("No IPSec association found."); - ret = -2; - goto bail; - } - - if (TSIP_MESSAGE_IS_RESPONSE(msg)) { - return 0; - } - - /* Security-Client, Require, Proxy-Require and Security Verify */ - switch(msg->line.request.request_type) { - case tsip_BYE: - case tsip_INVITE: - case tsip_OPTIONS: - case tsip_REGISTER: - case tsip_SUBSCRIBE: - case tsip_NOTIFY: - case tsip_REFER: - case tsip_INFO: - case tsip_UPDATE: - case tsip_MESSAGE: - case tsip_PUBLISH: - case tsip_PRACK: - { - const tsk_list_item_t *item; - TSIP_MESSAGE_ADD_HEADER(msg, TSIP_HEADER_SECURITY_CLIENT_VA_ARGS("ipsec-3gpp", - TIPSEC_ALG_TO_STR(asso->ctx->alg), - TIPSEC_PROTOCOL_TO_STR(asso->ctx->protocol), - TIPSEC_MODE_TO_STR(asso->ctx->mode), - TIPSEC_EALG_TO_STR(asso->ctx->ealg), - asso->ctx->port_uc, - asso->ctx->port_us, - asso->ctx->spi_uc, - asso->ctx->spi_us - )); - /* RFC 3329 - 2.3.1 Client Initiated - All the subsequent SIP requests sent by the client to that server - SHOULD make use of the security mechanism initiated in the previous - step. These requests MUST contain a Security-Verify header field - that mirrors the server's list received previously in the Security- - Server header field. These requests MUST also have both a Require - and Proxy-Require header fields with the value "sec-agree". - */ - tsk_list_foreach(item, self->secVerifies){ - tsip_message_add_header(msg, (const tsip_header_t*)item->data); - } - TSIP_MESSAGE_ADD_HEADER(msg, TSIP_HEADER_REQUIRE_VA_ARGS("sec-agree")); - TSIP_MESSAGE_ADD_HEADER(msg, TSIP_HEADER_PROXY_REQUIRE_VA_ARGS("sec-agree")); - break; - } - - default: break; - } - - ret = 0; - - /* Add Security-Server headers */ + int ret = -1; + const tsip_ipsec_association_t* asso; + + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + goto bail; + } + + asso = (self->asso_temporary && TSIP_REQUEST_IS_REGISTER(msg)) ? self->asso_temporary : self->asso_active; + if (!asso || !asso->ctx) { + TSK_DEBUG_ERROR("No IPSec association found."); + ret = -2; + goto bail; + } + + if (TSIP_MESSAGE_IS_RESPONSE(msg)) { + return 0; + } + + /* Security-Client, Require, Proxy-Require and Security Verify */ + switch(msg->line.request.request_type) { + case tsip_BYE: + case tsip_INVITE: + case tsip_OPTIONS: + case tsip_REGISTER: + case tsip_SUBSCRIBE: + case tsip_NOTIFY: + case tsip_REFER: + case tsip_INFO: + case tsip_UPDATE: + case tsip_MESSAGE: + case tsip_PUBLISH: + case tsip_PRACK: { + const tsk_list_item_t *item; + TSIP_MESSAGE_ADD_HEADER(msg, TSIP_HEADER_SECURITY_CLIENT_VA_ARGS("ipsec-3gpp", + TIPSEC_ALG_TO_STR(asso->ctx->alg), + TIPSEC_PROTOCOL_TO_STR(asso->ctx->protocol), + TIPSEC_MODE_TO_STR(asso->ctx->mode), + TIPSEC_EALG_TO_STR(asso->ctx->ealg), + asso->ctx->port_uc, + asso->ctx->port_us, + asso->ctx->spi_uc, + asso->ctx->spi_us + )); + /* RFC 3329 - 2.3.1 Client Initiated + All the subsequent SIP requests sent by the client to that server + SHOULD make use of the security mechanism initiated in the previous + step. These requests MUST contain a Security-Verify header field + that mirrors the server's list received previously in the Security- + Server header field. These requests MUST also have both a Require + and Proxy-Require header fields with the value "sec-agree". + */ + tsk_list_foreach(item, self->secVerifies) { + tsip_message_add_header(msg, (const tsip_header_t*)item->data); + } + TSIP_MESSAGE_ADD_HEADER(msg, TSIP_HEADER_REQUIRE_VA_ARGS("sec-agree")); + TSIP_MESSAGE_ADD_HEADER(msg, TSIP_HEADER_PROXY_REQUIRE_VA_ARGS("sec-agree")); + break; + } + + default: + break; + } + + ret = 0; + + /* Add Security-Server headers */ bail: - return ret; + return ret; } tnet_fd_t tsip_transport_ipsec_getFD(tsip_transport_ipsec_t* self, int isRequest) { - if (!self) { - TSK_DEBUG_ERROR("Invalid parameter"); - return TNET_INVALID_FD; - } - - /* If no active SAs ca be found then use default connection. */ - if (!self->asso_active) { - return TNET_INVALID_FD; - // return TSIP_TRANSPORT(self)->connectedFD; - } - - /* IPSec ports management - For more information: http://betelco.blogspot.com/2008/09/ipsec-using-security-agreement-in-3gpp.html - */ - - if (TNET_SOCKET_TYPE_IS_DGRAM(TSIP_TRANSPORT(self)->type)) { - /* - === UDP === - port_uc -> REGISTER -> port_ps - port_ps <- 200 OK <- port_pc - */ - return self->asso_active->socket_uc->fd; - } - else { - /* - === TCP === - port_uc -> REGISTER -> port_ps - port_uc <- 200 OK <- port_ps - - port_us <- NOTIFY <- port_pc - port_us -> 200 OK -> port_pc - */ - if (isRequest) { - return self->asso_active->socket_uc->fd; - } - else { - return self->asso_active->socket_us->fd; - } - } - - return TNET_INVALID_FD; + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return TNET_INVALID_FD; + } + + /* If no active SAs ca be found then use default connection. */ + if (!self->asso_active) { + return TNET_INVALID_FD; + // return TSIP_TRANSPORT(self)->connectedFD; + } + + /* IPSec ports management + For more information: http://betelco.blogspot.com/2008/09/ipsec-using-security-agreement-in-3gpp.html + */ + + if (TNET_SOCKET_TYPE_IS_DGRAM(TSIP_TRANSPORT(self)->type)) { + /* + === UDP === + port_uc -> REGISTER -> port_ps + port_ps <- 200 OK <- port_pc + */ + return self->asso_active->socket_uc->fd; + } + else { + /* + === TCP === + port_uc -> REGISTER -> port_ps + port_uc <- 200 OK <- port_ps + + port_us <- NOTIFY <- port_pc + port_us -> 200 OK -> port_pc + */ + if (isRequest) { + return self->asso_active->socket_uc->fd; + } + else { + return self->asso_active->socket_us->fd; + } + } + + return TNET_INVALID_FD; } @@ -373,57 +373,56 @@ tnet_fd_t tsip_transport_ipsec_getFD(tsip_transport_ipsec_t* self, int isRequest // static tsk_object_t* tsip_transport_ipsec_ctor(tsk_object_t * self, va_list * app) { - tsip_transport_ipsec_t *transport = self; - if(transport){ - const struct tsip_stack_s *stack = va_arg(*app, const struct tsip_stack_s*); - const char *host = va_arg(*app, const char*); + tsip_transport_ipsec_t *transport = self; + if(transport) { + const struct tsip_stack_s *stack = va_arg(*app, const struct tsip_stack_s*); + const char *host = va_arg(*app, const char*); #if defined(__GNUC__) - tnet_port_t port = (tnet_port_t)va_arg(*app, unsigned); + tnet_port_t port = (tnet_port_t)va_arg(*app, unsigned); #else - tnet_port_t port = va_arg(*app, tnet_port_t); + tnet_port_t port = va_arg(*app, tnet_port_t); #endif - tnet_socket_type_t type = va_arg(*app, tnet_socket_type_t); - const char *description = va_arg(*app, const char*); - - /* init base */ - tsip_transport_init(TSIP_TRANSPORT(transport), type, stack, host, port, description); - } - return self; + tnet_socket_type_t type = va_arg(*app, tnet_socket_type_t); + const char *description = va_arg(*app, const char*); + + /* init base */ + tsip_transport_init(TSIP_TRANSPORT(transport), type, stack, host, port, description); + } + return self; } static tsk_object_t* tsip_transport_ipsec_dtor(tsk_object_t * self) -{ - tsip_transport_ipsec_t *transport = self; - if(transport){ - /* deinit base */ - tsip_transport_deinit(TSIP_TRANSPORT(transport)); - - /* deinit self */ - tsip_transport_ipsec_cleanupSAs(transport); - - TSK_OBJECT_SAFE_FREE(transport->secVerifies); - } - return self; +{ + tsip_transport_ipsec_t *transport = self; + if(transport) { + /* deinit base */ + tsip_transport_deinit(TSIP_TRANSPORT(transport)); + + /* deinit self */ + tsip_transport_ipsec_cleanupSAs(transport); + + TSK_OBJECT_SAFE_FREE(transport->secVerifies); + } + return self; } static int tsip_transport_ipsec_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) { - const tsip_transport_ipsec_t *transport1 = obj1; - const tsip_transport_ipsec_t *transport2 = obj2; - if(transport1 && transport2){ - const char* desc1 = tsip_transport_get_description(TSIP_TRANSPORT(transport1)); - const char* desc2 = tsip_transport_get_description(TSIP_TRANSPORT(transport2)); - return tsk_stricmp(desc1, desc2); - } - return -1; + const tsip_transport_ipsec_t *transport1 = obj1; + const tsip_transport_ipsec_t *transport2 = obj2; + if(transport1 && transport2) { + const char* desc1 = tsip_transport_get_description(TSIP_TRANSPORT(transport1)); + const char* desc2 = tsip_transport_get_description(TSIP_TRANSPORT(transport2)); + return tsk_stricmp(desc1, desc2); + } + return -1; } -static const tsk_object_def_t tsip_transport_ipsec_def_s = -{ - sizeof(tsip_transport_ipsec_t), - tsip_transport_ipsec_ctor, - tsip_transport_ipsec_dtor, - tsip_transport_ipsec_cmp, +static const tsk_object_def_t tsip_transport_ipsec_def_s = { + sizeof(tsip_transport_ipsec_t), + tsip_transport_ipsec_ctor, + tsip_transport_ipsec_dtor, + tsip_transport_ipsec_cmp, }; const tsk_object_def_t *tsip_transport_ipsec_def_t = &tsip_transport_ipsec_def_s; @@ -442,96 +441,92 @@ const tsk_object_def_t *tsip_transport_ipsec_def_t = &tsip_transport_ipsec_def_s // static tsk_object_t* tsip_ipsec_association_ctor(tsk_object_t * self, va_list * app) { - tsip_ipsec_association_t *association = self; - if(association){ - - const tsip_transport_t* transport = va_arg(*app, const tsip_transport_t *); - - /* Set transport */ - association->transport = transport; - - /* Get local IP and port. */ - tsip_transport_get_ip_n_port(transport, &association->ip_local, &association->port_local); - - /* Create IPSec context */ - if (tipsec_ctx_create( - TIPSEC_IPPROTO_FROM_STR(transport->protocol), - TNET_SOCKET_TYPE_IS_IPV6(transport->type), - TIPSEC_MODE_FROM_STR(transport->stack->security.ipsec.mode), - TIPSEC_EALG_FROM_STR(transport->stack->security.ipsec.ealg), - TIPSEC_ALG_FROM_STR(transport->stack->security.ipsec.alg), - TIPSEC_PROTOCOL_FROM_STR(transport->stack->security.ipsec.protocol), &association->ctx)) - { - TSK_DEBUG_ERROR("Failed to create IPSec context"); - return tsk_null; - } - - /* Create Both client and Server legs */ - association->socket_us = tnet_socket_create(association->ip_local, TNET_SOCKET_PORT_ANY, transport->type); - association->socket_uc = tnet_socket_create(association->ip_local, TNET_SOCKET_PORT_ANY, transport->type); - - /* Add Both sockets to the network transport */ - tsip_transport_add_socket(transport, association->socket_us->fd, transport->type, 0, 0); - tsip_transport_add_socket(transport, association->socket_uc->fd, transport->type, 0, 1); - - /* Set local */ - if (tnet_get_peerip(transport->connectedFD, &association->ip_remote) == 0) { /* Get remote IP string */ - if (tipsec_ctx_set_local(association->ctx, association->ip_local, association->ip_remote, association->socket_uc->port, association->socket_us->port)) { - TSK_DEBUG_ERROR("Failed to set IPSec local info:%s,%s,%u,%u", association->ip_local, association->ip_remote, association->socket_uc->port, association->socket_us->port); - return tsk_null; - } - } - else { - // Resolve the HostName because "tipsec_ctx_set_local()" requires IP address instead of FQDN. - if (tnet_resolve(transport->stack->network.proxy_cscf[transport->stack->network.transport_idx_default], - transport->stack->network.proxy_cscf_port[transport->stack->network.transport_idx_default], - transport->stack->network.proxy_cscf_type[transport->stack->network.transport_idx_default], - &association->ip_remote, tsk_null)) - { - return tsk_null; - } - if (tipsec_ctx_set_local(association->ctx, - association->ip_local, - association->ip_remote, - association->socket_uc->port, - association->socket_us->port)) - { - return tsk_null; - } - } - } - return self; + tsip_ipsec_association_t *association = self; + if(association) { + + const tsip_transport_t* transport = va_arg(*app, const tsip_transport_t *); + + /* Set transport */ + association->transport = transport; + + /* Get local IP and port. */ + tsip_transport_get_ip_n_port(transport, &association->ip_local, &association->port_local); + + /* Create IPSec context */ + if (tipsec_ctx_create( + TIPSEC_IPPROTO_FROM_STR(transport->protocol), + TNET_SOCKET_TYPE_IS_IPV6(transport->type), + TIPSEC_MODE_FROM_STR(transport->stack->security.ipsec.mode), + TIPSEC_EALG_FROM_STR(transport->stack->security.ipsec.ealg), + TIPSEC_ALG_FROM_STR(transport->stack->security.ipsec.alg), + TIPSEC_PROTOCOL_FROM_STR(transport->stack->security.ipsec.protocol), &association->ctx)) { + TSK_DEBUG_ERROR("Failed to create IPSec context"); + return tsk_null; + } + + /* Create Both client and Server legs */ + association->socket_us = tnet_socket_create(association->ip_local, TNET_SOCKET_PORT_ANY, transport->type); + association->socket_uc = tnet_socket_create(association->ip_local, TNET_SOCKET_PORT_ANY, transport->type); + + /* Add Both sockets to the network transport */ + tsip_transport_add_socket(transport, association->socket_us->fd, transport->type, 0, 0); + tsip_transport_add_socket(transport, association->socket_uc->fd, transport->type, 0, 1); + + /* Set local */ + if (tnet_get_peerip(transport->connectedFD, &association->ip_remote) == 0) { /* Get remote IP string */ + if (tipsec_ctx_set_local(association->ctx, association->ip_local, association->ip_remote, association->socket_uc->port, association->socket_us->port)) { + TSK_DEBUG_ERROR("Failed to set IPSec local info:%s,%s,%u,%u", association->ip_local, association->ip_remote, association->socket_uc->port, association->socket_us->port); + return tsk_null; + } + } + else { + // Resolve the HostName because "tipsec_ctx_set_local()" requires IP address instead of FQDN. + if (tnet_resolve(transport->stack->network.proxy_cscf[transport->stack->network.transport_idx_default], + transport->stack->network.proxy_cscf_port[transport->stack->network.transport_idx_default], + transport->stack->network.proxy_cscf_type[transport->stack->network.transport_idx_default], + &association->ip_remote, tsk_null)) { + return tsk_null; + } + if (tipsec_ctx_set_local(association->ctx, + association->ip_local, + association->ip_remote, + association->socket_uc->port, + association->socket_us->port)) { + return tsk_null; + } + } + } + return self; } static tsk_object_t* tsip_ipsec_association_dtor(tsk_object_t * self) -{ - tsip_ipsec_association_t *association = self; - if(association){ - TSK_OBJECT_SAFE_FREE(association->ctx); - - /* Remove Both sockets from the network transport and delete them. */ - if(association->socket_uc){ - tsip_transport_remove_socket(association->transport, &association->socket_uc->fd); - TSK_OBJECT_SAFE_FREE(association->socket_uc); - } - if(association->socket_us){ - tsip_transport_remove_socket(association->transport, &association->socket_us->fd); - TSK_OBJECT_SAFE_FREE(association->socket_us); - } - } - return self; +{ + tsip_ipsec_association_t *association = self; + if(association) { + TSK_OBJECT_SAFE_FREE(association->ctx); + + /* Remove Both sockets from the network transport and delete them. */ + if(association->socket_uc) { + tsip_transport_remove_socket(association->transport, &association->socket_uc->fd); + TSK_OBJECT_SAFE_FREE(association->socket_uc); + } + if(association->socket_us) { + tsip_transport_remove_socket(association->transport, &association->socket_us->fd); + TSK_OBJECT_SAFE_FREE(association->socket_us); + } + } + return self; } static int tsip_ipsec_association_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) { - return -1; + return -1; } -static const tsk_object_def_t tsip_ipsec_association_def_s = -{ - sizeof(tsip_ipsec_association_t), - tsip_ipsec_association_ctor, - tsip_ipsec_association_dtor, - tsip_ipsec_association_cmp, +static const tsk_object_def_t tsip_ipsec_association_def_s = { + sizeof(tsip_ipsec_association_t), + tsip_ipsec_association_ctor, + tsip_ipsec_association_dtor, + tsip_ipsec_association_cmp, }; const tsk_object_def_t *tsip_ipsec_association_def_t = &tsip_ipsec_association_def_s; |