diff options
author | Mamadou DIOP <bossiel@yahoo.fr> | 2016-02-23 22:00:35 +0100 |
---|---|---|
committer | Mamadou DIOP <bossiel@yahoo.fr> | 2016-02-23 22:00:35 +0100 |
commit | 50dfb4359619563012997bc3ddafb7667741066c (patch) | |
tree | db234c1edc3240a653363b5735fc4077af4b8720 /tinySIP/src/transports/tsip_transport.c | |
parent | 94b2219209038e05dd26395f6fb700be4d1062c0 (diff) | |
download | doubango-50dfb4359619563012997bc3ddafb7667741066c.zip doubango-50dfb4359619563012997bc3ddafb7667741066c.tar.gz |
Add new QoS implementation
Code formatting
Diffstat (limited to 'tinySIP/src/transports/tsip_transport.c')
-rwxr-xr-x | tinySIP/src/transports/tsip_transport.c | 1707 |
1 files changed, 853 insertions, 854 deletions
diff --git a/tinySIP/src/transports/tsip_transport.c b/tinySIP/src/transports/tsip_transport.c index f86f718..e9d2473 100755 --- a/tinySIP/src/transports/tsip_transport.c +++ b/tinySIP/src/transports/tsip_transport.c @@ -8,12 +8,12 @@ * 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. * @@ -56,68 +56,67 @@ static const char* __null_callid = tsk_null; -static const tsip_transport_idx_xt _tsip_transport_idxs_xs[TSIP_TRANSPORT_IDX_MAX] = -{ - { TSIP_TRANSPORT_IDX_UDP, "UDP", TNET_SOCKET_TYPE_UDP }, - { TSIP_TRANSPORT_IDX_DTLS, "DTLS", TNET_SOCKET_TYPE_DTLS }, - { TSIP_TRANSPORT_IDX_TCP, "TCP", TNET_SOCKET_TYPE_TCP }, - { TSIP_TRANSPORT_IDX_TLS, "TLS", TNET_SOCKET_TYPE_TLS }, - { TSIP_TRANSPORT_IDX_WS, "WS", TNET_SOCKET_TYPE_WS }, - { TSIP_TRANSPORT_IDX_WSS, "WSS", TNET_SOCKET_TYPE_WSS }, +static const tsip_transport_idx_xt _tsip_transport_idxs_xs[TSIP_TRANSPORT_IDX_MAX] = { + { TSIP_TRANSPORT_IDX_UDP, "UDP", TNET_SOCKET_TYPE_UDP }, + { TSIP_TRANSPORT_IDX_DTLS, "DTLS", TNET_SOCKET_TYPE_DTLS }, + { TSIP_TRANSPORT_IDX_TCP, "TCP", TNET_SOCKET_TYPE_TCP }, + { TSIP_TRANSPORT_IDX_TLS, "TLS", TNET_SOCKET_TYPE_TLS }, + { TSIP_TRANSPORT_IDX_WS, "WS", TNET_SOCKET_TYPE_WS }, + { TSIP_TRANSPORT_IDX_WSS, "WSS", TNET_SOCKET_TYPE_WSS }, }; const tsip_transport_idx_xt* tsip_transport_get_by_name(const char* name) { - int i; - if(!name) { - return tsk_null; - } - for(i = 0; i < TSIP_TRANSPORT_IDX_MAX; ++i) { - if(tsk_striequals(_tsip_transport_idxs_xs[i].name, name)){ - return &_tsip_transport_idxs_xs[i]; - } - } - return tsk_null; + int i; + if(!name) { + return tsk_null; + } + for(i = 0; i < TSIP_TRANSPORT_IDX_MAX; ++i) { + if(tsk_striequals(_tsip_transport_idxs_xs[i].name, name)) { + return &_tsip_transport_idxs_xs[i]; + } + } + return tsk_null; } // returns -1 if not exist int tsip_transport_get_idx_by_name(const char* name) { - const tsip_transport_idx_xt* t_idx = tsip_transport_get_by_name(name); - return t_idx ? t_idx->idx : -1; + const tsip_transport_idx_xt* t_idx = tsip_transport_get_by_name(name); + return t_idx ? t_idx->idx : -1; } enum tnet_socket_type_e tsip_transport_get_type_by_name(const char* name) { - const tsip_transport_idx_xt* t_idx = tsip_transport_get_by_name(name); - return t_idx ? t_idx->type : tnet_socket_type_invalid; + const tsip_transport_idx_xt* t_idx = tsip_transport_get_by_name(name); + return t_idx ? t_idx->type : tnet_socket_type_invalid; } /*== Predicate function to find a peer by local id */ static int _pred_find_stream_peer_by_local_fd(const tsk_list_item_t *item, const void *local_fd) { - if(item && item->data){ - const tsip_transport_stream_peer_t *peer = (const tsip_transport_stream_peer_t*)item->data; - return (peer->local_fd - *((tnet_fd_t*)local_fd)); - } - return -1; + if(item && item->data) { + const tsip_transport_stream_peer_t *peer = (const tsip_transport_stream_peer_t*)item->data; + return (peer->local_fd - *((tnet_fd_t*)local_fd)); + } + return -1; } /* creates new SIP transport */ tsip_transport_t* tsip_transport_create(tsip_stack_t* stack, const char* host, tnet_port_t port, tnet_socket_type_t type, const char* description) { - tsip_transport_t* transport; - if((transport = tsk_object_new(tsip_transport_def_t, stack, host, port, type, description))){ - int i; - for(i = 0; i < sizeof(_tsip_transport_idxs_xs)/sizeof(_tsip_transport_idxs_xs[0]); ++i){ - if(_tsip_transport_idxs_xs[i].type & type){ - transport->idx = _tsip_transport_idxs_xs[i].idx; - break; - } - } - } - return transport; + tsip_transport_t* transport; + if((transport = tsk_object_new(tsip_transport_def_t, stack, host, port, type, description))) { + int i; + for(i = 0; i < sizeof(_tsip_transport_idxs_xs)/sizeof(_tsip_transport_idxs_xs[0]); ++i) { + if(_tsip_transport_idxs_xs[i].type & type) { + transport->idx = _tsip_transport_idxs_xs[i].idx; + break; + } + } + } + return transport; } /* add Via header using the transport config @@ -125,866 +124,868 @@ must be called after update_aor() */ int tsip_transport_addvia(const tsip_transport_t* self, const char *branch, tsip_message_t *msg) { - tnet_ip_t ip = { '\0' }; - tnet_port_t port; - int ret; - int32_t transport_idx; - - if((transport_idx = tsip_transport_get_idx_by_name(self->protocol)) == -1){ - transport_idx = self->stack->network.transport_idx_default; - } - - /* we always use same port to send() and recv() msg which means Via and Contact headers are identical */ - if(TNET_SOCKET_TYPE_IS_IPSEC(self->type) && ((tsip_transport_ipsec_t*)self)->asso_active){ - memcpy(ip, ((tsip_transport_ipsec_t*)self)->asso_active->socket_us->ip, sizeof(tnet_ip_t)); - port = ((tsip_transport_ipsec_t*)self)->asso_active->socket_us->port; - } - else if(self->stack->network.aor.ip[transport_idx] && self->stack->network.aor.port[transport_idx]){ - memcpy(ip, self->stack->network.aor.ip[transport_idx], TSK_MIN(tsk_strlen(self->stack->network.aor.ip[transport_idx]), sizeof(ip))); - port = self->stack->network.aor.port[transport_idx]; - } - else if((ret = tsip_transport_get_ip_n_port(self, &ip, &port))){ - return ret; - } - - /* is there a Via header? */ - if(!msg->firstVia){ - /* RFC 3261 - 18.1.1 Sending Requests - Before a request is sent, the client transport MUST insert a value of - the "sent-by" field into the Via header field. This field contains - an IP address or host name, and port. The usage of an FQDN is - RECOMMENDED. This field is used for sending responses under certain - conditions, described below. If the port is absent, the default - value depends on the transport. It is 5060 for UDP, TCP and SCTP, - 5061 for TLS. - */ - msg->firstVia = tsip_header_Via_create(TSIP_HEADER_VIA_PROTO_NAME_DEFAULT, TSIP_HEADER_VIA_PROTO_VERSION_DEFAULT, self->via_protocol, ip, port); - TSIP_HEADER_ADD_PARAM(TSIP_HEADER(msg->firstVia), "rport", tsk_null); - } - else if(msg->update && self->stack->network.mode == tsip_stack_mode_webrtc2sip){ - if(TNET_SOCKET_TYPE_IS_WS(msg->src_net_type) || TNET_SOCKET_TYPE_IS_WSS(msg->src_net_type)){ - const tsip_transport_t* ws_transport = tsip_transport_layer_find_by_type(self->stack->layer_transport, msg->src_net_type); - if(ws_transport){ - tsip_transport_stream_peer_t* peer = tsip_transport_find_stream_peer_by_local_fd(TSIP_TRANSPORT(ws_transport), msg->local_fd); - if(peer){ - // hack the first Via as many servers fail to parse "WS" or "WSS" as valid transpors - //if(tsk_striequals(msg->firstVia->transport, "WS") || tsk_striequals(msg->firstVia->transport, "WSS")){ - TSIP_HEADER_ADD_PARAM(TSIP_HEADER(msg->firstVia), "ws-hacked", TNET_SOCKET_TYPE_IS_WSS(msg->src_net_type) ? "WSS" : "WS"); - tsk_strupdate(&msg->firstVia->transport, "TCP"); - tsk_strupdate(&msg->firstVia->host, peer->remote_ip); - msg->firstVia->port = peer->remote_port; - //} - TSK_OBJECT_SAFE_FREE(peer); - - // replace first Via with ours - tsip_message_add_header(msg, (const tsip_header_t *)msg->firstVia); - TSK_OBJECT_SAFE_FREE(msg->firstVia); - msg->firstVia = tsip_header_Via_create(TSIP_HEADER_VIA_PROTO_NAME_DEFAULT, TSIP_HEADER_VIA_PROTO_VERSION_DEFAULT, self->via_protocol, ip, port); - TSIP_HEADER_ADD_PARAM(TSIP_HEADER(msg->firstVia), "rport", tsk_null); - } - } - } - } - - /* updates the branch */ - if(branch){ - tsk_strupdate(&msg->firstVia->branch, branch); - } - else{ /* Probably ACK sent from Dialog Layer */ - TSK_FREE(msg->firstVia->branch); - if((msg->firstVia->branch = tsk_strdup(TSIP_TRANSAC_MAGIC_COOKIE))){ - tsk_istr_t _branch; - tsk_strrandom(&_branch); - tsk_strcat_2(&msg->firstVia->branch, "-%s", _branch); - } - } - - /* multicast case */ - if(tsk_false){ - /* RFC 3261 - 18.1.1 Sending Requests (FIXME) - A client that sends a request to a multicast address MUST add the - "maddr" parameter to its Via header field value containing the - destination multicast address, and for IPv4, SHOULD add the "ttl" - parameter with a value of 1. Usage of IPv6 multicast is not defined - in this specification, and will be a subject of future - standardization when the need arises. - */ - } - - /* - * comp=sigcomp; sigcomp-id= - */ - - return 0; + tnet_ip_t ip = { '\0' }; + tnet_port_t port; + int ret; + int32_t transport_idx; + + if((transport_idx = tsip_transport_get_idx_by_name(self->protocol)) == -1) { + transport_idx = self->stack->network.transport_idx_default; + } + + /* we always use same port to send() and recv() msg which means Via and Contact headers are identical */ + if(TNET_SOCKET_TYPE_IS_IPSEC(self->type) && ((tsip_transport_ipsec_t*)self)->asso_active) { + memcpy(ip, ((tsip_transport_ipsec_t*)self)->asso_active->socket_us->ip, sizeof(tnet_ip_t)); + port = ((tsip_transport_ipsec_t*)self)->asso_active->socket_us->port; + } + else if(self->stack->network.aor.ip[transport_idx] && self->stack->network.aor.port[transport_idx]) { + memcpy(ip, self->stack->network.aor.ip[transport_idx], TSK_MIN(tsk_strlen(self->stack->network.aor.ip[transport_idx]), sizeof(ip))); + port = self->stack->network.aor.port[transport_idx]; + } + else if((ret = tsip_transport_get_ip_n_port(self, &ip, &port))) { + return ret; + } + + /* is there a Via header? */ + if(!msg->firstVia) { + /* RFC 3261 - 18.1.1 Sending Requests + Before a request is sent, the client transport MUST insert a value of + the "sent-by" field into the Via header field. This field contains + an IP address or host name, and port. The usage of an FQDN is + RECOMMENDED. This field is used for sending responses under certain + conditions, described below. If the port is absent, the default + value depends on the transport. It is 5060 for UDP, TCP and SCTP, + 5061 for TLS. + */ + msg->firstVia = tsip_header_Via_create(TSIP_HEADER_VIA_PROTO_NAME_DEFAULT, TSIP_HEADER_VIA_PROTO_VERSION_DEFAULT, self->via_protocol, ip, port); + TSIP_HEADER_ADD_PARAM(TSIP_HEADER(msg->firstVia), "rport", tsk_null); + } + else if(msg->update && self->stack->network.mode == tsip_stack_mode_webrtc2sip) { + if(TNET_SOCKET_TYPE_IS_WS(msg->src_net_type) || TNET_SOCKET_TYPE_IS_WSS(msg->src_net_type)) { + const tsip_transport_t* ws_transport = tsip_transport_layer_find_by_type(self->stack->layer_transport, msg->src_net_type); + if(ws_transport) { + tsip_transport_stream_peer_t* peer = tsip_transport_find_stream_peer_by_local_fd(TSIP_TRANSPORT(ws_transport), msg->local_fd); + if(peer) { + // hack the first Via as many servers fail to parse "WS" or "WSS" as valid transpors + //if(tsk_striequals(msg->firstVia->transport, "WS") || tsk_striequals(msg->firstVia->transport, "WSS")){ + TSIP_HEADER_ADD_PARAM(TSIP_HEADER(msg->firstVia), "ws-hacked", TNET_SOCKET_TYPE_IS_WSS(msg->src_net_type) ? "WSS" : "WS"); + tsk_strupdate(&msg->firstVia->transport, "TCP"); + tsk_strupdate(&msg->firstVia->host, peer->remote_ip); + msg->firstVia->port = peer->remote_port; + //} + TSK_OBJECT_SAFE_FREE(peer); + + // replace first Via with ours + tsip_message_add_header(msg, (const tsip_header_t *)msg->firstVia); + TSK_OBJECT_SAFE_FREE(msg->firstVia); + msg->firstVia = tsip_header_Via_create(TSIP_HEADER_VIA_PROTO_NAME_DEFAULT, TSIP_HEADER_VIA_PROTO_VERSION_DEFAULT, self->via_protocol, ip, port); + TSIP_HEADER_ADD_PARAM(TSIP_HEADER(msg->firstVia), "rport", tsk_null); + } + } + } + } + + /* updates the branch */ + if(branch) { + tsk_strupdate(&msg->firstVia->branch, branch); + } + else { /* Probably ACK sent from Dialog Layer */ + TSK_FREE(msg->firstVia->branch); + if((msg->firstVia->branch = tsk_strdup(TSIP_TRANSAC_MAGIC_COOKIE))) { + tsk_istr_t _branch; + tsk_strrandom(&_branch); + tsk_strcat_2(&msg->firstVia->branch, "-%s", _branch); + } + } + + /* multicast case */ + if(tsk_false) { + /* RFC 3261 - 18.1.1 Sending Requests (FIXME) + A client that sends a request to a multicast address MUST add the + "maddr" parameter to its Via header field value containing the + destination multicast address, and for IPv4, SHOULD add the "ttl" + parameter with a value of 1. Usage of IPv6 multicast is not defined + in this specification, and will be a subject of future + standardization when the need arises. + */ + } + + /* + * comp=sigcomp; sigcomp-id= + */ + + return 0; } int tsip_transport_msg_update_aor(tsip_transport_t* self, tsip_message_t *msg) { - int ret = 0; - int32_t transport_idx; - - /* already updtated (e.g. retrans)? */ - if(!msg->update){ - return 0; - } - - if((transport_idx = tsip_transport_get_idx_by_name(self->protocol)) == -1){ - transport_idx = self->stack->network.transport_idx_default; - } - - /* retrieves the transport ip address and port */ - if(!self->stack->network.aor.ip[transport_idx] && !self->stack->network.aor.port[transport_idx]){ - tnet_ip_t ip = {0}; - tnet_port_t port = 0; - - if((ret = tsip_transport_get_public_ip_n_port(self, &ip, &port))){ - TSK_DEBUG_ERROR("Failed to get public IP"); - return ret; - } - else{ - ((tsip_stack_t*)self->stack)->network.aor.ip[transport_idx] = tsk_strdup(ip); - ((tsip_stack_t*)self->stack)->network.aor.port[transport_idx] = port; - } - } - - /* === Host and port === */ - if(msg->Contact && msg->Contact->uri){ - tsk_strupdate(&(msg->Contact->uri->scheme), self->scheme); - msg->Contact->uri->host_type = TNET_SOCKET_TYPE_IS_IPV6(self->type) ? host_ipv6 : host_ipv4; /* for serializer ...who know? */ - tsk_params_add_param(&msg->Contact->uri->params, "transport", self->protocol); - - // IPSec - if(TNET_SOCKET_TYPE_IS_IPSEC(self->type) && ((tsip_transport_ipsec_t*)self)->asso_active){ - tsk_strupdate(&(msg->Contact->uri->host), ((tsip_transport_ipsec_t*)self)->asso_active->socket_us->ip); - msg->Contact->uri->port = ((tsip_transport_ipsec_t*)self)->asso_active->socket_us->port; - } - else { - tsk_strupdate(&(msg->Contact->uri->host), self->stack->network.aor.ip[transport_idx]); - msg->Contact->uri->port = self->stack->network.aor.port[transport_idx]; - } - - /* Add extra params for message received over WebSocket transport */ - if((TNET_SOCKET_TYPE_IS_WS(msg->src_net_type) || TNET_SOCKET_TYPE_IS_WSS(msg->src_net_type)) && msg->local_fd > 0){ - tnet_ip_t ws_src_ip; - tnet_port_t ws_src_port; - if(tnet_get_ip_n_port(msg->local_fd, tsk_false/*remote*/, &ws_src_ip, &ws_src_port) == 0){ - tsk_params_add_param(&msg->Contact->uri->params, "ws-src-ip", ws_src_ip); - tsk_params_add_param_3(&msg->Contact->uri->params, "ws-src-port", (int64_t)ws_src_port); - tsk_params_add_param(&msg->Contact->uri->params, "ws-src-proto", TNET_SOCKET_TYPE_IS_WS(msg->src_net_type) ? "ws" : "wss"); - } - } - } - - return 0; + int ret = 0; + int32_t transport_idx; + + /* already updtated (e.g. retrans)? */ + if(!msg->update) { + return 0; + } + + if((transport_idx = tsip_transport_get_idx_by_name(self->protocol)) == -1) { + transport_idx = self->stack->network.transport_idx_default; + } + + /* retrieves the transport ip address and port */ + if(!self->stack->network.aor.ip[transport_idx] && !self->stack->network.aor.port[transport_idx]) { + tnet_ip_t ip = {0}; + tnet_port_t port = 0; + + if((ret = tsip_transport_get_public_ip_n_port(self, &ip, &port))) { + TSK_DEBUG_ERROR("Failed to get public IP"); + return ret; + } + else { + ((tsip_stack_t*)self->stack)->network.aor.ip[transport_idx] = tsk_strdup(ip); + ((tsip_stack_t*)self->stack)->network.aor.port[transport_idx] = port; + } + } + + /* === Host and port === */ + if(msg->Contact && msg->Contact->uri) { + tsk_strupdate(&(msg->Contact->uri->scheme), self->scheme); + msg->Contact->uri->host_type = TNET_SOCKET_TYPE_IS_IPV6(self->type) ? host_ipv6 : host_ipv4; /* for serializer ...who know? */ + tsk_params_add_param(&msg->Contact->uri->params, "transport", self->protocol); + + // IPSec + if(TNET_SOCKET_TYPE_IS_IPSEC(self->type) && ((tsip_transport_ipsec_t*)self)->asso_active) { + tsk_strupdate(&(msg->Contact->uri->host), ((tsip_transport_ipsec_t*)self)->asso_active->socket_us->ip); + msg->Contact->uri->port = ((tsip_transport_ipsec_t*)self)->asso_active->socket_us->port; + } + else { + tsk_strupdate(&(msg->Contact->uri->host), self->stack->network.aor.ip[transport_idx]); + msg->Contact->uri->port = self->stack->network.aor.port[transport_idx]; + } + + /* Add extra params for message received over WebSocket transport */ + if((TNET_SOCKET_TYPE_IS_WS(msg->src_net_type) || TNET_SOCKET_TYPE_IS_WSS(msg->src_net_type)) && msg->local_fd > 0) { + tnet_ip_t ws_src_ip; + tnet_port_t ws_src_port; + if(tnet_get_ip_n_port(msg->local_fd, tsk_false/*remote*/, &ws_src_ip, &ws_src_port) == 0) { + tsk_params_add_param(&msg->Contact->uri->params, "ws-src-ip", ws_src_ip); + tsk_params_add_param_3(&msg->Contact->uri->params, "ws-src-port", (int64_t)ws_src_port); + tsk_params_add_param(&msg->Contact->uri->params, "ws-src-proto", TNET_SOCKET_TYPE_IS_WS(msg->src_net_type) ? "ws" : "wss"); + } + } + } + + return 0; } /* update the entire message (IPSec headers, SigComp, ....) */ int tsip_transport_msg_update(const tsip_transport_t* self, tsip_message_t *msg) { - int ret = 0; - - /* already updtated (e.g. retrans)? */ - if(!msg->update){ - return 0; - } - - /* === IPSec headers (Security-Client, Security-Verify, Sec-Agree ...) === */ - if(TNET_SOCKET_TYPE_IS_IPSEC(self->type)){ - ret = tsip_transport_ipsec_updateMSG(TSIP_TRANSPORT_IPSEC(self), msg); - } - - /* === SigComp === */ - if(msg->sigcomp_id){ - /* Via */ - if(msg->firstVia){ - char* quoted_id = tsk_null; - TSIP_HEADER_ADD_PARAM(msg->firstVia, "comp", "sigcomp"); - tsk_sprintf("ed_id, "\"%s\"", msg->sigcomp_id); - TSIP_HEADER_ADD_PARAM(msg->firstVia, "sigcomp-id", quoted_id); - TSK_FREE(quoted_id); - } - /* Contact */ - if(msg->Contact && msg->Contact->uri){ - tsk_params_add_param(&msg->Contact->uri->params, "sigcomp-id", msg->sigcomp_id); - } - } - /* === WebRTC2SIP === */ - if(TSIP_MESSAGE_IS_REQUEST(msg)) { - if(self->stack->network.mode == tsip_stack_mode_webrtc2sip) { - // Request Uri (Fix: https://code.google.com/p/webrtc2sip/issues/detail?id=56) - if(tsk_params_have_param(msg->line.request.uri->params, "transport")){ - tsk_params_add_param(&msg->line.request.uri->params, "transport", self->protocol); - } - } - } - - - msg->update = tsk_false; /* To avoid to update retrans. */ - - return ret; + int ret = 0; + + /* already updtated (e.g. retrans)? */ + if(!msg->update) { + return 0; + } + + /* === IPSec headers (Security-Client, Security-Verify, Sec-Agree ...) === */ + if(TNET_SOCKET_TYPE_IS_IPSEC(self->type)) { + ret = tsip_transport_ipsec_updateMSG(TSIP_TRANSPORT_IPSEC(self), msg); + } + + /* === SigComp === */ + if(msg->sigcomp_id) { + /* Via */ + if(msg->firstVia) { + char* quoted_id = tsk_null; + TSIP_HEADER_ADD_PARAM(msg->firstVia, "comp", "sigcomp"); + tsk_sprintf("ed_id, "\"%s\"", msg->sigcomp_id); + TSIP_HEADER_ADD_PARAM(msg->firstVia, "sigcomp-id", quoted_id); + TSK_FREE(quoted_id); + } + /* Contact */ + if(msg->Contact && msg->Contact->uri) { + tsk_params_add_param(&msg->Contact->uri->params, "sigcomp-id", msg->sigcomp_id); + } + } + /* === WebRTC2SIP === */ + if(TSIP_MESSAGE_IS_REQUEST(msg)) { + if(self->stack->network.mode == tsip_stack_mode_webrtc2sip) { + // Request Uri (Fix: https://code.google.com/p/webrtc2sip/issues/detail?id=56) + if(tsk_params_have_param(msg->line.request.uri->params, "transport")) { + tsk_params_add_param(&msg->line.request.uri->params, "transport", self->protocol); + } + } + } + + + msg->update = tsk_false; /* To avoid to update retrans. */ + + return ret; } // "udp", "tcp" or "tls" tsk_size_t tsip_transport_send_raw(const tsip_transport_t* self, const char* dst_host, tnet_port_t dst_port, const void* data, tsk_size_t size, const char* callid) { - tsk_size_t ret = 0; - - TSK_DEBUG_INFO("\n\nSEND: %.*s\n\n", size, (const char*)data); - - if(TNET_SOCKET_TYPE_IS_DGRAM(self->type)){// "udp" or "dtls" - const struct sockaddr_storage* to = &self->pcscf_addr; - struct sockaddr_storage dst_addr; // must be local scope - if(!tsk_strnullORempty(dst_host) && dst_port){ - if(tnet_sockaddr_init(dst_host, dst_port, self->type, &dst_addr) == 0){ - to = &dst_addr; - } - } - if(!(ret = tnet_transport_sendto(self->net_transport, self->connectedFD, (const struct sockaddr*)to, data, size))){ - TSK_DEBUG_ERROR("Send(%u) returns zero", size); - } - } - else{// "sctp", "tcp" or "tls" - tsip_transport_stream_peer_t* peer = tsk_null; - tnet_ip_t dst_ip; - - if(tsk_strnullORempty(dst_host) || !dst_port){ - if(tnet_get_sockip_n_port((const struct sockaddr *)&self->pcscf_addr, &dst_ip, &dst_port) != 0){ - TSK_DEBUG_ERROR("Failed to get Proxy-CSCF IP address and port"); - return 0; - } - } - else{ - // get IP address and port - // we use ip/port instead of fqdn because this what "tsip_transport_add_stream_peer()" requires it - if(tnet_resolve(dst_host, dst_port, self->type, &dst_ip, &dst_port) != 0){ - TSK_DEBUG_ERROR("Failed to resolve(%s/%d)", dst_host, dst_port); - return 0; - } - } - - if(!(peer = tsip_transport_find_stream_peer_by_remote_ip(TSIP_TRANSPORT(self), dst_ip, dst_port, self->type))){ - tnet_fd_t fd; - TSK_DEBUG_INFO("Cannot find peer with remote IP/Port=%s/%d, connecting to the destination...", dst_ip, dst_port); - // connect to the destination + tsk_size_t ret = 0; + + TSK_DEBUG_INFO("\n\nSEND: %.*s\n\n", size, (const char*)data); + + if(TNET_SOCKET_TYPE_IS_DGRAM(self->type)) { // "udp" or "dtls" + const struct sockaddr_storage* to = &self->pcscf_addr; + struct sockaddr_storage dst_addr; // must be local scope + if(!tsk_strnullORempty(dst_host) && dst_port) { + if(tnet_sockaddr_init(dst_host, dst_port, self->type, &dst_addr) == 0) { + to = &dst_addr; + } + } + if(!(ret = tnet_transport_sendto(self->net_transport, self->connectedFD, (const struct sockaddr*)to, data, size))) { + TSK_DEBUG_ERROR("Send(%u) returns zero", size); + } + } + else { // "sctp", "tcp" or "tls" + tsip_transport_stream_peer_t* peer = tsk_null; + tnet_ip_t dst_ip; + + if(tsk_strnullORempty(dst_host) || !dst_port) { + if(tnet_get_sockip_n_port((const struct sockaddr *)&self->pcscf_addr, &dst_ip, &dst_port) != 0) { + TSK_DEBUG_ERROR("Failed to get Proxy-CSCF IP address and port"); + return 0; + } + } + else { + // get IP address and port + // we use ip/port instead of fqdn because this what "tsip_transport_add_stream_peer()" requires it + if(tnet_resolve(dst_host, dst_port, self->type, &dst_ip, &dst_port) != 0) { + TSK_DEBUG_ERROR("Failed to resolve(%s/%d)", dst_host, dst_port); + return 0; + } + } + + if(!(peer = tsip_transport_find_stream_peer_by_remote_ip(TSIP_TRANSPORT(self), dst_ip, dst_port, self->type))) { + tnet_fd_t fd; + TSK_DEBUG_INFO("Cannot find peer with remote IP/Port=%s/%d, connecting to the destination...", dst_ip, dst_port); + // connect to the destination // stream with the new "fd" will be added later, make sure that no other thread (e.g. network callback) will manipulate the peers tsip_transport_stream_peers_lock(TSIP_TRANSPORT(self)); - if((fd = tnet_transport_connectto_2(TSIP_TRANSPORT(self)->net_transport, dst_ip, dst_port)) == TNET_INVALID_FD){ - TSK_DEBUG_ERROR("Failed to connect to %s/%d", dst_ip, dst_port); + if((fd = tnet_transport_connectto_2(TSIP_TRANSPORT(self)->net_transport, dst_ip, dst_port)) == TNET_INVALID_FD) { + TSK_DEBUG_ERROR("Failed to connect to %s/%d", dst_ip, dst_port); tsip_transport_stream_peers_unlock(TSIP_TRANSPORT(self)); - return 0; - } + return 0; + } // only clients will have connected fd == EVAL. For servers, it will be equal to master's fd // connected fd value will be set to EVAL when "disconnected" event is received if (TSIP_TRANSPORT(self)->connectedFD == TNET_INVALID_FD) { TSIP_TRANSPORT(self)->connectedFD = fd; } - - if(tsip_transport_add_stream_peer_2(TSIP_TRANSPORT(self), fd, self->type, tsk_false, dst_ip, dst_port) != 0){ - TSK_DEBUG_ERROR("Failed to add stream peer local fd = %d, remote IP/Port=%s/%d", fd, dst_ip, dst_port); + + if(tsip_transport_add_stream_peer_2(TSIP_TRANSPORT(self), fd, self->type, tsk_false, dst_ip, dst_port) != 0) { + TSK_DEBUG_ERROR("Failed to add stream peer local fd = %d, remote IP/Port=%s/%d", fd, dst_ip, dst_port); tsip_transport_stream_peers_unlock(TSIP_TRANSPORT(self)); - return 0; - } + return 0; + } tsip_transport_stream_peers_unlock(TSIP_TRANSPORT(self)); - - // retrieve the peer - if(!(peer = tsip_transport_find_stream_peer_by_local_fd(TSIP_TRANSPORT(self), fd))){ - TSK_DEBUG_INFO("Cannot find peer with remote IP/Port=%s/%d. Cancel data sending", dst_ip, dst_port); - return 0; - } - } - // store call-id - if(callid != __null_callid && tsip_dialog_layer_have_dialog_with_callid(self->stack->layer_dialog, callid)){ - ret = tsip_transport_stream_peer_add_callid(peer, callid); - } - // send() data - if(peer->connected){ - ret = tnet_transport_send(self->net_transport, peer->local_fd, data, size); - } - else{ - TSK_DEBUG_INFO("Data send requested but peer not connected yet...saving data"); - tsk_buffer_append(peer->snd_buff_stream, data, size); - ret = 0; // nothing sent - } - TSK_OBJECT_SAFE_FREE(peer); - } - - return ret; + + // retrieve the peer + if(!(peer = tsip_transport_find_stream_peer_by_local_fd(TSIP_TRANSPORT(self), fd))) { + TSK_DEBUG_INFO("Cannot find peer with remote IP/Port=%s/%d. Cancel data sending", dst_ip, dst_port); + return 0; + } + } + // store call-id + if(callid != __null_callid && tsip_dialog_layer_have_dialog_with_callid(self->stack->layer_dialog, callid)) { + ret = tsip_transport_stream_peer_add_callid(peer, callid); + } + // send() data + if(peer->connected) { + ret = tnet_transport_send(self->net_transport, peer->local_fd, data, size); + } + else { + TSK_DEBUG_INFO("Data send requested but peer not connected yet...saving data"); + tsk_buffer_append(peer->snd_buff_stream, data, size); + ret = 0; // nothing sent + } + TSK_OBJECT_SAFE_FREE(peer); + } + + return ret; } // "ws" or "wss" tsk_size_t tsip_transport_send_raw_ws(const tsip_transport_t* self, tnet_fd_t local_fd, const void* data, tsk_size_t size, const char* callid) { - /*static const uint8_t __ws_first_byte = 0x82;*/ - const uint8_t* pdata = (const uint8_t*)data; - uint64_t data_size = 1 + 1 + size; - uint64_t lsize = (uint64_t)size; - uint8_t* pws_snd_buffer; - tsip_transport_stream_peer_t* peer; - tsk_size_t ret; - - if(!(peer = tsip_transport_find_stream_peer_by_local_fd(TSIP_TRANSPORT(self), local_fd))){ - TSK_DEBUG_ERROR("Failed to find peer with local fd equal to %d", local_fd); - return 0; - } - - if(lsize > 0x7D && lsize <= 0xFFFF){ - data_size += 2; - } - else if(lsize > 0xFFFF){ - data_size += 8; - } - if(peer->ws.snd_buffer_size < data_size){ - if(!(peer->ws.snd_buffer = tsk_realloc(peer->ws.snd_buffer, (tsk_size_t)data_size))){ - TSK_DEBUG_ERROR("Failed to allocate buffer with size = %llu", data_size); - peer->ws.snd_buffer_size = 0; - TSK_OBJECT_SAFE_FREE(peer); - return 0; - } - peer->ws.snd_buffer_size = data_size; - } - pws_snd_buffer = (uint8_t*)peer->ws.snd_buffer; - - pws_snd_buffer[0] = 0x82; - if(lsize <= 0x7D){ - pws_snd_buffer[1] = (uint8_t)lsize; - pws_snd_buffer = &pws_snd_buffer[2]; - } - else if(lsize <= 0xFFFF){ - pws_snd_buffer[1] = 0x7E; - pws_snd_buffer[2] = (lsize >> 8) & 0xFF; - pws_snd_buffer[3] = (lsize & 0xFF); - pws_snd_buffer = &pws_snd_buffer[4]; - } - else{ - pws_snd_buffer[1] = 0x7F; - pws_snd_buffer[2] = (lsize >> 56) & 0xFF; - pws_snd_buffer[3] = (lsize >> 48) & 0xFF; - pws_snd_buffer[4] = (lsize >> 40) & 0xFF; - pws_snd_buffer[5] = (lsize >> 32) & 0xFF; - pws_snd_buffer[6] = (lsize >> 24) & 0xFF; - pws_snd_buffer[7] = (lsize >> 16) & 0xFF; - pws_snd_buffer[8] = (lsize >> 8) & 0xFF; - pws_snd_buffer[9] = (lsize & 0xFF); - pws_snd_buffer = &pws_snd_buffer[10]; - } - - memcpy(pws_snd_buffer, pdata, (size_t)lsize); - - // store call-id - if(callid != __null_callid && tsip_dialog_layer_have_dialog_with_callid(self->stack->layer_dialog, callid)){ - ret = tsip_transport_stream_peer_add_callid(peer, callid); - } - // send() data - ret = tnet_transport_send(self->net_transport, local_fd, peer->ws.snd_buffer, (tsk_size_t)data_size); - - TSK_OBJECT_SAFE_FREE(peer); - - return ret; + /*static const uint8_t __ws_first_byte = 0x82;*/ + const uint8_t* pdata = (const uint8_t*)data; + uint64_t data_size = 1 + 1 + size; + uint64_t lsize = (uint64_t)size; + uint8_t* pws_snd_buffer; + tsip_transport_stream_peer_t* peer; + tsk_size_t ret; + + if(!(peer = tsip_transport_find_stream_peer_by_local_fd(TSIP_TRANSPORT(self), local_fd))) { + TSK_DEBUG_ERROR("Failed to find peer with local fd equal to %d", local_fd); + return 0; + } + + if(lsize > 0x7D && lsize <= 0xFFFF) { + data_size += 2; + } + else if(lsize > 0xFFFF) { + data_size += 8; + } + if(peer->ws.snd_buffer_size < data_size) { + if(!(peer->ws.snd_buffer = tsk_realloc(peer->ws.snd_buffer, (tsk_size_t)data_size))) { + TSK_DEBUG_ERROR("Failed to allocate buffer with size = %llu", data_size); + peer->ws.snd_buffer_size = 0; + TSK_OBJECT_SAFE_FREE(peer); + return 0; + } + peer->ws.snd_buffer_size = data_size; + } + pws_snd_buffer = (uint8_t*)peer->ws.snd_buffer; + + pws_snd_buffer[0] = 0x82; + if(lsize <= 0x7D) { + pws_snd_buffer[1] = (uint8_t)lsize; + pws_snd_buffer = &pws_snd_buffer[2]; + } + else if(lsize <= 0xFFFF) { + pws_snd_buffer[1] = 0x7E; + pws_snd_buffer[2] = (lsize >> 8) & 0xFF; + pws_snd_buffer[3] = (lsize & 0xFF); + pws_snd_buffer = &pws_snd_buffer[4]; + } + else { + pws_snd_buffer[1] = 0x7F; + pws_snd_buffer[2] = (lsize >> 56) & 0xFF; + pws_snd_buffer[3] = (lsize >> 48) & 0xFF; + pws_snd_buffer[4] = (lsize >> 40) & 0xFF; + pws_snd_buffer[5] = (lsize >> 32) & 0xFF; + pws_snd_buffer[6] = (lsize >> 24) & 0xFF; + pws_snd_buffer[7] = (lsize >> 16) & 0xFF; + pws_snd_buffer[8] = (lsize >> 8) & 0xFF; + pws_snd_buffer[9] = (lsize & 0xFF); + pws_snd_buffer = &pws_snd_buffer[10]; + } + + memcpy(pws_snd_buffer, pdata, (size_t)lsize); + + // store call-id + if(callid != __null_callid && tsip_dialog_layer_have_dialog_with_callid(self->stack->layer_dialog, callid)) { + ret = tsip_transport_stream_peer_add_callid(peer, callid); + } + // send() data + ret = tnet_transport_send(self->net_transport, local_fd, peer->ws.snd_buffer, (tsk_size_t)data_size); + + TSK_OBJECT_SAFE_FREE(peer); + + return ret; } -/* sends a request +/* sends a request * all callers of this function should provide a sigcomp-id */ tsk_size_t tsip_transport_send(const tsip_transport_t* self, const char *branch, tsip_message_t *msg, const char* destIP, int32_t destPort) { - tsk_size_t ret = 0; - if(self){ - tsk_buffer_t *buffer = tsk_null; - const char* callid = msg->Call_ID ? msg->Call_ID->value : __null_callid; - - /* Add Via and update AOR, IPSec headers, SigComp ... - * ACK sent from the transaction layer will contains a Via header and should not be updated - * CANCEL will have the same Via and Contact headers as the request it cancel - * Any request received from WS/WSS transport layer have to be updated regardless above rules - */ - if(TSIP_MESSAGE_IS_REQUEST(msg)){ - const tsk_bool_t update = ( (!TSIP_REQUEST_IS_ACK(msg) || (TSIP_REQUEST_IS_ACK(msg) && !msg->firstVia)) && !TSIP_REQUEST_IS_CANCEL(msg) ) - || ( TNET_SOCKET_TYPE_IS_WS(msg->src_net_type) || TNET_SOCKET_TYPE_IS_WSS(msg->src_net_type) ); - if(update){ - /* AoR: Contact header */ - tsip_transport_msg_update_aor((tsip_transport_t*)self, msg); - /* should be done before tsip_transport_msg_update() which could use the Via header - must be done after update_aor() - */ - tsip_transport_addvia(self, branch, msg); - tsip_transport_msg_update(self, msg); /* IPSec, SigComp, ... */ - } - } - else if(TSIP_MESSAGE_IS_RESPONSE(msg)){ - /* AoR for responses which have a contact header (e.g. 183/200 INVITE) */ - if(msg->Contact){ - tsip_transport_msg_update_aor((tsip_transport_t*)self, msg); - } - /* RFC 3581 - 4. Server Behavior - When a server compliant to this specification (which can be a proxy - or UAS) receives a request, it examines the topmost Via header field - value. If this Via header field value contains an "rport" parameter - with no value, it MUST set the value of the parameter to the source - port of the request. - */ - if(msg->firstVia->rport == 0){ - /* As the response message has been built from the request ...then it's first via is the same as - the request's first via. - */ - msg->firstVia->rport = msg->firstVia->port; - } - } - - if((buffer = tsk_buffer_create_null())){ - tsip_message_tostring(msg, buffer); - - if(buffer->size >1300){ - /* RFC 3261 - 18.1.1 Sending Requests (FIXME) - If a request is within 200 bytes of the path MTU, or if it is larger - than 1300 bytes and the path MTU is unknown, the request MUST be sent - using an RFC 2914 [43] congestion controlled transport protocol, such - as TCP. If this causes a change in the transport protocol from the - one indicated in the top Via, the value in the top Via MUST be - changed. This prevents fragmentation of messages over UDP and - provides congestion control for larger messages. However, - implementations MUST be able to handle messages up to the maximum - datagram packet size. For UDP, this size is 65,535 bytes, including - IP and UDP headers. - */ - } - - /* === SigComp === */ - if(msg->sigcomp_id){ - if(self->stack->sigcomp.handle){ - tsk_size_t out_size; - char SigCompBuffer[TSIP_SIGCOMP_MAX_BUFF_SIZE]; - - out_size = tsip_sigcomp_handler_compress(self->stack->sigcomp.handle, msg->sigcomp_id, TNET_SOCKET_TYPE_IS_STREAM(self->type), - buffer->data, buffer->size, SigCompBuffer, sizeof(SigCompBuffer)); - if(out_size){ - tsk_buffer_cleanup(buffer); - tsk_buffer_append(buffer, SigCompBuffer, out_size); - } - } - else{ - TSK_DEBUG_ERROR("The outgoing message should be compressed using SigComp but there is not compartment"); - } - } - - /* === Send the message === */ - if(TNET_SOCKET_TYPE_IS_WS(self->type) || TNET_SOCKET_TYPE_IS_WSS(self->type)){ - //if(!TNET_SOCKET_TYPE_IS_WS(msg->net_type) && !TNET_SOCKET_TYPE_IS_WSS(msg->net_type)){ - // message not received over WS/WS tranport but have to be sent over WS/WS - tsip_transport_stream_peer_t* peer = tsip_transport_find_stream_peer_by_remote_ip(TSIP_TRANSPORT(self), destIP, destPort, self->type); - if(peer){ - ret = tsip_transport_send_raw_ws(self, peer->local_fd, buffer->data, buffer->size, callid); - TSK_OBJECT_SAFE_FREE(peer); - } - else if(msg->local_fd > 0) - //} - //else{ - ret = tsip_transport_send_raw_ws(self, msg->local_fd, buffer->data, buffer->size, callid); - //} - } - else if(TNET_SOCKET_TYPE_IS_IPSEC(self->type)){ - tnet_fd_t fd = tsip_transport_ipsec_getFD(TSIP_TRANSPORT_IPSEC(self), TSIP_MESSAGE_IS_REQUEST(msg)); - // "fd == TNET_INVALID_FD" means IPSec SAs not up yet - ret = (fd != TNET_INVALID_FD) - ? tnet_sockfd_send(fd, buffer->data, buffer->size, 0) - : tsip_transport_send_raw(self, destIP, destPort, buffer->data, buffer->size, callid); - } - else{ - ret = tsip_transport_send_raw(self, destIP, destPort, buffer->data, buffer->size, callid); - } + tsk_size_t ret = 0; + if(self) { + tsk_buffer_t *buffer = tsk_null; + const char* callid = msg->Call_ID ? msg->Call_ID->value : __null_callid; + + /* Add Via and update AOR, IPSec headers, SigComp ... + * ACK sent from the transaction layer will contains a Via header and should not be updated + * CANCEL will have the same Via and Contact headers as the request it cancel + * Any request received from WS/WSS transport layer have to be updated regardless above rules + */ + if(TSIP_MESSAGE_IS_REQUEST(msg)) { + const tsk_bool_t update = ( (!TSIP_REQUEST_IS_ACK(msg) || (TSIP_REQUEST_IS_ACK(msg) && !msg->firstVia)) && !TSIP_REQUEST_IS_CANCEL(msg) ) + || ( TNET_SOCKET_TYPE_IS_WS(msg->src_net_type) || TNET_SOCKET_TYPE_IS_WSS(msg->src_net_type) ); + if(update) { + /* AoR: Contact header */ + tsip_transport_msg_update_aor((tsip_transport_t*)self, msg); + /* should be done before tsip_transport_msg_update() which could use the Via header + must be done after update_aor() + */ + tsip_transport_addvia(self, branch, msg); + tsip_transport_msg_update(self, msg); /* IPSec, SigComp, ... */ + } + } + else if(TSIP_MESSAGE_IS_RESPONSE(msg)) { + /* AoR for responses which have a contact header (e.g. 183/200 INVITE) */ + if(msg->Contact) { + tsip_transport_msg_update_aor((tsip_transport_t*)self, msg); + } + /* RFC 3581 - 4. Server Behavior + When a server compliant to this specification (which can be a proxy + or UAS) receives a request, it examines the topmost Via header field + value. If this Via header field value contains an "rport" parameter + with no value, it MUST set the value of the parameter to the source + port of the request. + */ + if(msg->firstVia->rport == 0) { + /* As the response message has been built from the request ...then it's first via is the same as + the request's first via. + */ + msg->firstVia->rport = msg->firstVia->port; + } + } + + if((buffer = tsk_buffer_create_null())) { + tsip_message_tostring(msg, buffer); + + if(buffer->size >1300) { + /* RFC 3261 - 18.1.1 Sending Requests (FIXME) + If a request is within 200 bytes of the path MTU, or if it is larger + than 1300 bytes and the path MTU is unknown, the request MUST be sent + using an RFC 2914 [43] congestion controlled transport protocol, such + as TCP. If this causes a change in the transport protocol from the + one indicated in the top Via, the value in the top Via MUST be + changed. This prevents fragmentation of messages over UDP and + provides congestion control for larger messages. However, + implementations MUST be able to handle messages up to the maximum + datagram packet size. For UDP, this size is 65,535 bytes, including + IP and UDP headers. + */ + } + + /* === SigComp === */ + if(msg->sigcomp_id) { + if(self->stack->sigcomp.handle) { + tsk_size_t out_size; + char SigCompBuffer[TSIP_SIGCOMP_MAX_BUFF_SIZE]; + + out_size = tsip_sigcomp_handler_compress(self->stack->sigcomp.handle, msg->sigcomp_id, TNET_SOCKET_TYPE_IS_STREAM(self->type), + buffer->data, buffer->size, SigCompBuffer, sizeof(SigCompBuffer)); + if(out_size) { + tsk_buffer_cleanup(buffer); + tsk_buffer_append(buffer, SigCompBuffer, out_size); + } + } + else { + TSK_DEBUG_ERROR("The outgoing message should be compressed using SigComp but there is not compartment"); + } + } + + /* === Send the message === */ + if(TNET_SOCKET_TYPE_IS_WS(self->type) || TNET_SOCKET_TYPE_IS_WSS(self->type)) { + //if(!TNET_SOCKET_TYPE_IS_WS(msg->net_type) && !TNET_SOCKET_TYPE_IS_WSS(msg->net_type)){ + // message not received over WS/WS tranport but have to be sent over WS/WS + tsip_transport_stream_peer_t* peer = tsip_transport_find_stream_peer_by_remote_ip(TSIP_TRANSPORT(self), destIP, destPort, self->type); + if(peer) { + ret = tsip_transport_send_raw_ws(self, peer->local_fd, buffer->data, buffer->size, callid); + TSK_OBJECT_SAFE_FREE(peer); + } + else if(msg->local_fd > 0) + //} + //else{ + { + ret = tsip_transport_send_raw_ws(self, msg->local_fd, buffer->data, buffer->size, callid); + } + //} + } + else if(TNET_SOCKET_TYPE_IS_IPSEC(self->type)) { + tnet_fd_t fd = tsip_transport_ipsec_getFD(TSIP_TRANSPORT_IPSEC(self), TSIP_MESSAGE_IS_REQUEST(msg)); + // "fd == TNET_INVALID_FD" means IPSec SAs not up yet + ret = (fd != TNET_INVALID_FD) + ? tnet_sockfd_send(fd, buffer->data, buffer->size, 0) + : tsip_transport_send_raw(self, destIP, destPort, buffer->data, buffer->size, callid); + } + else { + ret = tsip_transport_send_raw(self, destIP, destPort, buffer->data, buffer->size, callid); + } //bail: - TSK_OBJECT_SAFE_FREE(buffer); - } - } + TSK_OBJECT_SAFE_FREE(buffer); + } + } - return ret; + return ret; } tsip_uri_t* tsip_transport_get_uri(const tsip_transport_t *self, tsk_bool_t lr) { - if(self){ - //tnet_ip_t ip; - //tnet_port_t port; - tsip_uri_t* uri = tsk_null; - - //if(!tnet_get_ip_n_port(self->connectedFD, &ip, &port)){ - char* uristring = tsk_null; - int ipv6 = TNET_SOCKET_TYPE_IS_IPV6(self->type); - - tsk_sprintf(&uristring, "%s:%s%s%s:%d;%s;transport=%s", - self->scheme, - ipv6 ? "[" : "", - ((tsip_stack_t*)self->stack)->network.aor.ip[self->idx], - ipv6 ? "]" : "", - ((tsip_stack_t*)self->stack)->network.aor.port[self->idx], - lr ? "lr" : "", - self->protocol); - if(uristring){ - if((uri = tsip_uri_parse(uristring, tsk_strlen(uristring)))){ - uri->host_type = ipv6 ? host_ipv6 : host_ipv4; - } - TSK_FREE(uristring); - } - //} - return uri; - } - return tsk_null; + if(self) { + //tnet_ip_t ip; + //tnet_port_t port; + tsip_uri_t* uri = tsk_null; + + //if(!tnet_get_ip_n_port(self->connectedFD, &ip, &port)){ + char* uristring = tsk_null; + int ipv6 = TNET_SOCKET_TYPE_IS_IPV6(self->type); + + tsk_sprintf(&uristring, "%s:%s%s%s:%d;%s;transport=%s", + self->scheme, + ipv6 ? "[" : "", + ((tsip_stack_t*)self->stack)->network.aor.ip[self->idx], + ipv6 ? "]" : "", + ((tsip_stack_t*)self->stack)->network.aor.port[self->idx], + lr ? "lr" : "", + self->protocol); + if(uristring) { + if((uri = tsip_uri_parse(uristring, tsk_strlen(uristring)))) { + uri->host_type = ipv6 ? host_ipv6 : host_ipv4; + } + TSK_FREE(uristring); + } + //} + return uri; + } + return tsk_null; } // remote ip should not be FQDN int tsip_transport_add_stream_peer_2(tsip_transport_t *self, tnet_fd_t local_fd, enum tnet_socket_type_e type, tsk_bool_t connected, const char* remote_host, tnet_port_t remote_port) { - tsip_transport_stream_peer_t* peer = tsk_null; - tnet_ip_t remote_ip; - int ret = 0; + tsip_transport_stream_peer_t* peer = tsk_null; + tnet_ip_t remote_ip; + int ret = 0; - if(!self || local_fd < 0){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if(!self || local_fd < 0) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - tsip_transport_stream_peers_lock(self); + tsip_transport_stream_peers_lock(self); - if(tsip_transport_have_stream_peer_with_local_fd(self, local_fd)){ - TSK_DEBUG_INFO("Peer with local fd=%d already exist", local_fd); + if(tsip_transport_have_stream_peer_with_local_fd(self, local_fd)) { + TSK_DEBUG_INFO("Peer with local fd=%d already exist", local_fd); #if TSIP_UNDER_WINDOWS - // could happen if the closed socket haven't raised "close event" yet and new one added : Windows only - tsip_transport_remove_stream_peer_by_local_fd(self, local_fd); + // could happen if the closed socket haven't raised "close event" yet and new one added : Windows only + tsip_transport_remove_stream_peer_by_local_fd(self, local_fd); #else - peer = tsip_transport_pop_stream_peer_by_local_fd(self, local_fd); + peer = tsip_transport_pop_stream_peer_by_local_fd(self, local_fd); #endif - } - - if(tsk_strnullORempty(remote_host) || !remote_port){ - if(tnet_get_ip_n_port(local_fd, tsk_false/*remote*/, &remote_ip, &remote_port) != 0){ - TSK_DEBUG_ERROR("Failed to get remote peer ip and address for local fd = %d", local_fd); - ret = -2; - goto bail; - } - remote_host = (const char*)remote_ip; - } - else if((ret = tnet_resolve(remote_host, remote_port, type, &remote_ip, &remote_port))){ - TSK_DEBUG_ERROR("Failed to resolve(%s/%d)", remote_host, remote_port); - ret = -3; - goto bail; - } - - if(!peer && !(peer = tsk_object_new(tsip_transport_stream_peer_def_t))){ - TSK_DEBUG_ERROR("Failed to create network stream peer"); - ret = -4; - goto bail; - } - - peer->local_fd = local_fd; - peer->type = type; - peer->connected = connected; - peer->remote_port = remote_port; - memcpy(peer->remote_ip, remote_ip, sizeof(remote_ip)); - - tsip_transport_stream_peers_lock(self); - peer->time_latest_activity = tsk_time_now(); - peer->time_added = peer->time_latest_activity; - tsk_list_push_back_data(self->stream_peers, (void**)&peer); - ++self->stream_peers_count; - TSK_DEBUG_INFO("#%d peers in the '%s' transport", self->stream_peers_count, tsip_transport_get_description(self)); - tsip_transport_stream_peers_unlock(self); - - // Cleanup streams - if (self->stream_peers_count > TSIP_TRANSPORT_STREAM_PEERS_COUNT_BEFORE_CHECKING_TIMEOUT && self->stack->network.mode == tsip_stack_mode_webrtc2sip) { - ret = tsip_transport_stream_peers_cleanup(self); - } + } + + if(tsk_strnullORempty(remote_host) || !remote_port) { + if(tnet_get_ip_n_port(local_fd, tsk_false/*remote*/, &remote_ip, &remote_port) != 0) { + TSK_DEBUG_ERROR("Failed to get remote peer ip and address for local fd = %d", local_fd); + ret = -2; + goto bail; + } + remote_host = (const char*)remote_ip; + } + else if((ret = tnet_resolve(remote_host, remote_port, type, &remote_ip, &remote_port))) { + TSK_DEBUG_ERROR("Failed to resolve(%s/%d)", remote_host, remote_port); + ret = -3; + goto bail; + } + + if(!peer && !(peer = tsk_object_new(tsip_transport_stream_peer_def_t))) { + TSK_DEBUG_ERROR("Failed to create network stream peer"); + ret = -4; + goto bail; + } + + peer->local_fd = local_fd; + peer->type = type; + peer->connected = connected; + peer->remote_port = remote_port; + memcpy(peer->remote_ip, remote_ip, sizeof(remote_ip)); + + tsip_transport_stream_peers_lock(self); + peer->time_latest_activity = tsk_time_now(); + peer->time_added = peer->time_latest_activity; + tsk_list_push_back_data(self->stream_peers, (void**)&peer); + ++self->stream_peers_count; + TSK_DEBUG_INFO("#%d peers in the '%s' transport", self->stream_peers_count, tsip_transport_get_description(self)); + tsip_transport_stream_peers_unlock(self); + + // Cleanup streams + if (self->stream_peers_count > TSIP_TRANSPORT_STREAM_PEERS_COUNT_BEFORE_CHECKING_TIMEOUT && self->stack->network.mode == tsip_stack_mode_webrtc2sip) { + ret = tsip_transport_stream_peers_cleanup(self); + } bail: - TSK_OBJECT_SAFE_FREE(peer); - tsip_transport_stream_peers_unlock(self); - return ret; + TSK_OBJECT_SAFE_FREE(peer); + tsip_transport_stream_peers_unlock(self); + return ret; } // up to the caller to release the returned object tsip_transport_stream_peer_t* tsip_transport_find_stream_peer_by_local_fd(tsip_transport_t *self, tnet_fd_t local_fd) { - tsip_transport_stream_peer_t* peer = tsk_null; - tsk_list_item_t* item; - - if(!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return tsk_null; - } - - tsip_transport_stream_peers_lock(self); - tsk_list_foreach(item, self->stream_peers){ - if(((tsip_transport_stream_peer_t*)item->data)->local_fd == local_fd){ - peer = tsk_object_ref(item->data); - break; - } - } - tsip_transport_stream_peers_unlock(self); - return peer; + tsip_transport_stream_peer_t* peer = tsk_null; + tsk_list_item_t* item; + + if(!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tsk_null; + } + + tsip_transport_stream_peers_lock(self); + tsk_list_foreach(item, self->stream_peers) { + if(((tsip_transport_stream_peer_t*)item->data)->local_fd == local_fd) { + peer = tsk_object_ref(item->data); + break; + } + } + tsip_transport_stream_peers_unlock(self); + return peer; } // up to the caller to release the returned object // calling this function will remove the peer from the list tsip_transport_stream_peer_t* tsip_transport_pop_stream_peer_by_local_fd(tsip_transport_t *self, tnet_fd_t local_fd) { - if(self){ - tsip_transport_stream_peer_t* peer = tsk_null; - tsk_list_item_t *item; - tsip_transport_stream_peers_lock(self); - if((item = tsk_list_pop_item_by_pred(self->stream_peers, _pred_find_stream_peer_by_local_fd, &local_fd))){ - peer = tsk_object_ref(item->data); - TSK_OBJECT_SAFE_FREE(item); - --self->stream_peers_count; - TSK_DEBUG_INFO("#%d peers in the '%s' transport", self->stream_peers_count, tsip_transport_get_description(self)); - } - tsip_transport_stream_peers_unlock(self); - return peer; - } - return tsk_null; + if(self) { + tsip_transport_stream_peer_t* peer = tsk_null; + tsk_list_item_t *item; + tsip_transport_stream_peers_lock(self); + if((item = tsk_list_pop_item_by_pred(self->stream_peers, _pred_find_stream_peer_by_local_fd, &local_fd))) { + peer = tsk_object_ref(item->data); + TSK_OBJECT_SAFE_FREE(item); + --self->stream_peers_count; + TSK_DEBUG_INFO("#%d peers in the '%s' transport", self->stream_peers_count, tsip_transport_get_description(self)); + } + tsip_transport_stream_peers_unlock(self); + return peer; + } + return tsk_null; } // up to the caller to release the returned object tsip_transport_stream_peer_t* tsip_transport_find_stream_peer_by_remote_ip(tsip_transport_t *self, const char* remote_ip, tnet_port_t remote_port, enum tnet_socket_type_e type) { - tsip_transport_stream_peer_t* peer = tsk_null; - tsk_list_item_t* item; - - if(!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return tsk_null; - } - - tsip_transport_stream_peers_lock(self); - tsk_list_foreach(item, self->stream_peers){ - if(((tsip_transport_stream_peer_t*)item->data)->type == type && ((tsip_transport_stream_peer_t*)item->data)->remote_port == remote_port && tsk_striequals(((tsip_transport_stream_peer_t*)item->data)->remote_ip, remote_ip)){ - peer = tsk_object_ref(item->data); - break; - } - } - tsip_transport_stream_peers_unlock(self); - return peer; + tsip_transport_stream_peer_t* peer = tsk_null; + tsk_list_item_t* item; + + if(!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tsk_null; + } + + tsip_transport_stream_peers_lock(self); + tsk_list_foreach(item, self->stream_peers) { + if(((tsip_transport_stream_peer_t*)item->data)->type == type && ((tsip_transport_stream_peer_t*)item->data)->remote_port == remote_port && tsk_striequals(((tsip_transport_stream_peer_t*)item->data)->remote_ip, remote_ip)) { + peer = tsk_object_ref(item->data); + break; + } + } + tsip_transport_stream_peers_unlock(self); + return peer; } tsk_bool_t tsip_transport_have_stream_peer_with_remote_ip(tsip_transport_t *self, const char* remote_ip, tnet_port_t remote_port, enum tnet_socket_type_e type) { - if(self && !tsk_strnullORempty(remote_ip) && remote_port){ - tsip_transport_stream_peer_t* peer = tsip_transport_find_stream_peer_by_remote_ip(self, remote_ip, remote_port, type); - if(peer){ - TSK_OBJECT_SAFE_FREE(peer); - return tsk_true; - } - } - return tsk_false; + if(self && !tsk_strnullORempty(remote_ip) && remote_port) { + tsip_transport_stream_peer_t* peer = tsip_transport_find_stream_peer_by_remote_ip(self, remote_ip, remote_port, type); + if(peer) { + TSK_OBJECT_SAFE_FREE(peer); + return tsk_true; + } + } + return tsk_false; } tsk_bool_t tsip_transport_have_stream_peer_with_local_fd(tsip_transport_t *self, tnet_fd_t local_fd) { - tsip_transport_stream_peer_t* peer = tsip_transport_find_stream_peer_by_local_fd(self, local_fd); - tsk_bool_t ret = (peer != tsk_null); - TSK_OBJECT_SAFE_FREE(peer); - return ret; + tsip_transport_stream_peer_t* peer = tsip_transport_find_stream_peer_by_local_fd(self, local_fd); + tsk_bool_t ret = (peer != tsk_null); + TSK_OBJECT_SAFE_FREE(peer); + return ret; } int tsip_transport_remove_stream_peer_by_local_fd(tsip_transport_t *self, tnet_fd_t local_fd) { - if(!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - tsip_transport_stream_peers_lock(self); - if (tsk_list_remove_item_by_pred(self->stream_peers, _pred_find_stream_peer_by_local_fd, &local_fd)) { - --self->stream_peers_count; - TSK_DEBUG_INFO("#%d peers in the '%s' transport", self->stream_peers_count, tsip_transport_get_description(self)); - } - tsip_transport_stream_peers_unlock(self); - - return 0; + if(!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + tsip_transport_stream_peers_lock(self); + if (tsk_list_remove_item_by_pred(self->stream_peers, _pred_find_stream_peer_by_local_fd, &local_fd)) { + --self->stream_peers_count; + TSK_DEBUG_INFO("#%d peers in the '%s' transport", self->stream_peers_count, tsip_transport_get_description(self)); + } + tsip_transport_stream_peers_unlock(self); + + return 0; } int tsip_transport_remove_callid_from_stream_peers(tsip_transport_t *self, const char* callid, tsk_bool_t* removed) { - if(!self || !removed){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - *removed = tsk_false; - if(TNET_SOCKET_TYPE_IS_STREAM(self->type)){ - tsk_list_item_t *item; - tsip_transport_stream_peers_lock(self); - tsk_list_foreach(item, self->stream_peers){ - if(tsip_transport_stream_peer_remove_callid((tsip_transport_stream_peer_t*)item->data, callid, removed) == 0 && *removed){ - TSK_DEBUG_INFO("[Transport] Removed call-id = '%s' from transport with type = %d", callid, self->type); - break; - } - } - tsip_transport_stream_peers_unlock(self); - } - - return 0; + if(!self || !removed) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + *removed = tsk_false; + if(TNET_SOCKET_TYPE_IS_STREAM(self->type)) { + tsk_list_item_t *item; + tsip_transport_stream_peers_lock(self); + tsk_list_foreach(item, self->stream_peers) { + if(tsip_transport_stream_peer_remove_callid((tsip_transport_stream_peer_t*)item->data, callid, removed) == 0 && *removed) { + TSK_DEBUG_INFO("[Transport] Removed call-id = '%s' from transport with type = %d", callid, self->type); + break; + } + } + tsip_transport_stream_peers_unlock(self); + } + + return 0; } tsk_bool_t tsip_transport_stream_peer_have_callid(const tsip_transport_stream_peer_t* self, const char* callid) { - tsk_bool_t have_cid = tsk_false; - if(self){ - const tsk_list_item_t* item; - - tsk_list_lock(self->dialogs_cids); - tsk_list_foreach(item, self->dialogs_cids){ - if(tsk_strequals(TSK_STRING_STR(item->data), callid)){ - have_cid = tsk_true; - break; - } - } - tsk_list_unlock(self->dialogs_cids); - } - return have_cid; + tsk_bool_t have_cid = tsk_false; + if(self) { + const tsk_list_item_t* item; + + tsk_list_lock(self->dialogs_cids); + tsk_list_foreach(item, self->dialogs_cids) { + if(tsk_strequals(TSK_STRING_STR(item->data), callid)) { + have_cid = tsk_true; + break; + } + } + tsk_list_unlock(self->dialogs_cids); + } + return have_cid; } int tsip_transport_stream_peer_add_callid(tsip_transport_stream_peer_t* self, const char* callid) { - if(self && !tsk_strnullORempty(callid)){ - tsk_list_lock(self->dialogs_cids); - if(!tsip_transport_stream_peer_have_callid(self, callid)){ - tsk_string_t* cid = tsk_string_create(callid); - if(cid){ - TSK_DEBUG_INFO("Add call-id = '%s' to peer with local fd = %d", callid, self->local_fd); - tsk_list_push_back_data(self->dialogs_cids, (void**)&cid); - TSK_OBJECT_SAFE_FREE(cid); - } - } - tsk_list_unlock(self->dialogs_cids); - return 0; - } - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; + if(self && !tsk_strnullORempty(callid)) { + tsk_list_lock(self->dialogs_cids); + if(!tsip_transport_stream_peer_have_callid(self, callid)) { + tsk_string_t* cid = tsk_string_create(callid); + if(cid) { + TSK_DEBUG_INFO("Add call-id = '%s' to peer with local fd = %d", callid, self->local_fd); + tsk_list_push_back_data(self->dialogs_cids, (void**)&cid); + TSK_OBJECT_SAFE_FREE(cid); + } + } + tsk_list_unlock(self->dialogs_cids); + return 0; + } + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; } int tsip_transport_stream_peer_remove_callid(tsip_transport_stream_peer_t* self, const char* callid, tsk_bool_t *removed) { - if(self && removed){ - *removed = tsk_false; - tsk_list_lock(self->dialogs_cids); - if((*removed = tsk_list_remove_item_by_pred(self->dialogs_cids, tsk_string_pred_cmp, callid)) == tsk_true){ - TSK_DEBUG_INFO("[Stream] Removed call-id = '%s' from peer with local fd = %d", callid, self->local_fd); - } - tsk_list_unlock(self->dialogs_cids); - return 0; - } - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; + if(self && removed) { + *removed = tsk_false; + tsk_list_lock(self->dialogs_cids); + if((*removed = tsk_list_remove_item_by_pred(self->dialogs_cids, tsk_string_pred_cmp, callid)) == tsk_true) { + TSK_DEBUG_INFO("[Stream] Removed call-id = '%s' from peer with local fd = %d", callid, self->local_fd); + } + tsk_list_unlock(self->dialogs_cids); + return 0; + } + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; } int tsip_transport_stream_peers_cleanup(tsip_transport_t *self) { - if(!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if (TNET_SOCKET_TYPE_IS_STREAM(self->type)) { - tsk_list_item_t *item; - tsip_transport_stream_peer_t *peer; - tnet_fd_t fd; - tsk_bool_t close; - uint64_t now = tsk_time_now(); - tsip_transport_stream_peers_lock(self); - tsk_list_foreach(item, self->stream_peers) { - if ((peer = (item->data))) { - close = ((now - TSIP_TRANSPORT_STREAM_PEER_TIMEOUT) > peer->time_latest_activity); - if (!close) { - close = !peer->got_valid_sip_msg && ((now - TSIP_TRANSPORT_STREAM_PEER_FIRST_MSG_TIMEOUT) > peer->time_added); - } - if (!close) { - if ((TNET_SOCKET_TYPE_IS_WS(peer->type) || TNET_SOCKET_TYPE_IS_WSS(peer->type)) && !peer->ws.handshaking_done) { - close = ((now - TSIP_TRANSPORT_STREAM_PEER_WS_HANDSHAKING_TIMEOUT) > peer->time_added); - } - } - if (close) { - fd = peer->local_fd; - TSK_DEBUG_INFO("Peer with fd=%d, type=%d, got_valid_sip_msg=%d, time_added=%llu, time_latest_activity=%llu, now=%llu in '%s' transport timedout", - fd, peer->type, peer->got_valid_sip_msg, peer->time_added, peer->time_latest_activity, now, tsip_transport_get_description(self)); - tsip_transport_remove_socket(self, (tnet_fd_t *)&fd); - } - } - } - tsip_transport_stream_peers_unlock(self); - } - - return 0; + if(!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if (TNET_SOCKET_TYPE_IS_STREAM(self->type)) { + tsk_list_item_t *item; + tsip_transport_stream_peer_t *peer; + tnet_fd_t fd; + tsk_bool_t close; + uint64_t now = tsk_time_now(); + tsip_transport_stream_peers_lock(self); + tsk_list_foreach(item, self->stream_peers) { + if ((peer = (item->data))) { + close = ((now - TSIP_TRANSPORT_STREAM_PEER_TIMEOUT) > peer->time_latest_activity); + if (!close) { + close = !peer->got_valid_sip_msg && ((now - TSIP_TRANSPORT_STREAM_PEER_FIRST_MSG_TIMEOUT) > peer->time_added); + } + if (!close) { + if ((TNET_SOCKET_TYPE_IS_WS(peer->type) || TNET_SOCKET_TYPE_IS_WSS(peer->type)) && !peer->ws.handshaking_done) { + close = ((now - TSIP_TRANSPORT_STREAM_PEER_WS_HANDSHAKING_TIMEOUT) > peer->time_added); + } + } + if (close) { + fd = peer->local_fd; + TSK_DEBUG_INFO("Peer with fd=%d, type=%d, got_valid_sip_msg=%d, time_added=%llu, time_latest_activity=%llu, now=%llu in '%s' transport timedout", + fd, peer->type, peer->got_valid_sip_msg, peer->time_added, peer->time_latest_activity, now, tsip_transport_get_description(self)); + tsip_transport_remove_socket(self, (tnet_fd_t *)&fd); + } + } + } + tsip_transport_stream_peers_unlock(self); + } + + return 0; } int tsip_transport_init(tsip_transport_t* self, tnet_socket_type_t type, const struct tsip_stack_s *stack, const char *host, tnet_port_t port, const char* description) { - if(!self || self->initialized){ - return -1; - } - - self->stack = stack; - self->type = type; - self->net_transport = tnet_transport_create(host, port, type, description); - - self->scheme = "sip"; - - if(TNET_SOCKET_TYPE_IS_STREAM(type)){ - if(TNET_SOCKET_TYPE_IS_TLS(type)){ - self->scheme = "sips"; - self->protocol = "tcp"; - self->via_protocol = "TLS"; - self->service = "SIPS+D2T"; - } - else if(TNET_SOCKET_TYPE_IS_WS(type)){ - self->protocol = "ws"; - self->via_protocol = "WS"; - self->service = "SIP+D2W"; - } - else if(TNET_SOCKET_TYPE_IS_WSS(type)){ - self->scheme = "sips"; - self->protocol = "wss"; - self->via_protocol = "WSS"; - self->service = "SIPS+D2W"; - } - else{ - self->protocol = "tcp"; - self->via_protocol = "TCP"; - self->service = "SIP+D2T"; - } - - /* Stream buffer */ - self->stream_peers = tsk_list_create(); + if(!self || self->initialized) { + return -1; + } + + self->stack = stack; + self->type = type; + self->net_transport = tnet_transport_create(host, port, type, description); + + self->scheme = "sip"; + + if(TNET_SOCKET_TYPE_IS_STREAM(type)) { + if(TNET_SOCKET_TYPE_IS_TLS(type)) { + self->scheme = "sips"; + self->protocol = "tcp"; + self->via_protocol = "TLS"; + self->service = "SIPS+D2T"; + } + else if(TNET_SOCKET_TYPE_IS_WS(type)) { + self->protocol = "ws"; + self->via_protocol = "WS"; + self->service = "SIP+D2W"; + } + else if(TNET_SOCKET_TYPE_IS_WSS(type)) { + self->scheme = "sips"; + self->protocol = "wss"; + self->via_protocol = "WSS"; + self->service = "SIPS+D2W"; + } + else { + self->protocol = "tcp"; + self->via_protocol = "TCP"; + self->service = "SIP+D2T"; + } + + /* Stream buffer */ + self->stream_peers = tsk_list_create(); if (!self->stream_peers) { return -1; } - } - else{ - if(TNET_SOCKET_TYPE_IS_DTLS(type)){ - self->scheme = "sips"; - self->protocol = "dtls-udp"; - self->via_protocol = "DTLS-UDP"; - self->service = "SIPS+D2U"; - } - else{ - self->protocol = "udp"; - self->via_protocol = "UDP"; - self->service = "SIP+D2U"; - } - } - self->connectedFD = TNET_INVALID_FD; - self->initialized = 1; - - return 0; + } + else { + if(TNET_SOCKET_TYPE_IS_DTLS(type)) { + self->scheme = "sips"; + self->protocol = "dtls-udp"; + self->via_protocol = "DTLS-UDP"; + self->service = "SIPS+D2U"; + } + else { + self->protocol = "udp"; + self->via_protocol = "UDP"; + self->service = "SIP+D2U"; + } + } + self->connectedFD = TNET_INVALID_FD; + self->initialized = 1; + + return 0; } int tsip_transport_deinit(tsip_transport_t* self) { - if(!self || !self->initialized){ - return -1; - } - - TSK_OBJECT_SAFE_FREE(self->net_transport); - TSK_OBJECT_SAFE_FREE(self->stream_peers); - - self->initialized = 0; - return 0; + if(!self || !self->initialized) { + return -1; + } + + TSK_OBJECT_SAFE_FREE(self->net_transport); + TSK_OBJECT_SAFE_FREE(self->stream_peers); + + self->initialized = 0; + return 0; } @@ -995,53 +996,52 @@ int tsip_transport_deinit(tsip_transport_t* self) // static tsk_object_t* tsip_transport_ctor(tsk_object_t * self, va_list * app) { - tsip_transport_t *transport = self; - if(transport){ - const tsip_stack_handle_t *stack = va_arg(*app, const tsip_stack_handle_t*); - const char *host = va_arg(*app, const char*); + tsip_transport_t *transport = self; + if(transport) { + const tsip_stack_handle_t *stack = va_arg(*app, const tsip_stack_handle_t*); + 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*); - - if(tsip_transport_init(transport, type, stack, host, port, description)){ - TSK_DEBUG_ERROR("Failed to initialize transport"); - return tsk_null; - } - } - return self; + tnet_socket_type_t type = va_arg(*app, tnet_socket_type_t); + const char *description = va_arg(*app, const char*); + + if(tsip_transport_init(transport, type, stack, host, port, description)) { + TSK_DEBUG_ERROR("Failed to initialize transport"); + return tsk_null; + } + } + return self; } static tsk_object_t* tsip_transport_dtor(tsk_object_t * self) -{ - tsip_transport_t *transport = self; - if(transport){ - tsip_transport_deinit(transport); - } - return self; +{ + tsip_transport_t *transport = self; + if(transport) { + tsip_transport_deinit(transport); + } + return self; } static int tsip_transport_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) { - const tsip_transport_t *transport1 = obj1; - const tsip_transport_t *transport2 = obj2; - if(transport1 && transport2){ - const char* desc1 = tsip_transport_get_description(transport1); - const char* desc2 = tsip_transport_get_description(transport2); - return tsk_stricmp(desc1, desc2); - } - return -1; + const tsip_transport_t *transport1 = obj1; + const tsip_transport_t *transport2 = obj2; + if(transport1 && transport2) { + const char* desc1 = tsip_transport_get_description(transport1); + const char* desc2 = tsip_transport_get_description(transport2); + return tsk_stricmp(desc1, desc2); + } + return -1; } -static const tsk_object_def_t tsip_transport_def_s = -{ - sizeof(tsip_transport_t), - tsip_transport_ctor, - tsip_transport_dtor, - tsip_transport_cmp, +static const tsk_object_def_t tsip_transport_def_s = { + sizeof(tsip_transport_t), + tsip_transport_ctor, + tsip_transport_dtor, + tsip_transport_cmp, }; const tsk_object_def_t *tsip_transport_def_t = &tsip_transport_def_s; @@ -1053,51 +1053,50 @@ const tsk_object_def_t *tsip_transport_def_t = &tsip_transport_def_s; // static tsk_object_t* tsip_transport_stream_peer_ctor(tsk_object_t * self, va_list * app) { - tsip_transport_stream_peer_t *peer = self; - if(peer){ - if (!(peer->rcv_buff_stream = tsk_buffer_create_null())) { + tsip_transport_stream_peer_t *peer = self; + if(peer) { + if (!(peer->rcv_buff_stream = tsk_buffer_create_null())) { return tsk_null; } - if (!(peer->snd_buff_stream = tsk_buffer_create_null())) { + if (!(peer->snd_buff_stream = tsk_buffer_create_null())) { return tsk_null; } - if (!(peer->dialogs_cids = tsk_list_create())){ + if (!(peer->dialogs_cids = tsk_list_create())) { return tsk_null; } - } - return self; + } + return self; } static tsk_object_t* tsip_transport_stream_peer_dtor(tsk_object_t * self) -{ - tsip_transport_stream_peer_t *peer = self; - if(peer){ - TSK_DEBUG_INFO("*** Stream Peer destroyed ***"); - TSK_OBJECT_SAFE_FREE(peer->rcv_buff_stream); - TSK_OBJECT_SAFE_FREE(peer->snd_buff_stream); - - TSK_SAFE_FREE(peer->ws.rcv_buffer); - peer->ws.rcv_buffer_size = 0; - TSK_SAFE_FREE(peer->ws.snd_buffer); - peer->ws.snd_buffer_size = 0; - - TSK_OBJECT_SAFE_FREE(peer->dialogs_cids); - } - return self; +{ + tsip_transport_stream_peer_t *peer = self; + if(peer) { + TSK_DEBUG_INFO("*** Stream Peer destroyed ***"); + TSK_OBJECT_SAFE_FREE(peer->rcv_buff_stream); + TSK_OBJECT_SAFE_FREE(peer->snd_buff_stream); + + TSK_SAFE_FREE(peer->ws.rcv_buffer); + peer->ws.rcv_buffer_size = 0; + TSK_SAFE_FREE(peer->ws.snd_buffer); + peer->ws.snd_buffer_size = 0; + + TSK_OBJECT_SAFE_FREE(peer->dialogs_cids); + } + return self; } static int tsip_transport_stream_peer_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) { - const tsip_transport_stream_peer_t *peer1 = obj1; - const tsip_transport_stream_peer_t *peer2 = obj2; - if(peer1 && peer2){ - return (peer1->local_fd - peer2->local_fd); - } - return -1; + const tsip_transport_stream_peer_t *peer1 = obj1; + const tsip_transport_stream_peer_t *peer2 = obj2; + if(peer1 && peer2) { + return (peer1->local_fd - peer2->local_fd); + } + return -1; } -static const tsk_object_def_t tsip_transport_stream_peer_def_s = -{ - sizeof(tsip_transport_stream_peer_t), - tsip_transport_stream_peer_ctor, - tsip_transport_stream_peer_dtor, - tsip_transport_stream_peer_cmp, +static const tsk_object_def_t tsip_transport_stream_peer_def_s = { + sizeof(tsip_transport_stream_peer_t), + tsip_transport_stream_peer_ctor, + tsip_transport_stream_peer_dtor, + tsip_transport_stream_peer_cmp, }; const tsk_object_def_t *tsip_transport_stream_peer_def_t = &tsip_transport_stream_peer_def_s; |