]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
update stun to more modern spec
authorAnthony Minessale <anthm@freeswitch.org>
Fri, 22 Jun 2012 23:06:42 +0000 (18:06 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Fri, 22 Jun 2012 23:15:06 +0000 (18:15 -0500)
src/include/switch_stun.h
src/switch_stun.c

index 7159cf1f3b873d41173c2408e266715f8cdaf14b..fbf6b3270fe8f021d72ad904c2833cb69f4dfb51 100644 (file)
@@ -57,6 +57,8 @@ SWITCH_BEGIN_EXTERN_C
        SWITCH_STUN_DATA_INDICATION = 0x0115
 } switch_stun_message_t;
 
+#define STUN_MAGIC_COOKIE 0x2112A442
+
 typedef enum {
        SWITCH_STUN_ATTR_MAPPED_ADDRESS = 0x0001,       /* Address */
        SWITCH_STUN_ATTR_RESPONSE_ADDRESS = 0x0002,     /* Address */
@@ -77,7 +79,8 @@ typedef enum {
        SWITCH_STUN_ATTR_DESTINATION_ADDRESS = 0x0011,  /* Address */
        SWITCH_STUN_ATTR_SOURCE_ADDRESS2 = 0x0012,      /* Address */
        SWITCH_STUN_ATTR_DATA = 0x0013, /* ByteString */
-       SWITCH_STUN_ATTR_OPTIONS = 0x8001       /* UInt32 */
+       SWITCH_STUN_ATTR_OPTIONS = 0x8001,      /* UInt32 */
+       SWITCH_STUN_ATTR_XOR_MAPPED_ADDRESS = 0x0020,   /* Address */  
 } switch_stun_attribute_t;
 
 typedef enum {
@@ -101,7 +104,8 @@ typedef enum {
 typedef struct {
        uint16_t type;
        uint16_t length;
-       char id[16];
+       uint32_t cookie;
+       char id[12];
 } switch_stun_packet_header_t;
 
 typedef struct {
@@ -185,6 +189,7 @@ SWITCH_DECLARE(switch_stun_packet_t *) switch_stun_packet_build_header(switch_st
   \return true or false
 */
 SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_username(switch_stun_packet_t *packet, char *username, uint16_t ulen);
+SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_password(switch_stun_packet_t *packet, char *password, uint16_t ulen);
 
 
 /*!
@@ -195,6 +200,7 @@ SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_username(switch_stun_pa
   \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);
 
 /*!
   \brief Perform a stun lookup
index 30933fff6a4b005e6b5dd2bfdc2b2ae3aca98f6e..616cf27a37185945a361ef25686db49c0eb306fa 100644 (file)
@@ -186,7 +186,6 @@ SWITCH_DECLARE(switch_stun_packet_t *) switch_stun_packet_parse(uint8_t *buf, ui
                         * we don't want the upper layers to have to deal with attributes without a value
                         * (or worse: invalid length)
                         */
-                       return NULL;
                }
 
                /*
@@ -367,11 +366,12 @@ SWITCH_DECLARE(switch_stun_packet_t *) switch_stun_packet_build_header(switch_st
        header = (switch_stun_packet_header_t *) buf;
        header->type = htons(type);
        header->length = 0;
+       header->cookie = htonl(STUN_MAGIC_COOKIE);
 
        if (id) {
-               memcpy(header->id, id, 16);
+               memcpy(header->id, id, 12);
        } else {
-               switch_stun_random_string(header->id, 16, NULL);
+               switch_stun_random_string(header->id, 12, NULL);
        }
 
        return (switch_stun_packet_t *) buf;
@@ -402,6 +402,38 @@ SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_binded_address(switch_s
                }
        }
 
+       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);
+       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;
+               }
+       }
+
+       ip->address = htonl(ntohl(ip->address) ^ STUN_MAGIC_COOKIE);
+
        packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length;
        return 1;
 }
@@ -426,6 +458,26 @@ SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_username(switch_stun_pa
        return 1;
 }
 
+SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_password(switch_stun_packet_t *packet, char *password, uint16_t ulen)
+{
+       switch_stun_packet_attribute_t *attribute;
+
+       if (ulen % 4 != 0) {
+               return 0;
+       }
+       attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length));
+       attribute->type = htons(SWITCH_STUN_ATTR_PASSWORD);
+       attribute->length = htons(ulen);
+       if (password) {
+               memcpy(attribute->value, password, ulen);
+       } else {
+               switch_stun_random_string(attribute->value, ulen, NULL);
+       }
+
+       packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length;
+       return 1;
+}
+
 SWITCH_DECLARE(char *) switch_stun_host_lookup(const char *host, switch_memory_pool_t *pool)
 {
        switch_sockaddr_t *addr = NULL;