diff options
author | Benny Prijono <bennylp@teluu.com> | 2005-12-26 12:52:19 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2005-12-26 12:52:19 +0000 |
commit | 9b86a2145e18cb843e69167b10f3c7414c11c634 (patch) | |
tree | af539d9ce30ccd8f1d60cca5916496c442499375 /pjsip/src | |
parent | 346427b7dc57954f772beb165ef320c1639ba223 (diff) |
Modify transport to use generic sockaddr address
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@105 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip/src')
-rw-r--r-- | pjsip/src/pjsip/sip_endpoint.c | 27 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_resolve.c | 21 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_transaction.c | 62 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_transport.c | 145 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_transport_udp.c | 160 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_util.c | 20 | ||||
-rw-r--r-- | pjsip/src/test-pjsip/msg_test.c (renamed from pjsip/src/test-pjsip/msg.c) | 0 | ||||
-rw-r--r-- | pjsip/src/test-pjsip/uri_test.c (renamed from pjsip/src/test-pjsip/uri.c) | 0 |
8 files changed, 249 insertions, 186 deletions
diff --git a/pjsip/src/pjsip/sip_endpoint.c b/pjsip/src/pjsip/sip_endpoint.c index dae3d5b1..b3fa2f8c 100644 --- a/pjsip/src/pjsip/sip_endpoint.c +++ b/pjsip/src/pjsip/sip_endpoint.c @@ -725,8 +725,8 @@ static void endpt_transport_callback( pjsip_endpoint *endpt, PJ_LOG(5, (THIS_FILE, "endpt_transport_callback(rdata=%p)", rdata)); if (status != PJ_SUCCESS) { - const char *src_addr = pj_inet_ntoa(rdata->pkt_info.addr.sin_addr); - int port = pj_ntohs(rdata->pkt_info.addr.sin_port); + const char *src_addr = rdata->pkt_info.src_name; + int port = rdata->pkt_info.src_port; PJSIP_ENDPT_LOG_ERROR((endpt, "transport", status, "Src.addr=%s:%d, packet:--\n" "%s\n" @@ -740,20 +740,18 @@ static void endpt_transport_callback( pjsip_endpoint *endpt, * Ref: RFC3261 Section 18.1.2 Receiving Response */ if (msg->type == PJSIP_RESPONSE_MSG) { - const pj_sockaddr_in *addr; - const char *addr_addr; + const pj_str_t *addr_addr; int port = rdata->msg_info.via->sent_by.port; pj_bool_t mismatch = PJ_FALSE; if (port == 0) { int type; - type = rdata->tp_info.transport->type; + type = rdata->tp_info.transport->key.type; port = pjsip_transport_get_default_port_for_type(type); } - addr = &rdata->tp_info.transport->public_addr; - addr_addr = pj_inet_ntoa(addr->sin_addr); - if (pj_strcmp2(&rdata->msg_info.via->sent_by.host, addr_addr) != 0) + addr_addr = &rdata->tp_info.transport->local_name.host; + if (pj_strcmp(&rdata->msg_info.via->sent_by.host, addr_addr) != 0) mismatch = PJ_TRUE; - else if (port != pj_ntohs(addr->sin_port)) { + else if (port != rdata->tp_info.transport->local_name.port) { /* Port or address mismatch, we should discard response */ /* But we saw one implementation (we don't want to name it to * protect the innocence) which put wrong sent-by port although @@ -761,7 +759,7 @@ static void endpt_transport_callback( pjsip_endpoint *endpt, * So we discard the response only if the port doesn't match * both the port in sent-by and rport. We try to be lenient here! */ - if (rdata->msg_info.via->rport_param != pj_sockaddr_in_get_port(addr)) + if (rdata->msg_info.via->rport_param != rdata->tp_info.transport->local_name.port) mismatch = PJ_TRUE; else { PJ_LOG(4,(THIS_FILE, "Response %p has mismatch port in sent-by" @@ -958,7 +956,7 @@ PJ_DEF(pj_status_t) pjsip_endpt_create_tdata( pjsip_endpoint *endpt, */ PJ_DEF(void) pjsip_endpt_resolve( pjsip_endpoint *endpt, pj_pool_t *pool, - pjsip_host_port *target, + pjsip_host_info *target, void *token, pjsip_resolver_callback *cb) { @@ -987,12 +985,13 @@ PJ_DEF(pj_ioqueue_t*) pjsip_endpt_get_ioqueue(pjsip_endpoint *endpt) */ PJ_DEF(pj_status_t) pjsip_endpt_alloc_transport( pjsip_endpoint *endpt, pjsip_transport_type_e type, - const pj_sockaddr_in *remote, + const pj_sockaddr *remote, + int addr_len, pjsip_transport **p_transport) { PJ_LOG(5, (THIS_FILE, "pjsip_endpt_alloc_transport()")); - return pjsip_tpmgr_alloc_transport( endpt->transport_mgr, type, remote, - p_transport); + return pjsip_tpmgr_alloc_transport( endpt->transport_mgr, type, + remote, addr_len, p_transport); } diff --git a/pjsip/src/pjsip/sip_resolve.c b/pjsip/src/pjsip/sip_resolve.c index b89b7c01..4be6f56c 100644 --- a/pjsip/src/pjsip/sip_resolve.c +++ b/pjsip/src/pjsip/sip_resolve.c @@ -56,7 +56,7 @@ static int is_str_ip(const pj_str_t *host) PJ_DEF(void) pjsip_resolve( pjsip_resolver_t *resolver, pj_pool_t *pool, - pjsip_host_port *target, + pjsip_host_info *target, void *token, pjsip_resolver_callback *cb) { @@ -72,13 +72,13 @@ PJ_DEF(void) pjsip_resolve( pjsip_resolver_t *resolver, PJ_TODO(SUPPORT_RFC3263_SERVER_RESOLUTION) /* Is it IP address or hostname?. */ - is_ip_addr = is_str_ip(&target->host); + is_ip_addr = is_str_ip(&target->addr.host); /* Set the transport type if not explicitly specified. * RFC 3263 section 4.1 specify rules to set up this. */ if (type == PJSIP_TRANSPORT_UNSPECIFIED) { - if (is_ip_addr || (target->port != 0)) { + if (is_ip_addr || (target->addr.port != 0)) { #if PJ_HAS_TCP if (target->flag & PJSIP_TRANSPORT_SECURE) { @@ -103,23 +103,26 @@ PJ_DEF(void) pjsip_resolve( pjsip_resolver_t *resolver, } /* Set the port number if not specified. */ - if (target->port == 0) { - target->port = pjsip_transport_get_default_port_for_type(type); + if (target->addr.port == 0) { + target->addr.port = pjsip_transport_get_default_port_for_type(type); } /* Resolve hostname. */ if (!is_ip_addr) { - status = pj_sockaddr_in_init(&svr_addr.entry[0].addr, &target->host, - (pj_uint16_t)target->port); + status = pj_sockaddr_in_init((pj_sockaddr_in*)&svr_addr.entry[0].addr, + &target->addr.host, + (pj_uint16_t)target->addr.port); } else { - status = pj_sockaddr_in_init(&svr_addr.entry[0].addr, &target->host, - (pj_uint16_t)target->port); + status = pj_sockaddr_in_init((pj_sockaddr_in*)&svr_addr.entry[0].addr, + &target->addr.host, + (pj_uint16_t)target->addr.port); pj_assert(status == PJ_SUCCESS); } /* Call the callback. */ svr_addr.count = (status == PJ_SUCCESS) ? 1 : 0; svr_addr.entry[0].type = type; + svr_addr.entry[0].addr_len = sizeof(pj_sockaddr_in); (*cb)(status, token, &svr_addr); } diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c index eade0a4b..bb9eee9d 100644 --- a/pjsip/src/pjsip/sip_transaction.c +++ b/pjsip/src/pjsip/sip_transaction.c @@ -498,7 +498,7 @@ static void tsx_set_state( pjsip_transaction *tsx, */ static pj_status_t tsx_process_route( pjsip_transaction *tsx, pjsip_tx_data *tdata, - pjsip_host_port *send_addr ) + pjsip_host_info *send_addr ) { const pjsip_uri *new_request_uri, *target_uri; const pjsip_name_addr *topmost_route_uri; @@ -595,16 +595,16 @@ static pj_status_t tsx_process_route( pjsip_transaction *tsx, pjsip_uri *uri = (pjsip_uri*) target_uri; const pjsip_url *url = (const pjsip_url*)pjsip_uri_get_uri(uri); send_addr->flag |= (PJSIP_TRANSPORT_SECURE | PJSIP_TRANSPORT_RELIABLE); - pj_strdup(tdata->pool, &send_addr->host, &url->host); - send_addr->port = url->port; + pj_strdup(tdata->pool, &send_addr->addr.host, &url->host); + send_addr->addr.port = url->port; send_addr->type = pjsip_transport_get_type_from_name(&url->transport_param); } else if (PJSIP_URI_SCHEME_IS_SIP(target_uri)) { pjsip_uri *uri = (pjsip_uri*) target_uri; const pjsip_url *url = (const pjsip_url*)pjsip_uri_get_uri(uri); - pj_strdup(tdata->pool, &send_addr->host, &url->host); - send_addr->port = url->port; + pj_strdup(tdata->pool, &send_addr->addr.host, &url->host); + send_addr->addr.port = url->port; send_addr->type = pjsip_transport_get_type_from_name(&url->transport_param); #if PJ_HAS_TCP @@ -650,18 +650,18 @@ static void tsx_transport_callback(pjsip_transport *tr, pjsip_transaction *tsx = token; struct tsx_lock_data lck; - pj_memcpy(addr, tsx->dest_name.host.ptr, tsx->dest_name.host.slen); - addr[tsx->dest_name.host.slen] = '\0'; + pj_memcpy(addr, tsx->dest_name.addr.host.ptr, tsx->dest_name.addr.host.slen); + addr[tsx->dest_name.addr.host.slen] = '\0'; if (status == PJ_SUCCESS) { PJ_LOG(4, (tsx->obj_name, "%s connected to %s:%d", tr->type_name, - addr, tsx->dest_name.port)); + addr, tsx->dest_name.addr.port)); } else { PJ_LOG(4, (tsx->obj_name, "%s unable to connect to %s:%d, status=%d", tr->type_name, - addr, tsx->dest_name.port, status)); + addr, tsx->dest_name.addr.port, status)); } /* Lock transaction. */ @@ -737,13 +737,10 @@ static void tsx_resolver_callback(pj_status_t status, pj_memcpy(&tsx->remote_addr, addr, sizeof(*addr)); /* Create/find the transport for the remote address. */ - PJ_LOG(5,(tsx->obj_name, "tsx getting transport for %s:%d", - pj_inet_ntoa(addr->entry[0].addr.sin_addr), - pj_ntohs(addr->entry[0].addr.sin_port))); - tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_CONNECTING; status = pjsip_endpt_alloc_transport( tsx->endpt, addr->entry[0].type, &addr->entry[0].addr, + addr->entry[0].addr_len, &tp); tsx_transport_callback(tp, tsx, status); @@ -851,9 +848,9 @@ PJ_DEF(pj_status_t) pjsip_tsx_init_uac( pjsip_transaction *tsx, * the callback will be called. */ PJ_LOG(5,(tsx->obj_name, "tsx resolving destination %.*s:%d", - tsx->dest_name.host.slen, - tsx->dest_name.host.ptr, - tsx->dest_name.port)); + tsx->dest_name.addr.host.slen, + tsx->dest_name.addr.host.ptr, + tsx->dest_name.addr.port)); tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_RESOLVING; pjsip_endpt_resolve( tsx->endpt, tsx->pool, &tsx->dest_name, @@ -941,9 +938,9 @@ PJ_DEF(pj_status_t) pjsip_tsx_init_uas( pjsip_transaction *tsx, tsx->current_addr = 0; tsx->remote_addr.count = 1; - tsx->remote_addr.entry[0].type = tsx->transport->type; + tsx->remote_addr.entry[0].type = tsx->transport->key.type; pj_memcpy(&tsx->remote_addr.entry[0].addr, - &rdata->pkt_info.addr, rdata->pkt_info.addr_len); + &rdata->pkt_info.src_addr, rdata->pkt_info.src_addr_len); } else { pj_status_t status; @@ -964,9 +961,9 @@ PJ_DEF(pj_status_t) pjsip_tsx_init_uas( pjsip_transaction *tsx, * the callback will be called. */ PJ_LOG(5,(tsx->obj_name, "tsx resolving destination %.*s:%d", - tsx->dest_name.host.slen, - tsx->dest_name.host.ptr, - tsx->dest_name.port)); + tsx->dest_name.addr.host.slen, + tsx->dest_name.addr.host.ptr, + tsx->dest_name.addr.port)); tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_RESOLVING; pjsip_endpt_resolve( tsx->endpt, tsx->pool, &tsx->dest_name, @@ -1023,7 +1020,7 @@ static void tsx_timer_callback( pj_timer_heap_t *theap, pj_timer_entry *entry) PJ_DEF(void) pjsip_tsx_on_tx_ack( pjsip_transaction *tsx, pjsip_tx_data *tdata) { pjsip_msg *msg; - pjsip_host_port dest_addr; + pjsip_host_info dest_addr; pjsip_via_hdr *via; struct tsx_lock_data lck; pj_status_t status = PJ_SUCCESS; @@ -1059,8 +1056,8 @@ PJ_DEF(void) pjsip_tsx_on_tx_ack( pjsip_transaction *tsx, pjsip_tx_data *tdata) */ if (dest_addr.type == tsx->dest_name.type && dest_addr.flag == tsx->dest_name.flag && - dest_addr.port == tsx->dest_name.port && - pj_stricmp(&dest_addr.host, &tsx->dest_name.host) == 0) + dest_addr.addr.port == tsx->dest_name.addr.port && + pj_stricmp(&dest_addr.addr.host, &tsx->dest_name.addr.host) == 0) { /* Equal destination. We can use current transport. */ pjsip_tsx_on_tx_msg(tsx, tdata); @@ -1071,12 +1068,12 @@ PJ_DEF(void) pjsip_tsx_on_tx_ack( pjsip_transaction *tsx, pjsip_tx_data *tdata) /* New destination; we'll have to resolve host and create new transport. */ pj_memcpy(&tsx->dest_name, &dest_addr, sizeof(dest_addr)); - pj_strdup(tsx->pool, &tsx->dest_name.host, &dest_addr.host); + pj_strdup(tsx->pool, &tsx->dest_name.addr.host, &dest_addr.addr.host); PJ_LOG(5,(tsx->obj_name, "tsx resolving destination %.*s:%d", - tsx->dest_name.host.slen, - tsx->dest_name.host.ptr, - tsx->dest_name.port)); + tsx->dest_name.addr.host.slen, + tsx->dest_name.addr.host.ptr, + tsx->dest_name.addr.port)); tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_RESOLVING; pjsip_transport_dec_ref(tsx->transport); @@ -1215,7 +1212,6 @@ static pj_status_t tsx_send_msg( pjsip_transaction *tsx, * requests. */ if (tdata->msg->type == PJSIP_REQUEST_MSG) { - const pj_sockaddr_in *addr_name; pjsip_via_hdr *via = (pjsip_via_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL); @@ -1225,12 +1221,11 @@ static pj_status_t tsx_send_msg( pjsip_transaction *tsx, /* Don't update Via sent-by on retransmission. */ if (via->sent_by.host.slen == 0) { - addr_name = &tsx->transport->public_addr; pj_strdup2(tdata->pool, &via->transport, tsx->transport->type_name); - pj_strdup2(tdata->pool, &via->sent_by.host, - pj_inet_ntoa(addr_name->sin_addr)); - via->sent_by.port = pj_ntohs(addr_name->sin_port); + pj_strdup(tdata->pool, &via->sent_by.host, + &tsx->transport->local_name.host); + via->sent_by.port = tsx->transport->local_name.port; } } @@ -1242,6 +1237,7 @@ static pj_status_t tsx_send_msg( pjsip_transaction *tsx, tsx->has_unsent_msg = 0; status = pjsip_transport_send(tsx->transport, tdata, &tsx->remote_addr.entry[tsx->current_addr].addr, + tsx->remote_addr.entry[tsx->current_addr].addr_len, tsx, &tsx_on_send_complete); if (status != PJ_SUCCESS && status != PJ_EPENDING) { PJ_TODO(HANDLE_TRANSPORT_ERROR); diff --git a/pjsip/src/pjsip/sip_transport.c b/pjsip/src/pjsip/sip_transport.c index 225eabed..7299060c 100644 --- a/pjsip/src/pjsip/sip_transport.c +++ b/pjsip/src/pjsip/sip_transport.c @@ -46,8 +46,6 @@ struct pjsip_tpmgr void (*msg_cb)(pjsip_endpoint*, pj_status_t, pjsip_rx_data*); }; - - /***************************************************************************** * * GENERAL TRANSPORT (NAMES, TYPES, ETC.) @@ -81,6 +79,13 @@ pjsip_transport_get_type_from_name(const pj_str_t *name) { unsigned i; + /* Sanity check. + * Check that transport_names[] are indexed on transport type. + */ + PJ_ASSERT_RETURN(transport_names[PJSIP_TRANSPORT_UDP].type == + PJSIP_TRANSPORT_UDP, PJSIP_TRANSPORT_UNSPECIFIED); + + /* Get transport type from name. */ for (i=0; i<PJ_ARRAY_SIZE(transport_names); ++i) { if (pj_stricmp(name, &transport_names[i].name) == 0) { return transport_names[i].type; @@ -100,6 +105,13 @@ pjsip_transport_get_type_from_flag(unsigned flag) { unsigned i; + /* Sanity check. + * Check that transport_names[] are indexed on transport type. + */ + PJ_ASSERT_RETURN(transport_names[PJSIP_TRANSPORT_UDP].type == + PJSIP_TRANSPORT_UDP, PJSIP_TRANSPORT_UNSPECIFIED); + + /* Get the transport type for the specified flags. */ for (i=0; i<PJ_ARRAY_SIZE(transport_names); ++i) { if (transport_names[i].flag == flag) { return transport_names[i].type; @@ -113,7 +125,16 @@ pjsip_transport_get_type_from_flag(unsigned flag) PJ_DEF(unsigned) pjsip_transport_get_flag_from_type( pjsip_transport_type_e type ) { + /* Sanity check. + * Check that transport_names[] are indexed on transport type. + */ + PJ_ASSERT_RETURN(transport_names[PJSIP_TRANSPORT_UDP].type == + PJSIP_TRANSPORT_UDP, 0); + + /* Check that argument is valid. */ PJ_ASSERT_RETURN(type < PJ_ARRAY_SIZE(transport_names), 0); + + /* Return transport flag. */ return transport_names[type].flag; } @@ -123,7 +144,16 @@ pjsip_transport_get_flag_from_type( pjsip_transport_type_e type ) PJ_DEF(int) pjsip_transport_get_default_port_for_type(pjsip_transport_type_e type) { + /* Sanity check. + * Check that transport_names[] are indexed on transport type. + */ + PJ_ASSERT_RETURN(transport_names[PJSIP_TRANSPORT_UDP].type == + PJSIP_TRANSPORT_UDP, 0); + + /* Check that argument is valid. */ PJ_ASSERT_RETURN(type < PJ_ARRAY_SIZE(transport_names), 5060); + + /* Return the port. */ return transport_names[type].port; } @@ -224,17 +254,6 @@ PJ_DEF(pj_bool_t) pjsip_tx_data_is_valid( pjsip_tx_data *tdata ) * *****************************************************************************/ -/* - * Transport key for indexing in the hash table. - */ -typedef struct transport_key -{ - pj_uint8_t type; - pj_uint8_t zero; - pj_uint16_t port; - pj_uint32_t addr; -} transport_key; - /***************************************************************************** * @@ -269,7 +288,8 @@ static void transport_send_callback(pjsip_transport *transport, */ PJ_DEF(pj_status_t) pjsip_transport_send( pjsip_transport *tr, pjsip_tx_data *tdata, - const pj_sockaddr_in *addr, + const pj_sockaddr *addr, + int addr_len, void *token, void (*cb)(void *token, pjsip_tx_data *tdata, @@ -317,7 +337,7 @@ PJ_DEF(pj_status_t) pjsip_transport_send( pjsip_transport *tr, tdata->is_pending = 1; /* Send to transport. */ - status = (*tr->send_msg)(tr, tdata, addr, (void*)tdata, + status = (*tr->send_msg)(tr, tdata, addr, addr_len, (void*)tdata, &transport_send_callback); if (status != PJ_EPENDING) { @@ -395,7 +415,7 @@ PJ_DEF(pj_status_t) pjsip_transport_dec_ref( pjsip_transport *tp ) PJ_DEF(pj_status_t) pjsip_transport_register( pjsip_tpmgr *mgr, pjsip_transport *tp ) { - transport_key key; + int key_len; /* Init. */ tp->tpmgr = mgr; @@ -406,13 +426,9 @@ PJ_DEF(pj_status_t) pjsip_transport_register( pjsip_tpmgr *mgr, /* * Register to hash table. */ - key.type = (pj_uint8_t)tp->type; - key.zero = 0; - key.addr = pj_ntohl(tp->rem_addr.sin_addr.s_addr); - key.port = pj_ntohs(tp->rem_addr.sin_port); - + key_len = sizeof(tp->key.type) + tp->addr_len; pj_lock_acquire(mgr->lock); - pj_hash_set(tp->pool, mgr->table, &key, sizeof(key), tp); + pj_hash_set(tp->pool, mgr->table, &tp->key, key_len, tp); pj_lock_release(mgr->lock); return PJ_SUCCESS; @@ -425,8 +441,9 @@ PJ_DEF(pj_status_t) pjsip_transport_register( pjsip_tpmgr *mgr, PJ_DEF(pj_status_t) pjsip_transport_unregister( pjsip_tpmgr *mgr, pjsip_transport *tp) { - transport_key key; + int key_len; + /* Must have no user. */ PJ_ASSERT_RETURN(pj_atomic_get(tp->ref_cnt) == 0, PJSIP_EBUSY); pj_lock_acquire(tp->lock); @@ -444,12 +461,8 @@ PJ_DEF(pj_status_t) pjsip_transport_unregister( pjsip_tpmgr *mgr, /* * Unregister from hash table. */ - key.type = (pj_uint8_t)tp->type; - key.zero = 0; - key.addr = pj_ntohl(tp->rem_addr.sin_addr.s_addr); - key.port = pj_ntohs(tp->rem_addr.sin_port); - - pj_hash_set(tp->pool, mgr->table, &key, sizeof(key), NULL); + key_len = sizeof(tp->key.type) + tp->addr_len; + pj_hash_set(tp->pool, mgr->table, &tp->key, key_len, NULL); pj_lock_release(mgr->lock); @@ -601,7 +614,6 @@ PJ_DEF(pj_ssize_t) pjsip_tpmgr_receive_packet( pjsip_tpmgr *mgr, pjsip_rx_data *rdata) { pjsip_transport *tr = rdata->tp_info.transport; - pj_str_t s; char *current_pkt; pj_size_t remaining_len; @@ -682,18 +694,19 @@ PJ_DEF(pj_ssize_t) pjsip_tpmgr_receive_packet( pjsip_tpmgr *mgr, /* If message is received from address that's different from sent-by, * MUST add received parameter to the via. */ - s = pj_str(pj_inet_ntoa(rdata->pkt_info.addr.sin_addr)); - if (pj_strcmp(&s, &rdata->msg_info.via->sent_by.host) != 0) { - pj_strdup(rdata->tp_info.pool, - &rdata->msg_info.via->recvd_param, &s); + if (pj_strcmp2(&rdata->msg_info.via->sent_by.host, + rdata->pkt_info.src_name) != 0) + { + pj_strdup2(rdata->tp_info.pool, + &rdata->msg_info.via->recvd_param, + rdata->pkt_info.src_name); } /* RFC 3581: * If message contains "rport" param, put the received port there. */ if (rdata->msg_info.via->rport_param == 0) { - rdata->msg_info.via->rport_param = - pj_ntohs(rdata->pkt_info.addr.sin_port); + rdata->msg_info.via->rport_param = rdata->pkt_info.src_port; } /* Drop response message if it has more than one Via. @@ -735,32 +748,47 @@ finish_process_fragment: */ PJ_DEF(pj_status_t) pjsip_tpmgr_alloc_transport( pjsip_tpmgr *mgr, pjsip_transport_type_e type, - const pj_sockaddr_in *remote, + const pj_sockaddr_t *remote, + int addr_len, pjsip_transport **p_transport) { - transport_key key; + struct transport_key + { + pjsip_transport_type_e type; + pj_sockaddr addr; + } key; + int key_len; pjsip_transport *transport; pjsip_tpfactory *factory; pj_status_t status; pj_lock_acquire(mgr->lock); + key_len = sizeof(key.type) + addr_len; + /* First try to get exact destination. */ - key.type = (pj_uint8_t)type; - key.zero = 0; - key.addr = pj_ntohl(remote->sin_addr.s_addr); - key.port = pj_ntohs(remote->sin_port); + key.type = type; + pj_memcpy(&key.addr, remote, addr_len); - transport = pj_hash_get(mgr->table, &key, sizeof(key)); - if (transport != NULL) { + transport = pj_hash_get(mgr->table, &key, key_len); + if (transport == NULL) { unsigned flag = pjsip_transport_get_flag_from_type(type); - - /* For datagram transports, try lookup with zero address. */ - if (flag & PJSIP_TRANSPORT_DATAGRAM) { - key.addr = 0; - key.port = 0; + const pj_sockaddr *remote_addr = (const pj_sockaddr*)remote; + + /* For datagram transports, try lookup with zero address. + */ + if ( (flag & PJSIP_TRANSPORT_DATAGRAM) && + (remote_addr->sa_family == PJ_AF_INET)) + { + pj_sockaddr_in *addr = (pj_sockaddr_in*)&key.addr; - transport = pj_hash_get(mgr->table, &key, sizeof(key)); + pj_memset(addr, 0, sizeof(pj_sockaddr_in)); + addr->sin_family = PJ_AF_INET; + addr->sin_addr.s_addr = 0; + addr->sin_port = 0; + + key_len = sizeof(key.type) + sizeof(pj_sockaddr_in); + transport = pj_hash_get(mgr->table, &key, key_len); } } @@ -815,22 +843,11 @@ PJ_DEF(void) pjsip_tpmgr_dump_transports(pjsip_tpmgr *mgr) PJ_LOG(3, (THIS_FILE, " Dumping transports:")); do { - char src_addr[128], dst_addr[128]; - int src_port, dst_port; - pjsip_transport *t; - - t = pj_hash_this(mgr->table, itr); - pj_native_strcpy(src_addr, pj_inet_ntoa(t->local_addr.sin_addr)); - src_port = pj_ntohs(t->local_addr.sin_port); - - pj_native_strcpy(dst_addr, pj_inet_ntoa(t->rem_addr.sin_addr)); - dst_port = pj_ntohs(t->rem_addr.sin_port); + pjsip_transport *t = pj_hash_this(mgr->table, itr); - PJ_LOG(3, (THIS_FILE, " %s %s %s:%d --> %s:%d (refcnt=%d)", - t->type_name, + PJ_LOG(3, (THIS_FILE, " %s %s (refcnt=%d)", t->obj_name, - src_addr, src_port, - dst_addr, dst_port, + t->info, pj_atomic_get(t->ref_cnt))); itr = pj_hash_next(mgr->table, itr); diff --git a/pjsip/src/pjsip/sip_transport_udp.c b/pjsip/src/pjsip/sip_transport_udp.c index 2dc835a3..bd6d7ffb 100644 --- a/pjsip/src/pjsip/sip_transport_udp.c +++ b/pjsip/src/pjsip/sip_transport_udp.c @@ -40,14 +40,14 @@ struct udp_transport /* - * on_read_complete() + * udp_on_read_complete() * * This is callback notification from ioqueue that a pending recvfrom() * operation has completed. */ -static void on_read_complete( pj_ioqueue_key_t *key, - pj_ioqueue_op_key_t *op_key, - pj_ssize_t bytes_read) +static void udp_on_read_complete( pj_ioqueue_key_t *key, + pj_ioqueue_op_key_t *op_key, + pj_ssize_t bytes_read) { enum { MAX_IMMEDIATE_PACKET = 10 }; pjsip_rx_data_op_key *rdata_op_key = (pjsip_rx_data_op_key*) op_key; @@ -72,10 +72,16 @@ static void on_read_complete( pj_ioqueue_key_t *key, /* Report the packet to transport manager. */ if (bytes_read > 0) { pj_size_t size_eaten; + const pj_sockaddr_in *src_addr = + (pj_sockaddr_in*)&rdata->pkt_info.src_addr; + /* Init pkt_info part. */ rdata->pkt_info.len = bytes_read; rdata->pkt_info.zero = 0; pj_gettimeofday(&rdata->pkt_info.timestamp); + pj_native_strcpy(rdata->pkt_info.src_name, + pj_inet_ntoa(src_addr->sin_addr)); + rdata->pkt_info.src_port = pj_ntohs(src_addr->sin_port); size_eaten = pjsip_tpmgr_receive_packet(rdata->tp_info.transport->tpmgr, @@ -109,12 +115,12 @@ static void on_read_complete( pj_ioqueue_key_t *key, /* Read next packet. */ bytes_read = sizeof(rdata->pkt_info.packet); - rdata->pkt_info.addr_len = sizeof(rdata->pkt_info.addr); + rdata->pkt_info.src_addr_len = sizeof(rdata->pkt_info.src_addr); status = pj_ioqueue_recvfrom(key, op_key, rdata->pkt_info.packet, &bytes_read, flags, - &rdata->pkt_info.addr, - &rdata->pkt_info.addr_len); + &rdata->pkt_info.src_addr, + &rdata->pkt_info.src_addr_len); if (status == PJ_SUCCESS) { /* Continue loop. */ @@ -149,14 +155,14 @@ static void on_read_complete( pj_ioqueue_key_t *key, } /* - * on_write_complete() + * udp_on_write_complete() * * This is callback notification from ioqueue that a pending sendto() * operation has completed. */ -static void on_write_complete( pj_ioqueue_key_t *key, - pj_ioqueue_op_key_t *op_key, - pj_ssize_t bytes_sent) +static void udp_on_write_complete( pj_ioqueue_key_t *key, + pj_ioqueue_op_key_t *op_key, + pj_ssize_t bytes_sent) { struct udp_transport *tp = pj_ioqueue_get_user_data(key); pjsip_tx_data_op_key *tdata_op_key = (pjsip_tx_data_op_key*)op_key; @@ -169,18 +175,19 @@ static void on_write_complete( pj_ioqueue_key_t *key, } /* - * transport_send_msg() + * udp_send_msg() * * This function is called by transport manager (by transport->send_msg()) * to send outgoing message. */ -static pj_status_t transport_send_msg( pjsip_transport *transport, - pjsip_tx_data *tdata, - const pj_sockaddr_in *rem_addr, - void *token, - void (*callback)(pjsip_transport*, - void *token, - pj_ssize_t)) +static pj_status_t udp_send_msg( pjsip_transport *transport, + pjsip_tx_data *tdata, + const pj_sockaddr_t *rem_addr, + int addr_len, + void *token, + void (*callback)(pjsip_transport*, + void *token, + pj_ssize_t)) { struct udp_transport *tp = (struct udp_transport*)transport; pj_ssize_t size; @@ -197,15 +204,15 @@ static pj_status_t transport_send_msg( pjsip_transport *transport, size = tdata->buf.cur - tdata->buf.start; return pj_ioqueue_sendto(tp->key, (pj_ioqueue_op_key_t*)&tdata->op_key, tdata->buf.start, &size, 0, - rem_addr, (rem_addr ? sizeof(pj_sockaddr_in):0)); + rem_addr, addr_len); } /* - * transport_destroy() + * udp_destroy() * * This function is called by transport manager (by transport->destroy()). */ -static pj_status_t transport_destroy( pjsip_transport *transport ) +static pj_status_t udp_destroy( pjsip_transport *transport ) { struct udp_transport *tp = (struct udp_transport*)transport; int i; @@ -249,7 +256,7 @@ static pj_status_t transport_destroy( pjsip_transport *transport ) */ PJ_DEF(pj_status_t) pjsip_udp_transport_attach( pjsip_endpoint *endpt, pj_sock_t sock, - const pj_sockaddr_in *pub_addr, + const pjsip_host_port *a_name, unsigned async_cnt, pjsip_transport **p_transport) { @@ -258,33 +265,22 @@ PJ_DEF(pj_status_t) pjsip_udp_transport_attach( pjsip_endpoint *endpt, pj_ioqueue_t *ioqueue; pj_ioqueue_callback ioqueue_cb; unsigned i; - int addrlen; pj_status_t status; /* Create pool. */ pool = pjsip_endpt_create_pool(endpt, "udp%p", PJSIP_POOL_LEN_TRANSPORT, - PJSIP_POOL_INC_TRANSPORT); + PJSIP_POOL_INC_TRANSPORT); if (!pool) return PJ_ENOMEM; + /* Create the UDP transport object. */ tp = pj_pool_zalloc(pool, sizeof(struct udp_transport)); - tp->base.pool = pool; - tp->base.endpt = endpt; - /* Init type, type_name, and flag */ - tp->base.type = PJSIP_TRANSPORT_UDP; - pj_native_strcpy(tp->base.type_name, "UDP"); - tp->base.flag = pjsip_transport_get_flag_from_type(PJSIP_TRANSPORT_UDP); + /* Save pool. */ + tp->base.pool = pool; - /* Init addresses. */ - addrlen = sizeof(tp->base.local_addr); - status = pj_sock_getsockname(sock, &tp->base.local_addr, &addrlen); - if (status != PJ_SUCCESS) { - pjsip_endpt_destroy_pool(endpt, pool); - return status; - } - pj_memcpy(&tp->base.public_addr, pub_addr, sizeof(pj_sockaddr_in)); - tp->base.rem_addr.sin_family = PJ_AF_INET; + /* Object name. */ + pj_sprintf(tp->base.obj_name, "udp%p", tp); /* Init reference counter. */ status = pj_atomic_create(pool, 0, &tp->base.ref_cnt); @@ -296,22 +292,65 @@ PJ_DEF(pj_status_t) pjsip_udp_transport_attach( pjsip_endpoint *endpt, if (status != PJ_SUCCESS) goto on_error; + /* Set type. */ + tp->base.key.type = PJSIP_TRANSPORT_UDP; + + /* Remote address is left zero (except the family) */ + tp->base.key.rem_addr.sa_family = PJ_AF_INET; + + /* Type name. */ + tp->base.type_name = "UDP"; + + /* Transport flag */ + tp->base.flag = pjsip_transport_get_flag_from_type(PJSIP_TRANSPORT_UDP); + + + /* Length of addressess. */ + tp->base.addr_len = sizeof(pj_sockaddr_in); + + /* Init local address. */ + status = pj_sock_getsockname(sock, &tp->base.local_addr, + &tp->base.addr_len); + if (status != PJ_SUCCESS) + goto on_error; + + /* Init address name (published address) */ + pj_strdup_with_null(pool, &tp->base.local_name.host, &a_name->host); + tp->base.local_name.port = a_name->port; + + /* Init remote name. */ + tp->base.remote_name.host = pj_str("0.0.0.0"); + tp->base.remote_name.port = 0; + + /* Transport info. */ + tp->base.info = pj_pool_alloc(pool, 80); + pj_sprintf(tp->base.info, "udp %s:%d [published as %s:%d]", + pj_inet_ntoa(((pj_sockaddr_in*)&tp->base.local_addr)->sin_addr), + pj_ntohs(((pj_sockaddr_in*)&tp->base.local_addr)->sin_port), + tp->base.local_name.host, + tp->base.local_name.port); + + /* Set endpoint. */ + tp->base.endpt = endpt; + + /* Transport manager and timer will be initialized by tpmgr */ + /* Attach socket. */ tp->sock = sock; /* Register to ioqueue. */ ioqueue = pjsip_endpt_get_ioqueue(endpt); pj_memset(&ioqueue_cb, 0, sizeof(ioqueue_cb)); - ioqueue_cb.on_read_complete = &on_read_complete; - ioqueue_cb.on_write_complete = &on_write_complete; + ioqueue_cb.on_read_complete = &udp_on_read_complete; + ioqueue_cb.on_write_complete = &udp_on_write_complete; status = pj_ioqueue_register_sock(pool, ioqueue, tp->sock, tp, &ioqueue_cb, &tp->key); if (status != PJ_SUCCESS) goto on_error; /* Set functions. */ - tp->base.send_msg = &transport_send_msg; - tp->base.destroy = &transport_destroy; + tp->base.send_msg = &udp_send_msg; + tp->base.destroy = &udp_destroy; /* This is a permanent transport, so we initialize the ref count * to one so that transport manager don't destroy this transport @@ -330,8 +369,8 @@ PJ_DEF(pj_status_t) pjsip_udp_transport_attach( pjsip_endpoint *endpt, tp->rdata_cnt = 0; for (i=0; i<async_cnt; ++i) { pj_pool_t *rdata_pool = pjsip_endpt_create_pool(endpt, "rtd%p", - PJSIP_POOL_LEN_RDATA, - PJSIP_POOL_INC_RDATA); + PJSIP_POOL_RDATA_LEN, + PJSIP_POOL_RDATA_INC); if (!rdata_pool) { pj_atomic_set(tp->base.ref_cnt, 0); pjsip_transport_unregister(tp->base.tpmgr, &tp->base); @@ -339,6 +378,8 @@ PJ_DEF(pj_status_t) pjsip_udp_transport_attach( pjsip_endpoint *endpt, } tp->rdata[i] = pj_pool_zalloc(rdata_pool, sizeof(pjsip_rx_data)); + + /* Init tp_info part. */ tp->rdata[i]->tp_info.pool = rdata_pool; tp->rdata[i]->tp_info.transport = &tp->base; pj_ioqueue_op_key_init(&tp->rdata[i]->tp_info.op_key.op_key, @@ -352,17 +393,17 @@ PJ_DEF(pj_status_t) pjsip_udp_transport_attach( pjsip_endpoint *endpt, pj_ssize_t size; size = sizeof(tp->rdata[i]->pkt_info.packet); - tp->rdata[i]->pkt_info.addr_len = sizeof(tp->rdata[i]->pkt_info.addr); + tp->rdata[i]->pkt_info.src_addr_len = sizeof(tp->rdata[i]->pkt_info.src_addr); status = pj_ioqueue_recvfrom(tp->key, &tp->rdata[i]->tp_info.op_key.op_key, tp->rdata[i]->pkt_info.packet, &size, PJ_IOQUEUE_ALWAYS_ASYNC, - &tp->rdata[i]->pkt_info.addr, - &tp->rdata[i]->pkt_info.addr_len); + &tp->rdata[i]->pkt_info.src_addr, + &tp->rdata[i]->pkt_info.src_addr_len); if (status == PJ_SUCCESS) { pj_assert(!"Shouldn't happen because PJ_IOQUEUE_ALWAYS_ASYNC!"); - on_read_complete(tp->key, &tp->rdata[i]->tp_info.op_key.op_key, - size); + udp_on_read_complete(tp->key, &tp->rdata[i]->tp_info.op_key.op_key, + size); } else if (status != PJ_EPENDING) { /* Error! */ pjsip_transport_unregister(tp->base.tpmgr, &tp->base); @@ -375,23 +416,25 @@ PJ_DEF(pj_status_t) pjsip_udp_transport_attach( pjsip_endpoint *endpt, return PJ_SUCCESS; on_error: - transport_destroy((pjsip_transport*)tp); + udp_destroy((pjsip_transport*)tp); return status; } /* * pjsip_udp_transport_start() * - * Start an UDP transport/listener. + * Create a UDP socket in the specified address and start a transport. */ PJ_DEF(pj_status_t) pjsip_udp_transport_start( pjsip_endpoint *endpt, const pj_sockaddr_in *local, - const pj_sockaddr_in *pub_addr, + const pjsip_host_port *a_name, unsigned async_cnt, pjsip_transport **p_transport) { pj_sock_t sock; pj_status_t status; + char addr_buf[16]; + pjsip_host_port bound_name; status = pj_sock_socket(PJ_AF_INET, PJ_SOCK_DGRAM, 0, &sock); if (status != PJ_SUCCESS) @@ -403,7 +446,14 @@ PJ_DEF(pj_status_t) pjsip_udp_transport_start( pjsip_endpoint *endpt, return status; } - return pjsip_udp_transport_attach( endpt, sock, pub_addr, async_cnt, + if (a_name == NULL) { + a_name = &bound_name; + bound_name.host.ptr = addr_buf; + pj_strcpy2(&bound_name.host, pj_inet_ntoa(local->sin_addr)); + bound_name.port = pj_ntohs(local->sin_port); + } + + return pjsip_udp_transport_attach( endpt, sock, a_name, async_cnt, p_transport ); } diff --git a/pjsip/src/pjsip/sip_util.c b/pjsip/src/pjsip/sip_util.c index 57ef6fbb..c227eff7 100644 --- a/pjsip/src/pjsip/sip_util.c +++ b/pjsip/src/pjsip/sip_util.c @@ -676,7 +676,7 @@ PJ_DEF(pj_status_t) pjsip_endpt_create_cancel( pjsip_endpoint *endpt, PJ_DEF(pj_status_t) pjsip_get_response_addr(pj_pool_t *pool, const pjsip_transport *req_transport, const pjsip_via_hdr *via, - pjsip_host_port *send_addr) + pjsip_host_info *send_addr) { /* Determine the destination address (section 18.2.2): * - for TCP, SCTP, or TLS, send the response using the transport where @@ -688,27 +688,25 @@ PJ_DEF(pj_status_t) pjsip_get_response_addr(pj_pool_t *pool, * - otherwise send to the address in sent-by. */ send_addr->flag = req_transport->flag; - send_addr->type = req_transport->type; + send_addr->type = req_transport->key.type; if (PJSIP_TRANSPORT_IS_RELIABLE(req_transport)) { - const pj_sockaddr_in *remote_addr; - remote_addr = &req_transport->rem_addr; - pj_strdup2(pool, &send_addr->host, - pj_inet_ntoa(remote_addr->sin_addr)); - send_addr->port = pj_sockaddr_in_get_port(remote_addr); + pj_strdup( pool, &send_addr->addr.host, + &req_transport->remote_name.host); + send_addr->addr.port = req_transport->remote_name.port; } else { /* Set the host part */ if (via->maddr_param.slen) { - pj_strdup(pool, &send_addr->host, &via->maddr_param); + pj_strdup(pool, &send_addr->addr.host, &via->maddr_param); } else if (via->recvd_param.slen) { - pj_strdup(pool, &send_addr->host, &via->recvd_param); + pj_strdup(pool, &send_addr->addr.host, &via->recvd_param); } else { - pj_strdup(pool, &send_addr->host, &via->sent_by.host); + pj_strdup(pool, &send_addr->addr.host, &via->sent_by.host); } /* Set the port */ - send_addr->port = via->sent_by.port; + send_addr->addr.port = via->sent_by.port; } return PJ_SUCCESS; diff --git a/pjsip/src/test-pjsip/msg.c b/pjsip/src/test-pjsip/msg_test.c index 1f6affdd..1f6affdd 100644 --- a/pjsip/src/test-pjsip/msg.c +++ b/pjsip/src/test-pjsip/msg_test.c diff --git a/pjsip/src/test-pjsip/uri.c b/pjsip/src/test-pjsip/uri_test.c index 29a16dd5..29a16dd5 100644 --- a/pjsip/src/test-pjsip/uri.c +++ b/pjsip/src/test-pjsip/uri_test.c |