Changeset 1602 for pjproject/trunk
- Timestamp:
- Dec 1, 2007 8:59:25 AM (17 years ago)
- Location:
- pjproject/trunk/pjsip
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/include/pjsip/sip_transport.h
r1388 r1602 134 134 135 135 /** 136 * Get the socket address family of a given transport type. 137 * 138 * @param type Transport type. 139 * 140 * @return Transport type. 141 */ 142 PJ_DECL(int) pjsip_transport_type_get_af(pjsip_transport_type_e type); 143 144 /** 136 145 * Get transport flag from type. 137 146 * … … 162 171 */ 163 172 PJ_DECL(const char*) pjsip_transport_get_type_name(pjsip_transport_type_e t); 173 174 /** 175 * Get longer description for the specified transport type. 176 * 177 * @param t Transport type. 178 * 179 * @return Transport description. 180 */ 181 PJ_DECL(const char*) pjsip_transport_get_type_desc(pjsip_transport_type_e t); 164 182 165 183 … … 308 326 309 327 /** The IP source address string (NULL terminated). */ 310 char src_name[ 16];328 char src_name[PJ_INET6_ADDRSTRLEN]; 311 329 312 330 /** The IP source port number. */ … … 507 525 pj_sockaddr dst_addr; /**< Destination address. */ 508 526 int dst_addr_len; /**< Length of address. */ 509 char dst_name[ 16];/**< Destination address. */527 char dst_name[PJ_INET6_ADDRSTRLEN]; /**< Destination address. */ 510 528 int dst_port; /**< Destination port. */ 511 529 } tp_info; -
pjproject/trunk/pjsip/include/pjsip/sip_transport_udp.h
r1382 r1602 83 83 84 84 /** 85 * Attach UDP socket as a new transport and start the transport. 85 * Start IPv6 UDP transport. 86 */ 87 PJ_DECL(pj_status_t) pjsip_udp_transport_start6(pjsip_endpoint *endpt, 88 const pj_sockaddr_in6 *local, 89 const pjsip_host_port *a_name, 90 unsigned async_cnt, 91 pjsip_transport **p_transport); 92 93 94 /** 95 * Attach IPv4 UDP socket as a new transport and start the transport. 86 96 * 87 97 * @param endpt The SIP endpoint. … … 102 112 pjsip_transport **p_transport); 103 113 114 115 /** 116 * Attach IPv4 or IPv6 UDP socket as a new transport and start the transport. 117 * 118 * @param endpt The SIP endpoint. 119 * @param type Transport type, which is PJSIP_TRANSPORT_UDP for IPv4 120 * or PJSIP_TRANSPORT_UDP6 for IPv6 socket. 121 * @param sock UDP socket to use. 122 * @param a_name Published address (only the host and port portion is 123 * used). 124 * @param async_cnt Number of simultaneous async operations. 125 * @param p_transport Pointer to receive the transport. 126 * 127 * @return PJ_SUCCESS when the transport has been successfully 128 * started and registered to transport manager, or 129 * the appropriate error code. 130 */ 131 PJ_DECL(pj_status_t) pjsip_udp_transport_attach2(pjsip_endpoint *endpt, 132 pjsip_transport_type_e type, 133 pj_sock_t sock, 134 const pjsip_host_port *a_name, 135 unsigned async_cnt, 136 pjsip_transport **p_transport); 104 137 105 138 /** -
pjproject/trunk/pjsip/include/pjsip/sip_types.h
r974 r1602 83 83 84 84 /** Start of user defined transport */ 85 PJSIP_TRANSPORT_START_OTHER 85 PJSIP_TRANSPORT_START_OTHER, 86 87 /** Start of IPv6 transports */ 88 PJSIP_TRANSPORT_IPV6 = 128, 89 90 /** UDP over IPv6 */ 91 PJSIP_TRANSPORT_UDP6 = PJSIP_TRANSPORT_UDP + PJSIP_TRANSPORT_IPV6, 92 93 /** TCP over IPv6 */ 94 PJSIP_TRANSPORT_TCP6 = PJSIP_TRANSPORT_TCP + PJSIP_TRANSPORT_IPV6 86 95 87 96 } pjsip_transport_type_e; -
pjproject/trunk/pjsip/src/pjsip/sip_resolve.c
r1484 r1602 22 22 #include <pjlib-util/errno.h> 23 23 #include <pjlib-util/srv_resolver.h> 24 #include <pj/addr_resolv.h> 24 25 #include <pj/array.h> 25 26 #include <pj/assert.h> … … 138 139 /* 139 140 * Internal: 140 * determine if an address is a valid IP address. 141 */ 142 static int is_str_ip(const pj_str_t *host) 143 { 144 const char *p = host->ptr; 145 const char *end = ((const char*)host->ptr) + host->slen; 146 147 while (p != end) { 148 if (pj_isdigit(*p) || *p=='.') { 149 ++p; 150 } else { 151 return 0; 152 } 153 } 154 return 1; 141 * determine if an address is a valid IP address, and if it is, 142 * return the IP version (4 or 6). 143 */ 144 static int get_ip_addr_ver(const pj_str_t *host) 145 { 146 pj_in_addr dummy; 147 pj_in6_addr dummy6; 148 149 /* First check with inet_aton() */ 150 if (pj_inet_aton(host, &dummy) > 0) 151 return 4; 152 153 /* Then check if this is an IPv6 address */ 154 if (pj_inet_pton(pj_AF_INET6(), host, &dummy6) == PJ_SUCCESS) 155 return 6; 156 157 /* Not an IP address */ 158 return 0; 155 159 } 156 160 … … 167 171 pjsip_server_addresses svr_addr; 168 172 pj_status_t status = PJ_SUCCESS; 169 int i s_ip_addr;173 int ip_addr_ver; 170 174 struct query *query; 171 175 pjsip_transport_type_e type = target->type; 172 176 173 /* Is it IP address or hostname? .*/174 i s_ip_addr = is_str_ip(&target->addr.host);177 /* Is it IP address or hostname? And if it's an IP, which version? */ 178 ip_addr_ver = get_ip_addr_ver(&target->addr.host); 175 179 176 180 /* Set the transport type if not explicitly specified. … … 178 182 */ 179 183 if (type == PJSIP_TRANSPORT_UNSPECIFIED) { 180 if (i s_ip_addr || (target->addr.port != 0)) {184 if (ip_addr_ver || (target->addr.port != 0)) { 181 185 #if PJ_HAS_TCP 182 186 if (target->flag & PJSIP_TRANSPORT_SECURE) … … 210 214 } 211 215 } 216 217 /* Add IPv6 flag for IPv6 address */ 218 if (ip_addr_ver == 6) 219 type = (pjsip_transport_type_e)((int)type + PJSIP_TRANSPORT_IPV6); 212 220 } 213 221 … … 216 224 * we can just finish the resolution now using pj_gethostbyname() 217 225 */ 218 if (i s_ip_addr || resolver->res == NULL) {226 if (ip_addr_ver || resolver->res == NULL) { 219 227 220 228 pj_in_addr ip_addr; 229 int af; 230 pj_addrinfo ai; 231 unsigned count; 221 232 pj_uint16_t srv_port; 222 233 223 if (!i s_ip_addr) {234 if (!ip_addr_ver) { 224 235 PJ_LOG(5,(THIS_FILE, 225 236 "DNS resolver not available, target '%.*s:%d' type=%s " … … 239 250 } 240 251 241 /* This will eventually call pj_gethostbyname() if the host 242 * is not an IP address. 243 */ 244 status = pj_sockaddr_in_init((pj_sockaddr_in*)&svr_addr.entry[0].addr, 245 &target->addr.host, srv_port); 252 if (type & PJSIP_TRANSPORT_IPV6) { 253 af = pj_AF_INET6(); 254 } else { 255 af = pj_AF_INET(); 256 } 257 258 /* Resolve */ 259 count = 1; 260 status = pj_getaddrinfo(af, &target->addr.host, &count, &ai); 246 261 if (status != PJ_SUCCESS) 247 262 goto on_error; 263 264 svr_addr.entry[0].addr.addr.sa_family = (pj_uint16_t)af; 265 pj_memcpy(&svr_addr.entry[0].addr, &ai.ai_addr, sizeof(pj_sockaddr)); 266 267 if (af == pj_AF_INET6()) { 268 svr_addr.entry[0].addr.ipv6.sin6_port = pj_htons(srv_port); 269 } else { 270 svr_addr.entry[0].addr.ipv4.sin_port = pj_htons(srv_port); 271 } 248 272 249 273 /* Call the callback. */ -
pjproject/trunk/pjsip/src/pjsip/sip_transport.c
r1536 r1602 94 94 struct transport_names_t 95 95 { 96 pjsip_transport_type_e type; 97 pj_uint16_t port; 98 pj_str_t name; 99 unsigned flag; 100 char name_buf[16]; 96 pjsip_transport_type_e type; /* Transport type */ 97 pj_uint16_t port; /* Default port number */ 98 pj_str_t name; /* Id tag */ 99 const char *description; /* Longer description */ 100 unsigned flag; /* Flags */ 101 char name_buf[16]; /* For user's transport */ 101 102 } transport_names[16] = 102 103 { 103 { PJSIP_TRANSPORT_UNSPECIFIED, 0, {"Unspecified", 11}, 0}, 104 { PJSIP_TRANSPORT_UDP, 5060, {"UDP", 3}, PJSIP_TRANSPORT_DATAGRAM}, 105 { PJSIP_TRANSPORT_TCP, 5060, {"TCP", 3}, PJSIP_TRANSPORT_RELIABLE}, 106 { PJSIP_TRANSPORT_TLS, 5061, {"TLS", 3}, PJSIP_TRANSPORT_RELIABLE | PJSIP_TRANSPORT_SECURE}, 107 { PJSIP_TRANSPORT_SCTP, 5060, {"SCTP", 4}, PJSIP_TRANSPORT_RELIABLE}, 108 { PJSIP_TRANSPORT_LOOP, 15060, {"LOOP", 4}, PJSIP_TRANSPORT_RELIABLE}, 109 { PJSIP_TRANSPORT_LOOP_DGRAM, 15060, {"LOOP-DGRAM", 10}, PJSIP_TRANSPORT_DATAGRAM}, 104 { 105 PJSIP_TRANSPORT_UNSPECIFIED, 106 0, 107 {"Unspecified", 11}, 108 "Unspecified", 109 0 110 }, 111 { 112 PJSIP_TRANSPORT_UDP, 113 5060, 114 {"UDP", 3}, 115 "UDP transport", 116 PJSIP_TRANSPORT_DATAGRAM 117 }, 118 { 119 PJSIP_TRANSPORT_TCP, 120 5060, 121 {"TCP", 3}, 122 "TCP transport", 123 PJSIP_TRANSPORT_RELIABLE 124 }, 125 { 126 PJSIP_TRANSPORT_TLS, 127 5061, 128 {"TLS", 3}, 129 "TLS transport", 130 PJSIP_TRANSPORT_RELIABLE | PJSIP_TRANSPORT_SECURE 131 }, 132 { 133 PJSIP_TRANSPORT_SCTP, 134 5060, 135 {"SCTP", 4}, 136 "SCTP transport", 137 PJSIP_TRANSPORT_RELIABLE 138 }, 139 { 140 PJSIP_TRANSPORT_LOOP, 141 15060, 142 {"LOOP", 4}, 143 "Loopback transport", 144 PJSIP_TRANSPORT_RELIABLE 145 }, 146 { 147 PJSIP_TRANSPORT_LOOP_DGRAM, 148 15060, 149 {"LOOP-DGRAM", 10}, 150 "Loopback datagram transport", 151 PJSIP_TRANSPORT_DATAGRAM 152 }, 153 { 154 PJSIP_TRANSPORT_UDP6, 155 5060, 156 {"UDP", 3}, 157 "UDP IPv6 transport", 158 PJSIP_TRANSPORT_DATAGRAM 159 }, 160 { 161 PJSIP_TRANSPORT_TCP6, 162 5060, 163 {"TCP", 3}, 164 "TCP IPv6 transport", 165 PJSIP_TRANSPORT_RELIABLE 166 }, 110 167 }; 168 169 struct transport_names_t *get_tpname(pjsip_transport_type_e type) 170 { 171 unsigned i; 172 for (i=0; i<PJ_ARRAY_SIZE(transport_names); ++i) { 173 if (transport_names[i].type == type) 174 return &transport_names[i]; 175 } 176 pj_assert(!"Invalid transport type!"); 177 return NULL; 178 } 179 180 181 /* 182 * Tools to get address string. 183 */ 184 static const char *addr_string(const pj_sockaddr_t *addr) 185 { 186 static char str[PJ_INET6_ADDRSTRLEN]; 187 pj_inet_ntop(((const pj_sockaddr*)addr)->addr.sa_family, 188 pj_sockaddr_get_addr(addr), 189 str, sizeof(str)); 190 return str; 191 } 111 192 112 193 … … 154 235 unsigned i; 155 236 156 /* Sanity check.157 * Check that transport_names[] are indexed on transport type.158 */159 PJ_ASSERT_RETURN(transport_names[PJSIP_TRANSPORT_UDP].type ==160 PJSIP_TRANSPORT_UDP, PJSIP_TRANSPORT_UNSPECIFIED);161 162 237 if (name->slen == 0) 163 238 return PJSIP_TRANSPORT_UNSPECIFIED; … … 182 257 unsigned i; 183 258 184 /* Sanity check.185 * Check that transport_names[] are indexed on transport type.186 */187 PJ_ASSERT_RETURN(transport_names[PJSIP_TRANSPORT_UDP].type ==188 PJSIP_TRANSPORT_UDP, PJSIP_TRANSPORT_UNSPECIFIED);189 190 259 /* Get the transport type for the specified flags. */ 191 260 for (i=0; i<PJ_ARRAY_SIZE(transport_names); ++i) { … … 199 268 } 200 269 270 /* 271 * Get the socket address family of a given transport type. 272 */ 273 PJ_DEF(int) pjsip_transport_type_get_af(pjsip_transport_type_e type) 274 { 275 if (type | PJSIP_TRANSPORT_IPV6) 276 return pj_AF_INET6(); 277 else 278 return pj_AF_INET(); 279 } 280 201 281 PJ_DEF(unsigned) pjsip_transport_get_flag_from_type(pjsip_transport_type_e type) 202 282 { 203 /* Sanity check.204 * Check that transport_names[] are indexed on transport type.205 */206 PJ_ASSERT_RETURN(transport_names[PJSIP_TRANSPORT_UDP].type ==207 PJSIP_TRANSPORT_UDP, 0);208 209 /* Check that argument is valid. */210 PJ_ASSERT_RETURN((unsigned)type < PJ_ARRAY_SIZE(transport_names), 0);211 212 283 /* Return transport flag. */ 213 return transport_names[type].flag;284 return get_tpname(type)->flag; 214 285 } 215 286 … … 219 290 PJ_DEF(int) pjsip_transport_get_default_port_for_type(pjsip_transport_type_e type) 220 291 { 221 /* Sanity check.222 * Check that transport_names[] are indexed on transport type.223 */224 PJ_ASSERT_RETURN(transport_names[PJSIP_TRANSPORT_UDP].type ==225 PJSIP_TRANSPORT_UDP, 0);226 227 /* Check that argument is valid. */228 PJ_ASSERT_RETURN((unsigned)type < PJ_ARRAY_SIZE(transport_names), 5060);229 230 292 /* Return the port. */ 231 return transport_names[type].port;293 return get_tpname(type)->port; 232 294 } 233 295 … … 237 299 PJ_DEF(const char*) pjsip_transport_get_type_name(pjsip_transport_type_e type) 238 300 { 239 /* Sanity check.240 * Check that transport_names[] are indexed on transport type.241 */ 242 PJ_ASSERT_RETURN(transport_names[PJSIP_TRANSPORT_UDP].type == 243 PJSIP_TRANSPORT_UDP, "Unknown"); 244 245 /* Check that argument is valid.*/246 PJ_ASSERT_RETURN((unsigned)type<PJ_ARRAY_SIZE(transport_names), "Unknown"); 247 248 /* Return the port. */249 return transport_names[type].name.ptr;301 /* Return the name. */ 302 return get_tpname(type)->name.ptr; 303 } 304 305 /* 306 * Get transport description. 307 */ 308 PJ_DEF(const char*) pjsip_transport_get_type_desc(pjsip_transport_type_e type) 309 { 310 /* Return the description. */ 311 return get_tpname(type)->description; 250 312 } 251 313 … … 557 619 pj_memcpy(&tdata->tp_info.dst_addr, addr, addr_len); 558 620 tdata->tp_info.dst_addr_len = addr_len; 559 if (((pj_sockaddr*)addr)->addr.sa_family == pj_AF_INET()) { 560 const char *str_addr; 561 str_addr = pj_inet_ntoa(((pj_sockaddr_in*)addr)->sin_addr); 562 pj_ansi_strcpy(tdata->tp_info.dst_name, str_addr); 563 tdata->tp_info.dst_port = pj_ntohs(((pj_sockaddr_in*)addr)->sin_port); 564 } else { 565 pj_ansi_strcpy(tdata->tp_info.dst_name, "<unknown>"); 566 tdata->tp_info.dst_port = 0; 567 } 621 622 pj_inet_ntop(((pj_sockaddr*)addr)->addr.sa_family, 623 pj_sockaddr_get_addr(addr), 624 tdata->tp_info.dst_name, 625 sizeof(tdata->tp_info.dst_name)); 626 tdata->tp_info.dst_port = pj_sockaddr_get_port(addr); 568 627 569 628 /* Distribute to modules. … … 804 863 tp->obj_name, 805 864 pjsip_transport_get_type_name(tp->key.type), 806 pj_inet_ntoa(((pj_sockaddr_in*)&tp->key.rem_addr)->sin_addr),807 pj_ ntohs(((pj_sockaddr_in*)&tp->key.rem_addr)->sin_port)));865 addr_string(&tp->key.rem_addr), 866 pj_sockaddr_get_port(&tp->key.rem_addr))); 808 867 809 868 return PJ_SUCCESS; … … 1055 1114 } else if ((flag & PJSIP_TRANSPORT_DATAGRAM) != 0) { 1056 1115 1057 pj_sockaddr_in remote; 1116 pj_sockaddr remote; 1117 int addr_len; 1058 1118 pjsip_transport *tp; 1059 1119 1060 pj_sockaddr_in_init(&remote, NULL, 0); 1120 pj_bzero(&remote, sizeof(remote)); 1121 if (type & PJSIP_TRANSPORT_IPV6) { 1122 addr_len = sizeof(pj_sockaddr_in6); 1123 remote.addr.sa_family = pj_AF_INET6(); 1124 } else { 1125 addr_len = sizeof(pj_sockaddr_in); 1126 remote.addr.sa_family = pj_AF_INET(); 1127 } 1128 1061 1129 status = pjsip_tpmgr_acquire_transport(tpmgr, type, &remote, 1062 sizeof(remote), NULL, &tp);1130 addr_len, NULL, &tp); 1063 1131 1064 1132 if (status == PJ_SUCCESS) { … … 1382 1450 TRACE_((THIS_FILE,"Acquiring transport type=%s, remote=%s:%d", 1383 1451 pjsip_transport_get_type_name(type), 1384 pj_inet_ntoa(((pj_sockaddr_in*)remote)->sin_addr),1385 pj_ ntohs(((pj_sockaddr_in*)remote)->sin_port)));1452 addr_string(remote), 1453 pj_sockaddr_get_port(remote))); 1386 1454 1387 1455 pj_lock_acquire(mgr->lock); … … 1463 1531 type == PJSIP_TRANSPORT_LOOP_DGRAM) 1464 1532 { 1465 pj_sockaddr _in *addr = (pj_sockaddr_in*)&key.rem_addr;1466 1467 pj_bzero(addr, sizeof(pj_sockaddr_in));1468 key_len = sizeof(key.type) + sizeof(pj_sockaddr_in);1533 pj_sockaddr *addr = &key.rem_addr; 1534 1535 pj_bzero(addr, addr_len); 1536 key_len = sizeof(key.type) + addr_len; 1469 1537 transport = (pjsip_transport*) 1470 1538 pj_hash_get(mgr->table, &key, key_len, NULL); 1471 1539 } 1472 /* For datagram INETtransports, try lookup with zero address.1540 /* For datagram transports, try lookup with zero address. 1473 1541 */ 1474 else if ((flag & PJSIP_TRANSPORT_DATAGRAM) && 1475 (remote_addr->addr.sa_family == pj_AF_INET())) 1542 else if (flag & PJSIP_TRANSPORT_DATAGRAM) 1476 1543 { 1477 pj_sockaddr _in *addr = (pj_sockaddr_in*)&key.rem_addr;1478 1479 pj_bzero(addr, sizeof(pj_sockaddr_in));1480 addr-> sin_family = pj_AF_INET();1481 1482 key_len = sizeof(key.type) + sizeof(pj_sockaddr_in);1544 pj_sockaddr *addr = &key.rem_addr; 1545 1546 pj_bzero(addr, addr_len); 1547 addr->addr.sa_family = remote_addr->addr.sa_family; 1548 1549 key_len = sizeof(key.type) + addr_len; 1483 1550 transport = (pjsip_transport*) 1484 1551 pj_hash_get(mgr->table, &key, key_len, NULL); -
pjproject/trunk/pjsip/src/pjsip/sip_transport_tcp.c
r1551 r1602 290 290 */ 291 291 if (listener_addr->sin_addr.s_addr == 0) { 292 pj_ in_addr hostip;293 294 status = pj_gethostip( &hostip);292 pj_sockaddr hostip; 293 294 status = pj_gethostip(pj_AF_INET(), &hostip); 295 295 if (status != PJ_SUCCESS) 296 296 goto on_error; 297 297 298 listener_addr->sin_addr = hostip;298 listener_addr->sin_addr.s_addr = hostip.ipv4.sin_addr.s_addr; 299 299 } 300 300 -
pjproject/trunk/pjsip/src/pjsip/sip_transport_udp.c
r1405 r1602 143 143 if (bytes_read > MIN_SIZE) { 144 144 pj_size_t size_eaten; 145 const pj_sockaddr_in *src_addr = 146 (pj_sockaddr_in*)&rdata->pkt_info.src_addr; 145 const pj_sockaddr *src_addr = &rdata->pkt_info.src_addr; 147 146 148 147 /* Init pkt_info part. */ … … 150 149 rdata->pkt_info.zero = 0; 151 150 pj_gettimeofday(&rdata->pkt_info.timestamp); 152 pj_ansi_strcpy(rdata->pkt_info.src_name, 153 pj_inet_ntoa(src_addr->sin_addr)); 154 rdata->pkt_info.src_port = pj_ntohs(src_addr->sin_port); 151 if (src_addr->addr.sa_family == pj_AF_INET()) { 152 pj_ansi_strcpy(rdata->pkt_info.src_name, 153 pj_inet_ntoa(src_addr->ipv4.sin_addr)); 154 rdata->pkt_info.src_port = pj_ntohs(src_addr->ipv4.sin_port); 155 } else { 156 pj_inet_ntop(pj_AF_INET6(), 157 pj_sockaddr_get_addr(&rdata->pkt_info.src_addr), 158 rdata->pkt_info.src_name, 159 sizeof(rdata->pkt_info.src_name)); 160 rdata->pkt_info.src_port = pj_ntohs(src_addr->ipv6.sin6_port); 161 } 155 162 156 163 size_eaten = … … 413 420 414 421 /* Create socket */ 415 static pj_status_t create_socket( const pj_sockaddr_in*local_a,416 pj_sock_t *p_sock)422 static pj_status_t create_socket(int af, const pj_sockaddr_t *local_a, 423 int addr_len, pj_sock_t *p_sock) 417 424 { 418 425 pj_sock_t sock; 419 426 pj_sockaddr_in tmp_addr; 427 pj_sockaddr_in6 tmp_addr6; 420 428 pj_status_t status; 421 429 422 status = pj_sock_socket( pj_AF_INET(), pj_SOCK_DGRAM(), 0, &sock);430 status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &sock); 423 431 if (status != PJ_SUCCESS) 424 432 return status; 425 433 426 434 if (local_a == NULL) { 427 pj_sockaddr_in_init(&tmp_addr, NULL, 0); 428 local_a = &tmp_addr; 429 } 430 431 status = pj_sock_bind(sock, local_a, sizeof(*local_a)); 435 if (af == pj_AF_INET6()) { 436 pj_bzero(&tmp_addr6, sizeof(tmp_addr6)); 437 tmp_addr6.sin6_family = (pj_uint16_t)af; 438 local_a = &tmp_addr6; 439 addr_len = sizeof(tmp_addr6); 440 } else { 441 pj_sockaddr_in_init(&tmp_addr, NULL, 0); 442 local_a = &tmp_addr; 443 addr_len = sizeof(tmp_addr); 444 } 445 } 446 447 status = pj_sock_bind(sock, local_a, addr_len); 432 448 if (status != PJ_SUCCESS) { 433 449 pj_sock_close(sock); … … 443 459 static pj_status_t get_published_name(pj_sock_t sock, 444 460 char hostbuf[], 461 int hostbufsz, 445 462 pjsip_host_port *bound_name) 446 463 { 447 pj_sockaddr _intmp_addr;464 pj_sockaddr tmp_addr; 448 465 int addr_len; 449 466 pj_status_t status; … … 455 472 456 473 bound_name->host.ptr = hostbuf; 457 bound_name->port = pj_ntohs(tmp_addr.sin_port); 458 459 /* If bound address specifies "0.0.0.0", get the IP address 460 * of local hostname. 461 */ 462 if (tmp_addr.sin_addr.s_addr == PJ_INADDR_ANY) { 463 pj_in_addr hostip; 464 465 status = pj_gethostip(&hostip); 466 if (status != PJ_SUCCESS) 467 return status; 468 469 pj_strcpy2(&bound_name->host, pj_inet_ntoa(hostip)); 474 if (tmp_addr.addr.sa_family == pj_AF_INET()) { 475 bound_name->port = pj_ntohs(tmp_addr.ipv4.sin_port); 476 477 /* If bound address specifies "0.0.0.0", get the IP address 478 * of local hostname. 479 */ 480 if (tmp_addr.ipv4.sin_addr.s_addr == PJ_INADDR_ANY) { 481 pj_sockaddr hostip; 482 483 status = pj_gethostip(pj_AF_INET(), &hostip); 484 if (status != PJ_SUCCESS) 485 return status; 486 487 pj_strcpy2(&bound_name->host, pj_inet_ntoa(hostip.ipv4.sin_addr)); 488 } else { 489 /* Otherwise use bound address. */ 490 pj_strcpy2(&bound_name->host, 491 pj_inet_ntoa(tmp_addr.ipv4.sin_addr)); 492 status = PJ_SUCCESS; 493 } 494 470 495 } else { 471 /* Otherwise use bound address. */ 472 pj_strcpy2(&bound_name->host, pj_inet_ntoa(tmp_addr.sin_addr)); 473 } 474 475 return PJ_SUCCESS; 496 bound_name->port = pj_ntohs(tmp_addr.ipv6.sin6_port); 497 status = pj_inet_ntop(tmp_addr.addr.sa_family, 498 pj_sockaddr_get_addr(&tmp_addr), 499 hostbuf, hostbufsz); 500 } 501 502 503 return status; 476 504 } 477 505 … … 481 509 { 482 510 enum { INFO_LEN = 80 }; 511 char local_addr[PJ_INET6_ADDRSTRLEN]; 483 512 484 513 pj_assert(a_name->host.slen != 0); … … 491 520 tp->base.info = (char*) pj_pool_alloc(tp->base.pool, INFO_LEN); 492 521 } 522 523 pj_inet_ntop(tp->base.local_addr.addr.sa_family, 524 pj_sockaddr_get_addr(&tp->base.local_addr), 525 local_addr, sizeof(local_addr)); 526 493 527 pj_ansi_snprintf( 494 528 tp->base.info, INFO_LEN, "udp %s:%d [published as %s:%d]", 495 pj_inet_ntoa(((pj_sockaddr_in*)&tp->base.local_addr)->sin_addr),496 pj_ ntohs(((pj_sockaddr_in*)&tp->base.local_addr)->sin_port),529 local_addr, 530 pj_sockaddr_get_port(&tp->base.local_addr), 497 531 tp->base.local_name.host.ptr, 498 532 tp->base.local_name.port); … … 596 630 * Attach UDP socket and start transport. 597 631 */ 598 PJ_DEF(pj_status_t) pjsip_udp_transport_attach( pjsip_endpoint *endpt, 599 pj_sock_t sock, 600 const pjsip_host_port *a_name, 601 unsigned async_cnt, 602 pjsip_transport **p_transport) 632 static pj_status_t transport_attach( pjsip_endpoint *endpt, 633 pjsip_transport_type_e type, 634 pj_sock_t sock, 635 const pjsip_host_port *a_name, 636 unsigned async_cnt, 637 pjsip_transport **p_transport) 603 638 { 604 639 pj_pool_t *pool; 605 640 struct udp_transport *tp; 641 const char *format; 606 642 unsigned i; 607 643 pj_status_t status; … … 610 646 PJ_EINVAL); 611 647 648 /* Object name. */ 649 if (type & PJSIP_TRANSPORT_IPV6) 650 format = "udpv6%p"; 651 else 652 format = "udp%p"; 653 612 654 /* Create pool. */ 613 pool = pjsip_endpt_create_pool(endpt, "udp%p", PJSIP_POOL_LEN_TRANSPORT,655 pool = pjsip_endpt_create_pool(endpt, format, PJSIP_POOL_LEN_TRANSPORT, 614 656 PJSIP_POOL_INC_TRANSPORT); 615 657 if (!pool) … … 622 664 tp->base.pool = pool; 623 665 624 /* Object name. */ 625 pj_ansi_snprintf(tp->base.obj_name, sizeof(tp->base.obj_name), 626 "udp%p", tp); 666 pj_memcpy(tp->base.obj_name, pool->obj_name, PJ_MAX_OBJ_NAME); 627 667 628 668 /* Init reference counter. */ … … 632 672 633 673 /* Init lock. */ 634 status = pj_lock_create_recursive_mutex(pool, "udp%p", &tp->base.lock); 674 status = pj_lock_create_recursive_mutex(pool, pool->obj_name, 675 &tp->base.lock); 635 676 if (status != PJ_SUCCESS) 636 677 goto on_error; 637 678 638 679 /* Set type. */ 639 tp->base.key.type = PJSIP_TRANSPORT_UDP;680 tp->base.key.type = type; 640 681 641 682 /* Remote address is left zero (except the family) */ 642 tp->base.key.rem_addr.addr.sa_family = pj_AF_INET(); 683 tp->base.key.rem_addr.addr.sa_family = (pj_uint16_t) 684 ((type & PJSIP_TRANSPORT_IPV6) ? pj_AF_INET6() : pj_AF_INET()); 643 685 644 686 /* Type name. */ … … 646 688 647 689 /* Transport flag */ 648 tp->base.flag = pjsip_transport_get_flag_from_type( PJSIP_TRANSPORT_UDP);690 tp->base.flag = pjsip_transport_get_flag_from_type(type); 649 691 650 692 651 693 /* Length of addressess. */ 652 tp->base.addr_len = sizeof( pj_sockaddr_in);694 tp->base.addr_len = sizeof(tp->base.local_addr); 653 695 654 696 /* Init local address. */ … … 659 701 660 702 /* Init remote name. */ 661 tp->base.remote_name.host = pj_str("0.0.0.0"); 703 if (type == PJSIP_TRANSPORT_UDP) 704 tp->base.remote_name.host = pj_str("0.0.0.0"); 705 else 706 tp->base.remote_name.host = pj_str("::0"); 662 707 tp->base.remote_name.port = 0; 663 708 … … 724 769 725 770 PJ_LOG(4,(tp->base.obj_name, 726 "SIP UDP transport started, published address is %.*s:%d", 771 "SIP %s started, published address is %.*s:%d", 772 pjsip_transport_get_type_desc((pjsip_transport_type_e)tp->base.key.type), 727 773 (int)tp->base.local_name.host.slen, 728 774 tp->base.local_name.host.ptr, … … 734 780 udp_destroy((pjsip_transport*)tp); 735 781 return status; 782 } 783 784 785 PJ_DEF(pj_status_t) pjsip_udp_transport_attach( pjsip_endpoint *endpt, 786 pj_sock_t sock, 787 const pjsip_host_port *a_name, 788 unsigned async_cnt, 789 pjsip_transport **p_transport) 790 { 791 return transport_attach(endpt, PJSIP_TRANSPORT_UDP, sock, a_name, 792 async_cnt, p_transport); 793 } 794 795 PJ_DEF(pj_status_t) pjsip_udp_transport_attach2( pjsip_endpoint *endpt, 796 pjsip_transport_type_e type, 797 pj_sock_t sock, 798 const pjsip_host_port *a_name, 799 unsigned async_cnt, 800 pjsip_transport **p_transport) 801 { 802 return transport_attach(endpt, type, sock, a_name, 803 async_cnt, p_transport); 736 804 } 737 805 … … 749 817 pj_sock_t sock; 750 818 pj_status_t status; 751 char addr_buf[ 16];819 char addr_buf[PJ_INET6_ADDRSTRLEN]; 752 820 pjsip_host_port bound_name; 753 821 754 822 PJ_ASSERT_RETURN(endpt && async_cnt, PJ_EINVAL); 755 823 756 status = create_socket(local_a, &sock); 824 status = create_socket(pj_AF_INET(), local_a, sizeof(pj_sockaddr_in), 825 &sock); 757 826 if (status != PJ_SUCCESS) 758 827 return status; … … 762 831 * Build a name based on bound address. 763 832 */ 764 status = get_published_name(sock, addr_buf, &bound_name); 833 status = get_published_name(sock, addr_buf, sizeof(addr_buf), 834 &bound_name); 765 835 if (status != PJ_SUCCESS) { 766 836 pj_sock_close(sock); … … 775 845 } 776 846 847 848 /* 849 * pjsip_udp_transport_start() 850 * 851 * Create a UDP socket in the specified address and start a transport. 852 */ 853 PJ_DEF(pj_status_t) pjsip_udp_transport_start6(pjsip_endpoint *endpt, 854 const pj_sockaddr_in6 *local_a, 855 const pjsip_host_port *a_name, 856 unsigned async_cnt, 857 pjsip_transport **p_transport) 858 { 859 pj_sock_t sock; 860 pj_status_t status; 861 char addr_buf[PJ_INET_ADDRSTRLEN]; 862 pjsip_host_port bound_name; 863 864 PJ_ASSERT_RETURN(endpt && async_cnt, PJ_EINVAL); 865 866 status = create_socket(pj_AF_INET6(), local_a, sizeof(pj_sockaddr_in6), 867 &sock); 868 if (status != PJ_SUCCESS) 869 return status; 870 871 if (a_name == NULL) { 872 /* Address name is not specified. 873 * Build a name based on bound address. 874 */ 875 status = get_published_name(sock, addr_buf, sizeof(addr_buf), 876 &bound_name); 877 if (status != PJ_SUCCESS) { 878 pj_sock_close(sock); 879 return status; 880 } 881 882 a_name = &bound_name; 883 } 884 885 return pjsip_udp_transport_attach( endpt, sock, a_name, async_cnt, 886 p_transport); 887 } 777 888 778 889 /* … … 870 981 871 982 if (option & PJSIP_UDP_TRANSPORT_DESTROY_SOCKET) { 872 char addr_buf[ 16];983 char addr_buf[PJ_INET_ADDRSTRLEN]; 873 984 pjsip_host_port bound_name; 874 985 … … 891 1002 /* Create the socket if it's not specified */ 892 1003 if (sock == PJ_INVALID_SOCKET) { 893 status = create_socket(local, &sock); 1004 status = create_socket(pj_AF_INET(), local, 1005 sizeof(pj_sockaddr_in), &sock); 894 1006 if (status != PJ_SUCCESS) 895 1007 return status; … … 900 1012 */ 901 1013 if (a_name == NULL) { 902 status = get_published_name(sock, addr_buf, &bound_name); 1014 status = get_published_name(sock, addr_buf, sizeof(addr_buf), 1015 &bound_name); 903 1016 if (status != PJ_SUCCESS) { 904 1017 pj_sock_close(sock); -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c
r1571 r1602 1183 1183 1184 1184 /* 1185 * Tools to get address string. 1186 */ 1187 static const char *addr_string(const pj_sockaddr_t *addr) 1188 { 1189 static char str[128]; 1190 str[0] = '\0'; 1191 pj_inet_ntop(((const pj_sockaddr*)addr)->addr.sa_family, 1192 pj_sockaddr_get_addr(addr), 1193 str, sizeof(str)); 1194 return str; 1195 } 1196 1197 /* 1185 1198 * Create and initialize SIP socket (and possibly resolve public 1186 1199 * address via STUN, depending on config). 1187 1200 */ 1188 static pj_status_t create_sip_udp_sock(pj_in_addr bound_addr, 1201 static pj_status_t create_sip_udp_sock(int af, 1202 const pj_str_t *bind_param, 1189 1203 int port, 1190 1204 pj_sock_t *p_sock, 1191 pj_sockaddr _in*p_pub_addr)1192 { 1193 char ip_addr[32];1205 pj_sockaddr *p_pub_addr) 1206 { 1207 char stun_ip_addr[PJ_INET6_ADDRSTRLEN]; 1194 1208 pj_str_t stun_srv; 1195 1209 pj_sock_t sock; 1210 pj_sockaddr bind_addr; 1196 1211 pj_status_t status; 1197 1212 … … 1203 1218 } 1204 1219 1205 status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &sock); 1220 /* Initialize bound address */ 1221 if (bind_param->slen) { 1222 status = pj_sockaddr_init(af, &bind_addr, bind_param, 1223 (pj_uint16_t)port); 1224 if (status != PJ_SUCCESS) { 1225 pjsua_perror(THIS_FILE, 1226 "Unable to resolve transport bound address", 1227 status); 1228 return status; 1229 } 1230 } else { 1231 pj_sockaddr_init(af, &bind_addr, NULL, (pj_uint16_t)port); 1232 } 1233 1234 status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &sock); 1206 1235 if (status != PJ_SUCCESS) { 1207 1236 pjsua_perror(THIS_FILE, "socket() error", status); … … 1209 1238 } 1210 1239 1211 status = pj_sock_bind_in(sock, pj_ntohl(bound_addr.s_addr), 1212 (pj_uint16_t)port); 1240 status = pj_sock_bind(sock, &bind_addr, sizeof(bind_addr)); 1213 1241 if (status != PJ_SUCCESS) { 1214 1242 pjsua_perror(THIS_FILE, "bind() error", status); … … 1219 1247 /* If port is zero, get the bound port */ 1220 1248 if (port == 0) { 1221 pj_sockaddr _inbound_addr;1249 pj_sockaddr bound_addr; 1222 1250 int namelen = sizeof(bound_addr); 1223 1251 status = pj_sock_getsockname(sock, &bound_addr, &namelen); … … 1228 1256 } 1229 1257 1230 port = pj_ ntohs(bound_addr.sin_port);1258 port = pj_sockaddr_get_port(&bound_addr); 1231 1259 } 1232 1260 1233 1261 if (pjsua_var.stun_srv.addr.sa_family != 0) { 1234 pj_ansi_strcpy( ip_addr,pj_inet_ntoa(pjsua_var.stun_srv.ipv4.sin_addr));1235 stun_srv = pj_str( ip_addr);1262 pj_ansi_strcpy(stun_ip_addr,pj_inet_ntoa(pjsua_var.stun_srv.ipv4.sin_addr)); 1263 stun_srv = pj_str(stun_ip_addr); 1236 1264 } else { 1237 1265 stun_srv.slen = 0; … … 1241 1269 * the name of local host. 1242 1270 */ 1243 if (p _pub_addr->sin_addr.s_addr != 0) {1271 if (pj_sockaddr_has_addr(p_pub_addr)) { 1244 1272 /* 1245 1273 * Public address is already specified, no need to resolve the 1246 1274 * address, only set the port. 1247 1275 */ 1248 if (p _pub_addr->sin_port== 0)1249 p _pub_addr->sin_port = pj_htons((pj_uint16_t)port);1276 if (pj_sockaddr_get_port(p_pub_addr) == 0) 1277 pj_sockaddr_set_port(p_pub_addr, (pj_uint16_t)port); 1250 1278 1251 1279 } else if (stun_srv.slen) { … … 1253 1281 * STUN is specified, resolve the address with STUN. 1254 1282 */ 1283 if (af != pj_AF_INET()) { 1284 pjsua_perror(THIS_FILE, "Cannot use STUN", PJ_EAFNOTSUP); 1285 pj_sock_close(sock); 1286 return PJ_EAFNOTSUP; 1287 } 1288 1255 1289 status = pjstun_get_mapped_addr(&pjsua_var.cp.factory, 1, &sock, 1256 1290 &stun_srv, pj_ntohs(pjsua_var.stun_srv.ipv4.sin_port), 1257 1291 &stun_srv, pj_ntohs(pjsua_var.stun_srv.ipv4.sin_port), 1258 p_pub_addr);1292 &p_pub_addr->ipv4); 1259 1293 if (status != PJ_SUCCESS) { 1260 1294 pjsua_perror(THIS_FILE, "Error contacting STUN server", status); … … 1264 1298 1265 1299 } else { 1266 1267 pj_bzero(p_pub_addr, sizeof(pj_sockaddr_in)); 1268 1269 status = pj_gethostip(&p_pub_addr->sin_addr); 1300 pj_bzero(p_pub_addr, sizeof(pj_sockaddr)); 1301 1302 status = pj_gethostip(af, p_pub_addr); 1270 1303 if (status != PJ_SUCCESS) { 1271 1304 pjsua_perror(THIS_FILE, "Unable to get local host IP", status); … … 1274 1307 } 1275 1308 1276 p_pub_addr-> sin_family = pj_AF_INET();1277 p _pub_addr->sin_port = pj_htons((pj_uint16_t)port);1309 p_pub_addr->addr.sa_family = (pj_uint16_t)af; 1310 pj_sockaddr_set_port(p_pub_addr, (pj_uint16_t)port); 1278 1311 } 1279 1312 … … 1281 1314 1282 1315 PJ_LOG(4,(THIS_FILE, "SIP UDP socket reachable at %s:%d", 1283 pj_inet_ntoa(p_pub_addr->sin_addr),1284 (int)pj_ ntohs(p_pub_addr->sin_port)));1316 addr_string(p_pub_addr), 1317 (int)pj_sockaddr_get_port(p_pub_addr))); 1285 1318 1286 1319 return PJ_SUCCESS; … … 1314 1347 1315 1348 /* Create the transport */ 1316 if (type ==PJSIP_TRANSPORT_UDP) {1349 if (type & PJSIP_TRANSPORT_UDP) { 1317 1350 /* 1318 * Create UDP transport .1351 * Create UDP transport (IPv4 or IPv6). 1319 1352 */ 1320 1353 pjsua_transport_config config; 1354 char hostbuf[PJ_INET6_ADDRSTRLEN]; 1321 1355 pj_sock_t sock = PJ_INVALID_SOCKET; 1322 pj_sockaddr_in bound_addr; 1323 pj_sockaddr_in pub_addr; 1356 pj_sockaddr pub_addr; 1324 1357 pjsip_host_port addr_name; 1325 1358 … … 1330 1363 } 1331 1364 1332 /* Initialize bound address, if any */1333 bound_addr.sin_addr.s_addr = PJ_INADDR_ANY;1334 if (cfg->bound_addr.slen) {1335 status = pj_sockaddr_in_set_str_addr(&bound_addr,&cfg->bound_addr);1336 if (status != PJ_SUCCESS) {1337 pjsua_perror(THIS_FILE,1338 "Unable to resolve transport bound address",1339 status);1340 goto on_return;1341 }1342 }1343 1344 1365 /* Initialize the public address from the config, if any */ 1345 pj_sockaddr_in_init(&pub_addr, NULL, (pj_uint16_t)cfg->port); 1366 pj_sockaddr_init(pjsip_transport_type_get_af(type), &pub_addr, 1367 NULL, (pj_uint16_t)cfg->port); 1346 1368 if (cfg->public_addr.slen) { 1347 status = pj_sockaddr_in_set_str_addr(&pub_addr, &cfg->public_addr); 1369 status = pj_sockaddr_set_str_addr(pjsip_transport_type_get_af(type), 1370 &pub_addr, &cfg->public_addr); 1348 1371 if (status != PJ_SUCCESS) { 1349 1372 pjsua_perror(THIS_FILE, … … 1357 1380 * (only when public address is not specified). 1358 1381 */ 1359 status = create_sip_udp_sock(bound_addr.sin_addr, cfg->port, 1382 status = create_sip_udp_sock(pjsip_transport_type_get_af(type), 1383 &cfg->bound_addr, cfg->port, 1360 1384 &sock, &pub_addr); 1361 1385 if (status != PJ_SUCCESS) 1362 1386 goto on_return; 1363 1387 1364 addr_name.host = pj_str(pj_inet_ntoa(pub_addr.sin_addr)); 1365 addr_name.port = pj_ntohs(pub_addr.sin_port); 1388 pj_ansi_strcpy(hostbuf, addr_string(&pub_addr)); 1389 addr_name.host = pj_str(hostbuf); 1390 addr_name.port = pj_sockaddr_get_port(&pub_addr); 1366 1391 1367 1392 /* Create UDP transport */ 1368 status = pjsip_udp_transport_attach( pjsua_var.endpt, sock, 1369 &addr_name, 1, 1370 &tp); 1393 status = pjsip_udp_transport_attach2(pjsua_var.endpt, type, sock, 1394 &addr_name, 1, &tp); 1371 1395 if (status != PJ_SUCCESS) { 1372 1396 pjsua_perror(THIS_FILE, "Error creating SIP UDP transport", -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c
r1591 r1602 347 347 348 348 } else { 349 pj_ in_addr addr;349 pj_sockaddr addr; 350 350 351 351 /* Get local IP address. */ 352 status = pj_gethostip( &addr);352 status = pj_gethostip(pj_AF_INET(), &addr); 353 353 if (status != PJ_SUCCESS) 354 354 goto on_error; 355 355 356 356 for (i=0; i<2; ++i) 357 mapped_addr[i].sin_addr =addr;357 mapped_addr[i].sin_addr.s_addr = addr.ipv4.sin_addr.s_addr; 358 358 359 359 mapped_addr[0].sin_port=pj_htons((pj_uint16_t)next_rtp_port);
Note: See TracChangeset
for help on using the changeset viewer.