diff --git a/src/include/switch_stun.h b/src/include/switch_stun.h index 9db0aadd84..59cbdd3215 100644 --- a/src/include/switch_stun.h +++ b/src/include/switch_stun.h @@ -141,7 +141,6 @@ typedef struct { uint32_t address; } switch_stun_ip_t; - #if SWITCH_BYTE_ORDER == __BIG_ENDIAN typedef struct { @@ -196,8 +195,8 @@ SWITCH_DECLARE(char *) switch_stun_host_lookup(const char *host, switch_memory_p \param port the port \return true or false */ -SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_get_mapped_address(switch_stun_packet_attribute_t *attribute, char *ipstr, uint16_t *port); -SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_get_xor_mapped_address(switch_stun_packet_attribute_t *attribute, uint32_t cookie, char *ipstr, uint16_t *port); +SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_get_mapped_address(switch_stun_packet_attribute_t *attribute, char *ipstr, switch_size_t iplen, uint16_t *port); +SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_get_xor_mapped_address(switch_stun_packet_attribute_t *attribute, switch_stun_packet_header_t *header, char *ipstr, switch_size_t iplen, uint16_t *port); /*! @@ -237,10 +236,8 @@ SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_software(switch_stun_pa \param port the port of the mapped address \return true or false */ -SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_binded_address(switch_stun_packet_t *packet, char *ipstr, uint16_t port); -SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_xor_binded_address(switch_stun_packet_t *packet, char *ipstr, uint16_t port); - - +SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_binded_address(switch_stun_packet_t *packet, char *ipstr, uint16_t port, int family); +SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_xor_binded_address(switch_stun_packet_t *packet, char *ipstr, uint16_t port, int family); SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_integrity(switch_stun_packet_t *packet, const char *pass); SWITCH_DECLARE(uint32_t) switch_crc32_8bytes(const void* data, size_t length); SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_fingerprint(switch_stun_packet_t *packet); diff --git a/src/switch_rtp.c b/src/switch_rtp.c index c9bfab8e9d..61e8367707 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -934,17 +934,17 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d break; case SWITCH_STUN_ATTR_MAPPED_ADDRESS: if (attr->type) { - char ip[16]; + char ip[50]; uint16_t port; - switch_stun_packet_attribute_get_mapped_address(attr, ip, &port); + switch_stun_packet_attribute_get_mapped_address(attr, ip, sizeof(ip), &port); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG8, "|------: %s:%d\n", ip, port); } break; case SWITCH_STUN_ATTR_XOR_MAPPED_ADDRESS: if (attr->type) { - char ip[16]; + char ip[50]; uint16_t port; - switch_stun_packet_attribute_get_xor_mapped_address(attr, packet->header.cookie, ip, &port); + switch_stun_packet_attribute_get_xor_mapped_address(attr, &packet->header, ip, sizeof(ip), &port); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG8, "|------: %s:%d\n", ip, port); } break; @@ -1031,8 +1031,8 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d uint32_t old; //const char *tx_host; const char *old_host, *err = NULL; - //char bufa[30]; - char bufb[30]; + //char bufa[50]; + char bufb[50]; char adj_port[6]; switch_channel_t *channel = NULL; @@ -1137,11 +1137,12 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d switch_stun_packet_t *rpacket; const char *remote_ip; switch_size_t bytes; - char ipbuf[25]; + char ipbuf[50]; switch_sockaddr_t *from_addr = rtp_session->from_addr; switch_socket_t *sock_output = rtp_session->sock_output; uint8_t do_adj = 0; switch_time_t now = switch_micro_time_now(); + int cmp = 0; if (is_rtcp) { from_addr = rtp_session->rtcp_from_addr; @@ -1160,7 +1161,8 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d } remote_ip = switch_get_addr(ipbuf, sizeof(ipbuf), from_addr); - switch_stun_packet_attribute_add_xor_binded_address(rpacket, (char *) remote_ip, switch_sockaddr_get_port(from_addr)); + + switch_stun_packet_attribute_add_xor_binded_address(rpacket, (char *) remote_ip, switch_sockaddr_get_port(from_addr), from_addr->family); if ((ice->type & ICE_VANILLA)) { switch_stun_packet_attribute_add_integrity(rpacket, ice->pass); @@ -1173,9 +1175,12 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d port = switch_sockaddr_get_port(from_addr); host2 = switch_get_addr(buf2, sizeof(buf2), ice->addr); port2 = switch_sockaddr_get_port(ice->addr); + cmp = switch_cmp_addr(from_addr, ice->addr); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1, + "STUN from %s:%d %s\n", host, port, cmp ? "EXPECTED" : "IGNORED"); - if (switch_cmp_addr(from_addr, ice->addr)) { + if (cmp) { ice->last_ok = now; } else { if ((rtp_session->dtls->state != DS_READY || !ice->ready || !ice->rready)) { @@ -2212,7 +2217,7 @@ static int check_rtcp_and_ice(switch_rtp_t *rtp_session) #ifdef DEBUG_EXTRA { const char *old_host; - char bufb[30]; + char bufb[50]; old_host = switch_get_addr(bufb, sizeof(bufb), rtp_session->rtcp_remote_addr); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_CRIT, "%s SEND %s RTCP %s:%d %ld\n", rtp_session_name(rtp_session), @@ -2407,7 +2412,7 @@ static switch_status_t enable_remote_rtcp_socket(switch_rtp_t *rtp_session, cons return SWITCH_STATUS_FALSE; } else { const char *host; - char bufa[30]; + char bufa[50]; host = switch_get_addr(bufa, sizeof(bufa), rtp_session->rtcp_remote_addr); @@ -2445,7 +2450,7 @@ static switch_status_t enable_local_rtcp_socket(switch_rtp_t *rtp_session, const switch_port_t port = rtp_session->local_port; switch_socket_t *rtcp_new_sock = NULL, *rtcp_old_sock = NULL; switch_status_t status = SWITCH_STATUS_SUCCESS; - char bufa[30]; + char bufa[50]; if (rtp_session->flags[SWITCH_RTP_FLAG_ENABLE_RTCP]) { if (switch_sockaddr_info_get(&rtp_session->rtcp_local_addr, host, SWITCH_UNSPEC, port+1, 0, rtp_session->pool) != SWITCH_STATUS_SUCCESS) { @@ -4155,7 +4160,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_ice(switch_rtp_t *rtp_sessio switch_rtp_ice_t *ice; char *host = NULL; switch_port_t port = 0; - char bufc[30]; + char bufc[50]; switch_mutex_lock(rtp_session->ice_mutex); @@ -5139,7 +5144,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t const char *old_host; const char *my_host; - char bufa[30], bufb[30], bufc[30]; + char bufa[50], bufb[50], bufc[50]; tx_host = switch_get_addr(bufa, sizeof(bufa), rtp_session->rtp_from_addr); @@ -5540,7 +5545,7 @@ static void handle_nack(switch_rtp_t *rtp_session, uint32_t nack) const char *tx_host = NULL; const char *old_host = NULL; const char *my_host = NULL; - char bufa[30], bufb[30], bufc[30]; + char bufa[50], bufb[50], bufc[50]; if (!(rtp_session->flags[SWITCH_RTP_FLAG_NACK] && rtp_session->vbw)) { return; /* not enabled */ @@ -6424,7 +6429,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ uint32_t old = rtp_session->remote_port; const char *tx_host; const char *old_host; - char bufa[30], bufb[30]; + char bufa[50], bufb[50]; char adj_port[6]; tx_host = switch_get_addr(bufa, sizeof(bufa), rtp_session->rtp_from_addr); @@ -7305,7 +7310,7 @@ static int rtp_common_write(switch_rtp_t *rtp_session, const char *old_host; const char *my_host; - char bufa[30], bufb[30], bufc[30]; + char bufa[50], bufb[50], bufc[50]; tx_host = switch_get_addr(bufa, sizeof(bufa), rtp_session->rtp_from_addr); @@ -7495,7 +7500,7 @@ SWITCH_DECLARE(int) switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_fra //if (rtp_session->flags[SWITCH_RTP_FLAG_PROXY_MEDIA] || rtp_session->flags[SWITCH_RTP_FLAG_UDPTL]) { switch_size_t bytes; - //char bufa[30]; + //char bufa[50]; /* Fast PASS! */ if (!switch_test_flag(frame, SFF_PROXY_PACKET) && !switch_test_flag(frame, SFF_UDPTL_PACKET)) { diff --git a/src/switch_stun.c b/src/switch_stun.c index d1f43c3244..cc3f983b17 100644 --- a/src/switch_stun.c +++ b/src/switch_stun.c @@ -107,6 +107,21 @@ static const struct value_mapping ERROR_TYPES[] = { {0, 0} }; +static void v6_xor(uint8_t *addr, const uint8_t *transaction_id) +{ + int i; + + addr[0] ^= 0x21; + addr[1] ^= 0x12; + addr[2] ^= 0xa4; + addr[3] ^= 0x42; + + for (i = 0; i < 12; i++) { + addr[i + 4] ^= transaction_id[i]; + } +} + + SWITCH_DECLARE(void) switch_stun_random_string(char *buf, uint16_t len, char *set) { char chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; @@ -220,8 +235,6 @@ SWITCH_DECLARE(switch_stun_packet_t *) switch_stun_packet_parse(uint8_t *buf, ui { switch_stun_ip_t *ip = (switch_stun_ip_t *) attr->value; ip->port = ntohs(ip->port); - //uint32_t *u = (uint32_t *)attr->value; - //*u = ntohl(*u); } break; case SWITCH_STUN_ATTR_SOURCE_ADDRESS2: @@ -361,7 +374,7 @@ SWITCH_DECLARE(const char *) switch_stun_value_to_name(int32_t type, uint32_t va return "INVALID"; } -SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_get_mapped_address(switch_stun_packet_attribute_t *attribute, char *ipstr, uint16_t *port) +SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_get_mapped_address(switch_stun_packet_attribute_t *attribute, char *ipstr, switch_size_t iplen, uint16_t *port) { switch_stun_ip_t *ip; uint8_t x, *i; @@ -378,23 +391,30 @@ SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_get_mapped_address(switch_s return 1; } -SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_get_xor_mapped_address(switch_stun_packet_attribute_t *attribute, uint32_t cookie, char *ipstr, uint16_t *port) +SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_get_xor_mapped_address(switch_stun_packet_attribute_t *attribute, switch_stun_packet_header_t *header, char *ipstr, switch_size_t iplen, uint16_t *port) { switch_stun_ip_t *ip; uint8_t x, *i; char *p = ipstr; ip = (switch_stun_ip_t *) attribute->value; - ip->address ^= cookie; - i = (uint8_t *) & ip->address; - *ipstr = 0; - for (x = 0; x < 4; x++) { - sprintf(p, "%u%s", i[x], x == 3 ? "" : "."); - p = ipstr + strlen(ipstr); + if (ip->family == 2) { + uint8_t *v6addr = (uint8_t *) &ip->address; + v6_xor(v6addr, (uint8_t *)header->id); + inet_ntop(AF_INET6, v6addr, ipstr, iplen); + } else { + ip->address ^= header->cookie; + + i = (uint8_t *) & ip->address; + *ipstr = 0; + for (x = 0; x < 4; x++) { + sprintf(p, "%u%s", i[x], x == 3 ? "" : "."); + p = ipstr + strlen(ipstr); + } } - ip->port ^= ntohl(cookie) >> 16; + ip->port ^= ntohl(header->cookie) >> 16; *port = ip->port; return 1; @@ -427,62 +447,72 @@ SWITCH_DECLARE(switch_stun_packet_t *) switch_stun_packet_build_header(switch_st return (switch_stun_packet_t *) buf; } -SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_binded_address(switch_stun_packet_t *packet, char *ipstr, uint16_t port) + +SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_binded_address(switch_stun_packet_t *packet, char *ipstr, uint16_t port, int family) { switch_stun_packet_attribute_t *attribute; switch_stun_ip_t *ip; - uint8_t *i, x; - char *p = ipstr; - - attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length)); - attribute->type = htons(SWITCH_STUN_ATTR_MAPPED_ADDRESS); - attribute->length = htons(8); - ip = (switch_stun_ip_t *) attribute->value; - - ip->port = htons(port); - ip->family = 1; - i = (uint8_t *) & ip->address; - - for (x = 0; x < 4; x++) { - i[x] = (uint8_t) atoi(p); - if ((p = strchr(p, '.'))) { - p++; - } else { - break; - } - } - - packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length; - - return 1; -} - -SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_xor_binded_address(switch_stun_packet_t *packet, char *ipstr, uint16_t port) -{ - switch_stun_packet_attribute_t *attribute; - switch_stun_ip_t *ip; - uint8_t *i, x; - char *p = ipstr; - + attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length)); attribute->type = htons(SWITCH_STUN_ATTR_XOR_MAPPED_ADDRESS); - attribute->length = htons(8); + + if (family == AF_INET6) { + attribute->length = htons(20); + } else { + attribute->length = htons(8); + } + ip = (switch_stun_ip_t *) attribute->value; ip->port = htons(port ^ (STUN_MAGIC_COOKIE >> 16)); - ip->family = 1; - i = (uint8_t *) & ip->address; - for (x = 0; x < 4; x++) { - i[x] = (uint8_t) atoi(p); - if ((p = strchr(p, '.'))) { - p++; - } else { - break; - } + if (family == AF_INET6) { + ip->family = 2; + } else { + ip->family = 1; } - ip->address = htonl(ntohl(ip->address) ^ STUN_MAGIC_COOKIE); + if (family == AF_INET6) { + inet_pton(AF_INET6, ipstr, (struct in6_addr *) &ip->address); + } else { + inet_pton(AF_INET, ipstr, (int *) &ip->address); + } + + packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length; + return 1; +} + +SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_xor_binded_address(switch_stun_packet_t *packet, char *ipstr, uint16_t port, int family) +{ + switch_stun_packet_attribute_t *attribute; + switch_stun_ip_t *ip; + + attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length)); + attribute->type = htons(SWITCH_STUN_ATTR_XOR_MAPPED_ADDRESS); + + if (family == AF_INET6) { + attribute->length = htons(20); + } else { + attribute->length = htons(8); + } + + ip = (switch_stun_ip_t *) attribute->value; + + ip->port = htons(port ^ (STUN_MAGIC_COOKIE >> 16)); + + if (family == AF_INET6) { + ip->family = 2; + } else { + ip->family = 1; + } + + if (family == AF_INET6) { + inet_pton(AF_INET6, ipstr, (struct in6_addr *) &ip->address); + v6_xor((uint8_t *)&ip->address, (uint8_t *)packet->header.id); + } else { + inet_pton(AF_INET, ipstr, (int *) &ip->address); + ip->address = htonl(ntohl(ip->address) ^ STUN_MAGIC_COOKIE); + } packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length; return 1; @@ -677,7 +707,7 @@ SWITCH_DECLARE(switch_status_t) switch_stun_lookup(char **ip, switch_stun_packet_attribute_t *attr; switch_size_t bytes = 0; char username[33] = { 0 }; - char rip[16] = { 0 }; + char rip[50] = { 0 }; uint16_t rport = 0; switch_time_t started = 0; unsigned int elapsed = 0; @@ -780,12 +810,12 @@ SWITCH_DECLARE(switch_status_t) switch_stun_lookup(char **ip, switch_stun_ip_t *tmp = (switch_stun_ip_t *) attr->value; tmp->address ^= ntohl(0xabcdabcd); } - switch_stun_packet_attribute_get_mapped_address(attr, rip, &rport); + switch_stun_packet_attribute_get_mapped_address(attr, rip, sizeof(rip), &rport); } break; case SWITCH_STUN_ATTR_XOR_MAPPED_ADDRESS: if (attr->type) { - switch_stun_packet_attribute_get_xor_mapped_address(attr, packet->header.cookie, rip, &rport); + switch_stun_packet_attribute_get_xor_mapped_address(attr, &packet->header, rip, sizeof(rip), &rport); } break; case SWITCH_STUN_ATTR_USERNAME: diff --git a/src/switch_utils.c b/src/switch_utils.c index c4a2482356..f1cd1e572f 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -2196,7 +2196,7 @@ SWITCH_DECLARE(int) switch_cp_addr(switch_sockaddr_t *sa1, switch_sockaddr_t *sa struct sockaddr_in6 *s26; struct sockaddr *ss1; - struct sockaddr *ss2; + //struct sockaddr *ss2; if (!(sa1 && sa2)) return 0; @@ -2208,14 +2208,13 @@ SWITCH_DECLARE(int) switch_cp_addr(switch_sockaddr_t *sa1, switch_sockaddr_t *sa s26 = (struct sockaddr_in6 *) &sa2->sa; ss1 = (struct sockaddr *) &sa1->sa; - ss2 = (struct sockaddr *) &sa2->sa; + //ss2 = (struct sockaddr *) &sa2->sa; - if (ss1->sa_family != ss2->sa_family) - return 0; - sa1->port = sa2->port; sa1->family = sa2->family; - + + sa1->sa.sin.sin_family = sa2->family; + switch (ss1->sa_family) { case AF_INET: s1->sin_addr.s_addr = s2->sin_addr.s_addr;