RTS API Documentation  1.10.11
Data Structures | Macros | Enumerations | Functions
STUN code
+ Collaboration diagram for STUN code:

Data Structures

struct  switch_stun_packet_header_t
 
struct  switch_stun_packet_attribute_t
 
struct  switch_stun_packet_t
 
struct  switch_stun_ip_t
 
struct  switch_stun_ipv6_t
 
struct  switch_stun_error_code_t
 

Macros

#define SWITCH_STUN_DEFAULT_PORT   3478
 
#define SWITCH_STUN_PACKET_MIN_LEN   20
 
#define SWITCH_STUN_ATTRIBUTE_MIN_LEN   8
 
#define STUN_MAGIC_COOKIE   0x2112A442
 
#define switch_stun_attribute_padded_length(attribute)   (int16_t)((attribute->length & 0x3) ? 0x4 + (attribute->length & ~0x3) : attribute->length)
 Obtain the padded length of an attribute's value. More...
 
#define switch_stun_attribute_padded_length_hbo(attribute)   (int16_t)((ntohs(attribute->length) & 0x3) ? 0x4 + (ntohs(attribute->length) & ~0x3) : ntohs(attribute->length))
 
#define switch_stun_packet_first_attribute(packet, attribute)   attribute = (switch_stun_packet_attribute_t *)(&packet->first_attribute);
 set a switch_stun_packet_attribute_t pointer to point at the first attribute in a packet More...
 
#define switch_stun_packet_next_attribute(attribute, end)   (attribute && (attribute = (switch_stun_packet_attribute_t *) (attribute->value + switch_stun_attribute_padded_length(attribute))) && ((void *)attribute < end) && attribute->type && (((switch_byte_t *)attribute + switch_stun_attribute_padded_length(attribute)) < (switch_byte_t *)end))
 Increment an attribute pointer to the next attribute in it's packet. More...
 
#define switch_stun_packet_next_attribute_hbo(attribute, end)   (attribute && (attribute = (switch_stun_packet_attribute_t *) (attribute->value + switch_stun_attribute_padded_length_hbo(attribute))) && ((void *)attribute < end) && attribute->type && (((switch_byte_t *)attribute + switch_stun_attribute_padded_length_hbo(attribute)) < (switch_byte_t *)end))
 
#define switch_stun_packet_length(packet)   ntohs(packet->header.length) + (sizeof(switch_stun_packet_header_t))
 Obtain the correct length in bytes of a stun packet. More...
 

Enumerations

enum  switch_stun_message_t {
  SWITCH_STUN_BINDING_REQUEST = 0x0001, SWITCH_STUN_BINDING_RESPONSE = 0x0101, SWITCH_STUN_BINDING_ERROR_RESPONSE = 0x0111, SWITCH_STUN_SHARED_SECRET_REQUEST = 0x0002,
  SWITCH_STUN_SHARED_SECRET_RESPONSE = 0x0102, SWITCH_STUN_SHARED_SECRET_ERROR_RESPONSE = 0x0112, SWITCH_STUN_ALLOCATE_REQUEST = 0x0003, SWITCH_STUN_ALLOCATE_RESPONSE = 0x0103,
  SWITCH_STUN_ALLOCATE_ERROR_RESPONSE = 0x0113, SWITCH_STUN_SEND_REQUEST = 0x0004, SWITCH_STUN_SEND_RESPONSE = 0x0104, SWITCH_STUN_SEND_ERROR_RESPONSE = 0x0114,
  SWITCH_STUN_DATA_INDICATION = 0x0115
}
 
enum  switch_stun_attribute_t {
  SWITCH_STUN_ATTR_MAPPED_ADDRESS = 0x0001, SWITCH_STUN_ATTR_RESPONSE_ADDRESS = 0x0002, SWITCH_STUN_ATTR_CHANGE_REQUEST = 0x0003, SWITCH_STUN_ATTR_SOURCE_ADDRESS = 0x0004,
  SWITCH_STUN_ATTR_CHANGED_ADDRESS = 0x0005, SWITCH_STUN_ATTR_USERNAME = 0x0006, SWITCH_STUN_ATTR_PASSWORD = 0x0007, SWITCH_STUN_ATTR_MESSAGE_INTEGRITY = 0x0008,
  SWITCH_STUN_ATTR_ERROR_CODE = 0x0009, SWITCH_STUN_ATTR_UNKNOWN_ATTRIBUTES = 0x000a, SWITCH_STUN_ATTR_REFLECTED_FROM = 0x000b, SWITCH_STUN_ATTR_TRANSPORT_PREFERENCES = 0x000c,
  SWITCH_STUN_ATTR_LIFETIME = 0x000d, SWITCH_STUN_ATTR_ALTERNATE_SERVER = 0x000e, SWITCH_STUN_ATTR_MAGIC_COOKIE = 0x000f, SWITCH_STUN_ATTR_BANDWIDTH = 0x0010,
  SWITCH_STUN_ATTR_DESTINATION_ADDRESS = 0x0011, SWITCH_STUN_ATTR_SOURCE_ADDRESS2 = 0x0012, SWITCH_STUN_ATTR_DATA = 0x0013, SWITCH_STUN_ATTR_OPTIONS = 0x8001,
  SWITCH_STUN_ATTR_XOR_MAPPED_ADDRESS = 0x0020, SWITCH_STUN_ATTR_PRIORITY = 0x0024, SWITCH_STUN_ATTR_USE_CAND = 0x0025, SWITCH_STUN_ATTR_PADDING = 0x0026,
  SWITCH_STUN_ATTR_RESP_PORT = 0x0027, SWITCH_STUN_ATTR_SOFTWARE = 0x8022, SWITCH_STUN_ATTR_ALT_SERVER = 0x8023, SWITCH_STUN_ATTR_FINGERPRINT = 0x8028,
  SWITCH_STUN_ATTR_CONTROLLED = 0x8029, SWITCH_STUN_ATTR_CONTROLLING = 0x802a, SWITCH_STUN_ATTR_RESP_ORIGIN = 0x802b, SWITCH_STUN_ATTR_OTHER_ADDR = 0x802c
}
 
enum  switch_stun_error_t {
  SWITCH_STUN_ERROR_BAD_REQUEST = 400, SWITCH_STUN_ERROR_UNAUTHORIZED = 401, SWITCH_STUN_ERROR_UNKNOWN_ATTRIBUTE = 420, SWITCH_STUN_ERROR_STALE_CREDENTIALS = 430,
  SWITCH_STUN_ERROR_INTEGRITY_CHECK_FAILURE = 431, SWITCH_STUN_ERROR_MISSING_USERNAME = 432, SWITCH_STUN_ERROR_USE_TLS = 433, SWITCH_STUN_ERROR_SERVER_ERROR = 500,
  SWITCH_STUN_ERROR_GLOBAL_FAILURE = 600
}
 
enum  switch_stun_type_t { SWITCH_STUN_TYPE_PACKET_TYPE, SWITCH_STUN_TYPE_ATTRIBUTE, SWITCH_STUN_TYPE_ERROR }
 

Functions

void switch_stun_random_string (char *buf, uint16_t len, char *set)
 Writes random characters into a buffer. More...
 
switch_stun_packet_tswitch_stun_packet_parse (uint8_t *buf, uint32_t len)
 Prepare a raw packet for parsing. More...
 
const char * switch_stun_value_to_name (int32_t type, uint32_t value)
 Obtain a printable string form of a given value. More...
 
char * switch_stun_host_lookup (const char *host, switch_memory_pool_t *pool)
 
uint8_t switch_stun_packet_attribute_get_mapped_address (switch_stun_packet_attribute_t *attribute, char *ipstr, switch_size_t iplen, uint16_t *port)
 Extract a mapped address (IP:PORT) from a packet attribute. More...
 
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)
 
char * switch_stun_packet_attribute_get_username (switch_stun_packet_attribute_t *attribute, char *username, uint16_t len)
 Extract a username from a packet attribute. More...
 
switch_stun_packet_tswitch_stun_packet_build_header (switch_stun_message_t type, char *id, uint8_t *buf)
 Prepare a new outbound packet of a certian type and id. More...
 
uint8_t switch_stun_packet_attribute_add_username (switch_stun_packet_t *packet, char *username, uint16_t ulen)
 Add a username packet attribute. More...
 
uint8_t switch_stun_packet_attribute_add_password (switch_stun_packet_t *packet, char *password, uint16_t ulen)
 
uint8_t switch_stun_packet_attribute_add_software (switch_stun_packet_t *packet, char *software, uint16_t ulen)
 
uint8_t switch_stun_packet_attribute_add_binded_address (switch_stun_packet_t *packet, char *ipstr, uint16_t port, int family)
 Add a binded address packet attribute. More...
 
uint8_t switch_stun_packet_attribute_add_xor_binded_address (switch_stun_packet_t *packet, char *ipstr, uint16_t port, int family)
 
uint8_t switch_stun_packet_attribute_add_integrity (switch_stun_packet_t *packet, const char *pass)
 
uint32_t switch_crc32_8bytes (const void *data, size_t length)
 
uint8_t switch_stun_packet_attribute_add_fingerprint (switch_stun_packet_t *packet)
 
uint8_t switch_stun_packet_attribute_add_use_candidate (switch_stun_packet_t *packet)
 
uint8_t switch_stun_packet_attribute_add_controlling (switch_stun_packet_t *packet)
 
uint8_t switch_stun_packet_attribute_add_controlled (switch_stun_packet_t *packet)
 
uint8_t switch_stun_packet_attribute_add_priority (switch_stun_packet_t *packet, uint32_t priority)
 
switch_status_t switch_stun_lookup (char **ip, switch_port_t *port, char *stunip, switch_port_t stunport, char **err, switch_memory_pool_t *pool)
 Perform a stun lookup. More...
 
switch_status_t switch_stun_ip_lookup (char **external_ip, const char *sourceip, switch_memory_pool_t *external_pool)
 Perform a stun ip lookup. More...
 

Detailed Description

Macro Definition Documentation

◆ STUN_MAGIC_COOKIE

#define STUN_MAGIC_COOKIE   0x2112A442

◆ SWITCH_STUN_ATTRIBUTE_MIN_LEN

#define SWITCH_STUN_ATTRIBUTE_MIN_LEN   8

Definition at line 43 of file switch_stun.h.

Referenced by switch_stun_packet_parse().

◆ switch_stun_attribute_padded_length

#define switch_stun_attribute_padded_length (   attribute)    (int16_t)((attribute->length & 0x3) ? 0x4 + (attribute->length & ~0x3) : attribute->length)

Obtain the padded length of an attribute's value.

Parameters
attributethe attribute
Returns
the padded size in bytes

Definition at line 284 of file switch_stun.h.

Referenced by handle_ice(), switch_stun_lookup(), and switch_stun_packet_parse().

◆ switch_stun_attribute_padded_length_hbo

#define switch_stun_attribute_padded_length_hbo (   attribute)    (int16_t)((ntohs(attribute->length) & 0x3) ? 0x4 + (ntohs(attribute->length) & ~0x3) : ntohs(attribute->length))

Definition at line 285 of file switch_stun.h.

◆ SWITCH_STUN_DEFAULT_PORT

#define SWITCH_STUN_DEFAULT_PORT   3478

Definition at line 41 of file switch_stun.h.

Referenced by switch_core_media_ext_address_lookup(), and switch_stun_ip_lookup().

◆ switch_stun_packet_first_attribute

#define switch_stun_packet_first_attribute (   packet,
  attribute 
)    attribute = (switch_stun_packet_attribute_t *)(&packet->first_attribute);

set a switch_stun_packet_attribute_t pointer to point at the first attribute in a packet

Parameters
packetthe packet in question
attributethe pointer to set up

Definition at line 293 of file switch_stun.h.

Referenced by handle_ice(), switch_stun_lookup(), and switch_stun_packet_parse().

◆ switch_stun_packet_length

#define switch_stun_packet_length (   packet)    ntohs(packet->header.length) + (sizeof(switch_stun_packet_header_t))

Obtain the correct length in bytes of a stun packet.

Parameters
packetthe packet in question
Returns
the size in bytes (host order) of the entire packet

Definition at line 311 of file switch_stun.h.

Referenced by handle_ice(), ice_out(), and switch_stun_lookup().

◆ SWITCH_STUN_PACKET_MIN_LEN

#define SWITCH_STUN_PACKET_MIN_LEN   20

Definition at line 42 of file switch_stun.h.

Referenced by switch_stun_packet_parse().

◆ switch_stun_packet_next_attribute

#define switch_stun_packet_next_attribute (   attribute,
  end 
)    (attribute && (attribute = (switch_stun_packet_attribute_t *) (attribute->value + switch_stun_attribute_padded_length(attribute))) && ((void *)attribute < end) && attribute->type && (((switch_byte_t *)attribute + switch_stun_attribute_padded_length(attribute)) < (switch_byte_t *)end))

Increment an attribute pointer to the next attribute in it's packet.

Parameters
attributethe pointer to increment
endpointer to the end of the buffer
Returns
true or false depending on if there are any more attributes

Definition at line 302 of file switch_stun.h.

Referenced by handle_ice(), and switch_stun_lookup().

◆ switch_stun_packet_next_attribute_hbo

#define switch_stun_packet_next_attribute_hbo (   attribute,
  end 
)    (attribute && (attribute = (switch_stun_packet_attribute_t *) (attribute->value + switch_stun_attribute_padded_length_hbo(attribute))) && ((void *)attribute < end) && attribute->type && (((switch_byte_t *)attribute + switch_stun_attribute_padded_length_hbo(attribute)) < (switch_byte_t *)end))

Definition at line 304 of file switch_stun.h.

Enumeration Type Documentation

◆ switch_stun_attribute_t

Enumerator
SWITCH_STUN_ATTR_MAPPED_ADDRESS 
SWITCH_STUN_ATTR_RESPONSE_ADDRESS 
SWITCH_STUN_ATTR_CHANGE_REQUEST 
SWITCH_STUN_ATTR_SOURCE_ADDRESS 
SWITCH_STUN_ATTR_CHANGED_ADDRESS 
SWITCH_STUN_ATTR_USERNAME 
SWITCH_STUN_ATTR_PASSWORD 
SWITCH_STUN_ATTR_MESSAGE_INTEGRITY 
SWITCH_STUN_ATTR_ERROR_CODE 
SWITCH_STUN_ATTR_UNKNOWN_ATTRIBUTES 
SWITCH_STUN_ATTR_REFLECTED_FROM 
SWITCH_STUN_ATTR_TRANSPORT_PREFERENCES 
SWITCH_STUN_ATTR_LIFETIME 
SWITCH_STUN_ATTR_ALTERNATE_SERVER 
SWITCH_STUN_ATTR_MAGIC_COOKIE 
SWITCH_STUN_ATTR_BANDWIDTH 
SWITCH_STUN_ATTR_DESTINATION_ADDRESS 
SWITCH_STUN_ATTR_SOURCE_ADDRESS2 
SWITCH_STUN_ATTR_DATA 
SWITCH_STUN_ATTR_OPTIONS 
SWITCH_STUN_ATTR_XOR_MAPPED_ADDRESS 
SWITCH_STUN_ATTR_PRIORITY 
SWITCH_STUN_ATTR_USE_CAND 
SWITCH_STUN_ATTR_PADDING 
SWITCH_STUN_ATTR_RESP_PORT 
SWITCH_STUN_ATTR_SOFTWARE 
SWITCH_STUN_ATTR_ALT_SERVER 
SWITCH_STUN_ATTR_FINGERPRINT 
SWITCH_STUN_ATTR_CONTROLLED 
SWITCH_STUN_ATTR_CONTROLLING 
SWITCH_STUN_ATTR_RESP_ORIGIN 
SWITCH_STUN_ATTR_OTHER_ADDR 

Definition at line 62 of file switch_stun.h.

62  {
63  SWITCH_STUN_ATTR_MAPPED_ADDRESS = 0x0001, /* Address */
64  SWITCH_STUN_ATTR_RESPONSE_ADDRESS = 0x0002, /* Address */
65  SWITCH_STUN_ATTR_CHANGE_REQUEST = 0x0003, /* UInt32 */
66  SWITCH_STUN_ATTR_SOURCE_ADDRESS = 0x0004, /* Address */
67  SWITCH_STUN_ATTR_CHANGED_ADDRESS = 0x0005, /* Address */
68  SWITCH_STUN_ATTR_USERNAME = 0x0006, /* ByteString, multiple of 4 bytes */
69  SWITCH_STUN_ATTR_PASSWORD = 0x0007, /* ByteString, multiple of 4 bytes */
70  SWITCH_STUN_ATTR_MESSAGE_INTEGRITY = 0x0008, /* ByteString, 20 bytes */
71  SWITCH_STUN_ATTR_ERROR_CODE = 0x0009, /* ErrorCode */
72  SWITCH_STUN_ATTR_UNKNOWN_ATTRIBUTES = 0x000a, /* UInt16List */
73  SWITCH_STUN_ATTR_REFLECTED_FROM = 0x000b, /* Address */
74  SWITCH_STUN_ATTR_TRANSPORT_PREFERENCES = 0x000c, /* TransportPrefs */
75  SWITCH_STUN_ATTR_LIFETIME = 0x000d, /* UInt32 */
76  SWITCH_STUN_ATTR_ALTERNATE_SERVER = 0x000e, /* Address */
77  SWITCH_STUN_ATTR_MAGIC_COOKIE = 0x000f, /* ByteString, 4 bytes */
78  SWITCH_STUN_ATTR_BANDWIDTH = 0x0010, /* UInt32 */
79  SWITCH_STUN_ATTR_DESTINATION_ADDRESS = 0x0011, /* Address */
80  SWITCH_STUN_ATTR_SOURCE_ADDRESS2 = 0x0012, /* Address */
81  SWITCH_STUN_ATTR_DATA = 0x0013, /* ByteString */
82  SWITCH_STUN_ATTR_OPTIONS = 0x8001, /* UInt32 */
83  SWITCH_STUN_ATTR_XOR_MAPPED_ADDRESS = 0x0020, /* Address */
84 
85  /* ice crap */
86 
89  SWITCH_STUN_ATTR_PADDING = 0x0026,
98 
switch_stun_attribute_t
Definition: switch_stun.h:62

◆ switch_stun_error_t

Enumerator
SWITCH_STUN_ERROR_BAD_REQUEST 
SWITCH_STUN_ERROR_UNAUTHORIZED 
SWITCH_STUN_ERROR_UNKNOWN_ATTRIBUTE 
SWITCH_STUN_ERROR_STALE_CREDENTIALS 
SWITCH_STUN_ERROR_INTEGRITY_CHECK_FAILURE 
SWITCH_STUN_ERROR_MISSING_USERNAME 
SWITCH_STUN_ERROR_USE_TLS 
SWITCH_STUN_ERROR_SERVER_ERROR 
SWITCH_STUN_ERROR_GLOBAL_FAILURE 

Definition at line 101 of file switch_stun.h.

◆ switch_stun_message_t

Enumerator
SWITCH_STUN_BINDING_REQUEST 
SWITCH_STUN_BINDING_RESPONSE 
SWITCH_STUN_BINDING_ERROR_RESPONSE 
SWITCH_STUN_SHARED_SECRET_REQUEST 
SWITCH_STUN_SHARED_SECRET_RESPONSE 
SWITCH_STUN_SHARED_SECRET_ERROR_RESPONSE 
SWITCH_STUN_ALLOCATE_REQUEST 
SWITCH_STUN_ALLOCATE_RESPONSE 
SWITCH_STUN_ALLOCATE_ERROR_RESPONSE 
SWITCH_STUN_SEND_REQUEST 
SWITCH_STUN_SEND_RESPONSE 
SWITCH_STUN_SEND_ERROR_RESPONSE 
SWITCH_STUN_DATA_INDICATION 

Definition at line 44 of file switch_stun.h.

◆ switch_stun_type_t

Enumerator
SWITCH_STUN_TYPE_PACKET_TYPE 
SWITCH_STUN_TYPE_ATTRIBUTE 
SWITCH_STUN_TYPE_ERROR 

Definition at line 113 of file switch_stun.h.

Function Documentation

◆ switch_crc32_8bytes()

uint32_t switch_crc32_8bytes ( const void *  data,
size_t  length 
)

Definition at line 1232 of file switch_stun.c.

References crc32Lookup.

Referenced by switch_stun_packet_attribute_add_fingerprint().

1233 {
1234  uint32_t *current = (uint32_t *) data;
1235  uint32_t previousCrc32 = 0;
1236  uint32_t crc = ~previousCrc32; // same as previousCrc32 ^ 0xFFFFFFFF
1237  uint8_t *currentChar;
1238 
1239  // process eight bytes at once
1240  while (length >= 8)
1241  {
1242  uint32_t one = *current++ ^ crc;
1243  uint32_t two = *current++;
1244  crc = crc32Lookup[7][ one & 0xFF] ^
1245  crc32Lookup[6][(one>> 8) & 0xFF] ^
1246  crc32Lookup[5][(one>>16) & 0xFF] ^
1247  crc32Lookup[4][ one>>24 ] ^
1248  crc32Lookup[3][ two & 0xFF] ^
1249  crc32Lookup[2][(two>> 8) & 0xFF] ^
1250  crc32Lookup[1][(two>>16) & 0xFF] ^
1251  crc32Lookup[0][ two>>24 ];
1252  length -= 8;
1253  }
1254 
1255  currentChar = (uint8_t*) current;
1256  // remaining 1 to 7 bytes (standard CRC table-based algorithm)
1257  while (length--)
1258  crc = (crc >> 8) ^ crc32Lookup[0][(crc & 0xFF) ^ *currentChar++];
1259 
1260  return ~crc; // same as crc ^ 0xFFFFFFFF
1261 }
const uint32_t crc32Lookup[8][256]
look-up table, already defined in line 18
Definition: switch_stun.c:941
char const int length
Definition: switch_cJSON.h:153

◆ switch_stun_host_lookup()

char* switch_stun_host_lookup ( const char *  host,
switch_memory_pool_t pool 
)

Definition at line 699 of file switch_stun.c.

References buf, switch_core_strdup, switch_get_addr(), switch_sockaddr_info_get(), switch_str_nil, and SWITCH_UNSPEC.

Referenced by switch_core_media_ext_address_lookup(), and switch_stun_ip_lookup().

700 {
701  switch_sockaddr_t *addr = NULL;
702  char buf[30];
703  switch_status_t res;
704 
705  res = switch_sockaddr_info_get(&addr, host, SWITCH_UNSPEC, 0, 0, pool);
706  (void)res;
707 
708  return switch_core_strdup(pool, switch_str_nil(switch_get_addr(buf, sizeof(buf), addr)));
709 
710 }
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:733
switch_memory_pool_t * pool
switch_byte_t switch_byte_t * buf
struct fspr_sockaddr_t switch_sockaddr_t
Definition: switch_apr.h:1029
#define switch_str_nil(s)
Make a null string a blank string instead.
Definition: switch_utils.h:993
switch_status_t
Common return values.
#define SWITCH_UNSPEC
Definition: switch_apr.h:1022
const char * switch_get_addr(char *buf, switch_size_t len, switch_sockaddr_t *in)
Definition: switch_apr.c:979
switch_status_t switch_sockaddr_info_get(switch_sockaddr_t **sa, const char *hostname, int32_t family, switch_port_t port, int32_t flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:839

◆ switch_stun_ip_lookup()

switch_status_t switch_stun_ip_lookup ( char **  external_ip,
const char *  sourceip,
switch_memory_pool_t external_pool 
)

Perform a stun ip lookup.

Parameters
external_ipreplaced with stun results
sourceipstun:, host: or an ip
external_poolthe memory pool to use
Returns
SUCCESS or FAIL

Definition at line 867 of file switch_stun.c.

References ip, switch_assert, SWITCH_CHANNEL_LOG, switch_core_destroy_memory_pool, switch_core_new_memory_pool, switch_core_strdup, switch_find_local_ip(), SWITCH_LOG_ERROR, SWITCH_LOG_INFO, switch_log_printf(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, SWITCH_STUN_DEFAULT_PORT, switch_stun_host_lookup(), switch_stun_lookup(), and zstr.

Referenced by preprocess_stun_set().

868 {
870  char *stun_ip = NULL;
872  char *p;
873  char ip_buf[256] = "";
874  char *ip = NULL;
875  switch_port_t port = 0;
876  switch_memory_pool_t *local_pool = NULL;
877  char *error = "";
878 
879  if (!sourceip || !external_pool) {
880  *external_ip = NULL;
881  goto end;
882  }
883 
884  ip = ip_buf;
885 
886  if (!strncasecmp(sourceip, "host:", 5)) {
887  status = (*external_ip = switch_stun_host_lookup(sourceip + 5, external_pool)) ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
888  }
889  else if (!strncasecmp(sourceip, "stun:", 5)) {
890 
891  switch_core_new_memory_pool(&local_pool);
892 
893  stun_ip = switch_core_strdup(local_pool, sourceip + 5);
894 
895  switch_assert(stun_ip);
896 
897  if ((p = strchr(stun_ip, ':'))) {
898  int iport;
899  *p++ = '\0';
900  iport = atoi(p);
901  if (iport > 0 && iport < 0xFFFF) {
902  stun_port = (switch_port_t)iport;
903  }
904  }
905 
906  switch_find_local_ip(ip_buf, sizeof(ip_buf), NULL, AF_INET);
907 
908  if (zstr(stun_ip)) {
909  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "STUN Failed! NO STUN SERVER\n");
910  }
911  else {
912  if ((switch_stun_lookup(&ip, &port, stun_ip, stun_port, &error, local_pool)) == SWITCH_STATUS_SUCCESS && ip && port) {
913  *external_ip = switch_core_strdup(external_pool, ip);
914  status = SWITCH_STATUS_SUCCESS;
915  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "External ip address detected using STUN: %s\n", ip);
916  }
917  else {
918  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "STUN Failed! [%s]\n", error);
919  }
920  }
921 
922  if (status != SWITCH_STATUS_SUCCESS) {
923  *external_ip = "";
924  }
925 
926  switch_core_destroy_memory_pool(&local_pool);
927  }
928  else {
929  *external_ip = switch_core_strdup(external_pool, sourceip);
930  status = SWITCH_STATUS_SUCCESS;
931  }
932 
933 end:
934 
935  return status;
936 }
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core&#39;s master pool.
Definition: switch_core.h:633
#define SWITCH_CHANNEL_LOG
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:733
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:642
char * switch_stun_host_lookup(const char *host, switch_memory_pool_t *pool)
Definition: switch_stun.c:699
#define zstr(x)
Definition: switch_utils.h:314
Definition: cJSON.c:68
#define SWITCH_STUN_DEFAULT_PORT
Definition: switch_stun.h:41
uint16_t switch_port_t
char * ip
Definition: switch_msrp.c:60
switch_status_t
Common return values.
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
switch_status_t switch_find_local_ip(_Out_opt_bytecapcount_(len) char *buf, _In_ int len, _In_opt_ int *mask, _In_ int family)
find local ip of the box
struct fspr_pool_t switch_memory_pool_t
#define switch_assert(expr)
switch_status_t switch_stun_lookup(char **ip, switch_port_t *port, char *stunip, switch_port_t stunport, char **err, switch_memory_pool_t *pool)
Perform a stun lookup.
Definition: switch_stun.c:712

◆ switch_stun_lookup()

switch_status_t switch_stun_lookup ( char **  ip,
switch_port_t port,
char *  stunip,
switch_port_t  stunport,
char **  err,
switch_memory_pool_t pool 
)

Perform a stun lookup.

Parameters
ipthe local ip to use (replaced with stun results)
portthe local port to use (replaced with stun results)
stunipthe ip of the stun server
stunportthe port of the stun server
erra pointer to describe errors
poolthe memory pool to use
Returns
SUCCESS or FAIL

Definition at line 712 of file switch_stun.c.

References switch_stun_ip_t::address, buf, switch_assert, switch_cond_next(), switch_core_strdup, switch_micro_time_now(), SWITCH_SHUTDOWN_READWRITE, SWITCH_SO_NONBLOCK, switch_sockaddr_info_get(), switch_socket_bind(), switch_socket_close(), switch_socket_create(), switch_socket_opt_set(), switch_socket_recvfrom(), switch_socket_sendto(), switch_socket_shutdown(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, SWITCH_STATUS_TIMEOUT, SWITCH_STUN_ATTR_MAPPED_ADDRESS, SWITCH_STUN_ATTR_USERNAME, SWITCH_STUN_ATTR_XOR_MAPPED_ADDRESS, switch_stun_attribute_padded_length, SWITCH_STUN_BINDING_REQUEST, SWITCH_STUN_BINDING_RESPONSE, switch_stun_packet_attribute_add_username(), switch_stun_packet_attribute_get_mapped_address(), switch_stun_packet_attribute_get_username(), switch_stun_packet_attribute_get_xor_mapped_address(), switch_stun_packet_build_header(), switch_stun_packet_first_attribute, switch_stun_packet_length, switch_stun_packet_next_attribute, switch_stun_packet_parse(), switch_stun_random_string(), SWITCH_UNSPEC, TRUE, switch_stun_packet_attribute_t::type, and switch_stun_packet_attribute_t::value.

Referenced by switch_core_media_ext_address_lookup(), and switch_stun_ip_lookup().

714 {
715  switch_sockaddr_t *local_addr = NULL, *remote_addr = NULL, *from_addr = NULL;
716  switch_socket_t *sock = NULL;
717  uint8_t buf[260] = { 0 };
718  uint8_t *start = buf;
719  void *end_buf;
720  switch_stun_packet_t *packet;
722  switch_size_t bytes = 0;
723  char username[33] = { 0 };
724  char rip[50] = { 0 };
725  uint16_t rport = 0;
726  switch_time_t started = 0;
727  int funny = 0;
728  int size = sizeof(buf);
729  int xlen = sizeof(switch_stun_packet_header_t);
730  switch_status_t res;
731 
732  switch_assert(err);
733 
734  if (*err && !strcmp(*err, "funny")) {
735  funny = 1;
736  }
737 
738  *err = "Success";
739 
740  res = switch_sockaddr_info_get(&from_addr, NULL, SWITCH_UNSPEC, 0, 0, pool);
741  (void)res;
742 
743  if (switch_sockaddr_info_get(&local_addr, *ip, SWITCH_UNSPEC, *port, 0, pool) != SWITCH_STATUS_SUCCESS) {
744  *err = "Local Address Error!";
745 
746  return SWITCH_STATUS_FALSE;
747  }
748 
749  if (switch_sockaddr_info_get(&remote_addr, stunip, SWITCH_UNSPEC, stunport, 0, pool) != SWITCH_STATUS_SUCCESS) {
750  *err = "Remote Address Error!";
751 
752  return SWITCH_STATUS_FALSE;
753  }
754 
755  if (switch_socket_create(&sock, AF_INET, SOCK_DGRAM, 0, pool) != SWITCH_STATUS_SUCCESS) {
756  *err = "Socket Error!";
757 
758  return SWITCH_STATUS_FALSE;
759  }
760 
761  if (switch_socket_bind(sock, local_addr) != SWITCH_STATUS_SUCCESS) {
762  *err = "Bind Error!";
763 
764  return SWITCH_STATUS_FALSE;
765  }
766 
767  if (funny) {
768  *start++ = 0;
769  *start++ = 0;
770  *start++ = 0x22;
771  *start++ = 0x22;
772  }
773 
776  switch_stun_random_string(username, 32, NULL);
777  switch_stun_packet_attribute_add_username(packet, username, 32);
778  bytes = switch_stun_packet_length(packet);
779 
780  if (funny) {
781  packet = (switch_stun_packet_t *) buf;
782  bytes += 4;
783  buf[bytes++] = 0;
784  buf[bytes++] = 0;
785  buf[bytes++] = 0;
786  buf[bytes++] = 0;
787  }
788 
789  switch_socket_sendto(sock, remote_addr, 0, (void *) packet, &bytes);
790  started = switch_micro_time_now();
791 
792  *ip = NULL;
793  *port = 0;
794 
795  for (;;) {
796  bytes = sizeof(buf);
797  if (switch_socket_recvfrom(from_addr, sock, 0, (char *) &buf, &bytes) == SWITCH_STATUS_SUCCESS && bytes > 0) {
798  break;
799  }
800 
801  if (((unsigned int)((switch_micro_time_now() - started) / 1000)) > 5000) {
802  *err = "Timeout";
804  switch_socket_close(sock);
805 
806  return SWITCH_STATUS_TIMEOUT;
807  }
809  }
810 
811  switch_socket_close(sock);
812 
813  if (funny) {
814  size -= 4;
815  }
816 
817  packet = switch_stun_packet_parse(start, size);
818  if (!packet) {
819  *err = "Invalid STUN/ICE packet";
820 
821  return SWITCH_STATUS_FALSE;
822  }
823 
824  end_buf = buf + ((sizeof(buf) > packet->header.length) ? packet->header.length : sizeof(buf));
825 
827  switch_assert(attr);
828 
829  do {
830  switch (attr->type) {
832  if (funny) {
833  switch_stun_ip_t *tmp = (switch_stun_ip_t *) attr->value;
834  tmp->address ^= ntohl(0xabcdabcd);
835  }
836 
837  switch_stun_packet_attribute_get_mapped_address(attr, rip, sizeof(rip), &rport);
838  break;
840  switch_stun_packet_attribute_get_xor_mapped_address(attr, &packet->header, rip, sizeof(rip), &rport);
841  break;
843  switch_stun_packet_attribute_get_username(attr, username, 32);
844  break;
845  }
846 
847  if (!switch_stun_packet_next_attribute(attr, end_buf)) {
848  break;
849  }
850 
851  xlen += 4 + switch_stun_attribute_padded_length(attr);
852 
853  } while (xlen <= packet->header.length);
854 
855  if (packet->header.type == SWITCH_STUN_BINDING_RESPONSE) {
856  *ip = switch_core_strdup(pool, rip);
857  *port = rport;
858 
859  return SWITCH_STATUS_SUCCESS;
860  } else {
861  *err = "Invalid Reply";
862  }
863 
864  return SWITCH_STATUS_FALSE;
865 }
switch_time_t switch_micro_time_now(void)
Get the current epoch time in microseconds.
Definition: switch_time.c:311
switch_status_t switch_socket_bind(switch_socket_t *sock, switch_sockaddr_t *sa)
Definition: switch_apr.c:742
uint32_t address
Definition: switch_stun.h:141
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:733
switch_memory_pool_t * pool
switch_status_t switch_socket_recvfrom(switch_sockaddr_t *from, switch_socket_t *sock, int32_t flags, char *buf, size_t *len)
Definition: switch_apr.c:1021
switch_stun_packet_t * switch_stun_packet_build_header(switch_stun_message_t type, char *id, uint8_t *buf)
Prepare a new outbound packet of a certian type and id.
Definition: switch_stun.c:442
uint8_t switch_stun_packet_attribute_add_username(switch_stun_packet_t *packet, char *username, uint16_t ulen)
Add a username packet attribute.
Definition: switch_stun.c:627
int64_t switch_time_t
Definition: switch_apr.h:188
switch_byte_t switch_byte_t * buf
void switch_stun_random_string(char *buf, uint16_t len, char *set)
Writes random characters into a buffer.
Definition: switch_stun.c:125
switch_status_t switch_socket_sendto(switch_socket_t *sock, switch_sockaddr_t *where, int32_t flags, const char *buf, switch_size_t *len)
Definition: switch_apr.c:796
#define switch_stun_packet_first_attribute(packet, attribute)
set a switch_stun_packet_attribute_t pointer to point at the first attribute in a packet ...
Definition: switch_stun.h:293
#define switch_stun_attribute_padded_length(attribute)
Obtain the padded length of an attribute&#39;s value.
Definition: switch_stun.h:284
#define switch_stun_packet_length(packet)
Obtain the correct length in bytes of a stun packet.
Definition: switch_stun.h:311
switch_status_t switch_socket_opt_set(switch_socket_t *sock, int32_t opt, int32_t on)
Definition: switch_apr.c:907
uintptr_t switch_size_t
void switch_cond_next(void)
Definition: switch_time.c:658
struct fspr_sockaddr_t switch_sockaddr_t
Definition: switch_apr.h:1029
switch_stun_packet_header_t header
Definition: switch_stun.h:133
char * ip
Definition: switch_msrp.c:60
#define switch_stun_packet_next_attribute(attribute, end)
Increment an attribute pointer to the next attribute in it&#39;s packet.
Definition: switch_stun.h:302
switch_status_t switch_socket_create(switch_socket_t **new_sock, int family, int type, int protocol, switch_memory_pool_t *pool)
Definition: switch_apr.c:727
char * switch_stun_packet_attribute_get_username(switch_stun_packet_attribute_t *attribute, char *username, uint16_t len)
Extract a username from a packet attribute.
Definition: switch_stun.c:434
switch_status_t
Common return values.
#define SWITCH_SO_NONBLOCK
Definition: switch_apr.h:994
switch_status_t switch_socket_close(switch_socket_t *sock)
Definition: switch_apr.c:737
#define SWITCH_UNSPEC
Definition: switch_apr.h:1022
switch_status_t switch_socket_shutdown(switch_socket_t *sock, switch_shutdown_how_e how)
Definition: switch_apr.c:732
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)
Definition: switch_stun.c:401
switch_stun_packet_t * switch_stun_packet_parse(uint8_t *buf, uint32_t len)
Prepare a raw packet for parsing.
Definition: switch_stun.c:144
#define TRUE
struct fspr_socket_t switch_socket_t
Definition: switch_apr.h:1026
#define switch_assert(expr)
switch_status_t switch_sockaddr_info_get(switch_sockaddr_t **sa, const char *hostname, int32_t family, switch_port_t port, int32_t flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:839
uint8_t switch_stun_packet_attribute_get_mapped_address(switch_stun_packet_attribute_t *attribute, char *ipstr, switch_size_t iplen, uint16_t *port)
Extract a mapped address (IP:PORT) from a packet attribute.
Definition: switch_stun.c:384

◆ switch_stun_packet_attribute_add_binded_address()

uint8_t switch_stun_packet_attribute_add_binded_address ( switch_stun_packet_t packet,
char *  ipstr,
uint16_t  port,
int  family 
)

Add a binded address packet attribute.

Parameters
packetthe packet to add the attribute to
ipstrthe string representation of the ip
portthe port of the mapped address
Returns
true or false

Definition at line 462 of file switch_stun.c.

References switch_stun_ip_t::address, switch_stun_ip_t::family, switch_stun_packet_t::first_attribute, switch_stun_packet_t::header, ip, switch_stun_packet_header_t::length, switch_stun_packet_attribute_t::length, switch_stun_ip_t::port, STUN_MAGIC_COOKIE, SWITCH_STUN_ATTR_XOR_MAPPED_ADDRESS, switch_stun_packet_attribute_t::type, and switch_stun_packet_attribute_t::value.

463 {
466 
467  attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length));
468  attribute->type = htons(SWITCH_STUN_ATTR_XOR_MAPPED_ADDRESS);
469 
470  if (family == AF_INET6) {
471  attribute->length = htons(20);
472  } else {
473  attribute->length = htons(8);
474  }
475 
476  ip = (switch_stun_ip_t *) attribute->value;
477 
478  ip->port = htons(port ^ (STUN_MAGIC_COOKIE >> 16));
479 
480  if (family == AF_INET6) {
481  ip->family = 2;
482  } else {
483  ip->family = 1;
484  }
485 
486  if (family == AF_INET6) {
487  inet_pton(AF_INET6, ipstr, (struct in6_addr *) &ip->address);
488  } else {
489  inet_pton(AF_INET, ipstr, (int *) &ip->address);
490  }
491 
492  packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length;
493  return 1;
494 }
#define STUN_MAGIC_COOKIE
Definition: switch_stun.h:60
uint32_t address
Definition: switch_stun.h:141
uint8_t first_attribute[]
Definition: switch_stun.h:134
switch_stun_packet_header_t header
Definition: switch_stun.h:133
char * ip
Definition: switch_msrp.c:60

◆ switch_stun_packet_attribute_add_controlled()

uint8_t switch_stun_packet_attribute_add_controlled ( switch_stun_packet_t packet)

Definition at line 611 of file switch_stun.c.

References buf, switch_stun_packet_t::first_attribute, switch_stun_packet_t::header, switch_stun_packet_header_t::length, switch_stun_packet_attribute_t::length, SWITCH_STUN_ATTR_CONTROLLED, switch_stun_random_string(), switch_stun_packet_attribute_t::type, and switch_stun_packet_attribute_t::value.

Referenced by ice_out().

612 {
614  char buf[8];
615 
616  switch_stun_random_string(buf, 8, NULL);
617 
618  attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length));
619  attribute->type = htons(SWITCH_STUN_ATTR_CONTROLLED);
620  attribute->length = htons(8);
621  memcpy(attribute->value, buf, 8);
622  packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length;
623  return 1;
624 }
switch_byte_t switch_byte_t * buf
void switch_stun_random_string(char *buf, uint16_t len, char *set)
Writes random characters into a buffer.
Definition: switch_stun.c:125
uint8_t first_attribute[]
Definition: switch_stun.h:134
switch_stun_packet_header_t header
Definition: switch_stun.h:133

◆ switch_stun_packet_attribute_add_controlling()

uint8_t switch_stun_packet_attribute_add_controlling ( switch_stun_packet_t packet)

Definition at line 596 of file switch_stun.c.

References buf, switch_stun_packet_t::first_attribute, switch_stun_packet_t::header, switch_stun_packet_header_t::length, switch_stun_packet_attribute_t::length, SWITCH_STUN_ATTR_CONTROLLING, switch_stun_random_string(), switch_stun_packet_attribute_t::type, and switch_stun_packet_attribute_t::value.

Referenced by ice_out().

597 {
599  char buf[8];
600 
601  switch_stun_random_string(buf, 8, NULL);
602 
603  attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length));
604  attribute->type = htons(SWITCH_STUN_ATTR_CONTROLLING);
605  attribute->length = htons(8);
606  memcpy(attribute->value, buf, 8);
607  packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length;
608  return 1;
609 }
switch_byte_t switch_byte_t * buf
void switch_stun_random_string(char *buf, uint16_t len, char *set)
Writes random characters into a buffer.
Definition: switch_stun.c:125
uint8_t first_attribute[]
Definition: switch_stun.h:134
switch_stun_packet_header_t header
Definition: switch_stun.h:133

◆ switch_stun_packet_attribute_add_fingerprint()

uint8_t switch_stun_packet_attribute_add_fingerprint ( switch_stun_packet_t packet)

Definition at line 563 of file switch_stun.c.

References switch_stun_packet_t::first_attribute, switch_stun_packet_t::header, switch_stun_packet_header_t::length, switch_stun_packet_attribute_t::length, switch_crc32_8bytes(), SWITCH_STUN_ATTR_FINGERPRINT, switch_stun_packet_attribute_t::type, and switch_stun_packet_attribute_t::value.

Referenced by handle_ice(), and ice_out().

564 {
566  uint32_t crc;
567  uint16_t xlen;
568 
569  attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length));
570  attribute->type = htons(SWITCH_STUN_ATTR_FINGERPRINT);
571  attribute->length = htons(4);
572 
573  xlen = ntohs(packet->header.length) + sizeof(switch_stun_packet_header_t);
574 
575  packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length;
576 
577  crc = htonl(switch_crc32_8bytes(packet, xlen) ^ 0x5354554e);
578 
579  memcpy(attribute->value, &crc, 4);
580 
581  return 1;
582 }
uint32_t switch_crc32_8bytes(const void *data, size_t length)
Definition: switch_stun.c:1232
uint8_t first_attribute[]
Definition: switch_stun.h:134
switch_stun_packet_header_t header
Definition: switch_stun.h:133

◆ switch_stun_packet_attribute_add_integrity()

uint8_t switch_stun_packet_attribute_add_integrity ( switch_stun_packet_t packet,
const char *  pass 
)

Definition at line 546 of file switch_stun.c.

References switch_stun_packet_t::first_attribute, switch_stun_packet_t::header, switch_stun_packet_header_t::length, switch_stun_packet_attribute_t::length, SWITCH_STUN_ATTR_MESSAGE_INTEGRITY, switch_stun_packet_attribute_t::type, and switch_stun_packet_attribute_t::value.

Referenced by handle_ice(), and ice_out().

547 {
549  uint16_t xlen;
550 
551  attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length));
552  attribute->type = htons(SWITCH_STUN_ATTR_MESSAGE_INTEGRITY);
553  attribute->length = htons(20);
554 
555  xlen = ntohs(packet->header.length) + sizeof(switch_stun_packet_header_t);
556  packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length;
557 
558  HMAC(EVP_sha1(), (unsigned char *)pass, (int)strlen(pass), (void *)packet, xlen, (void *)attribute->value, NULL);
559 
560  return 1;
561 }
uint8_t first_attribute[]
Definition: switch_stun.h:134
switch_stun_packet_header_t header
Definition: switch_stun.h:133

◆ switch_stun_packet_attribute_add_password()

uint8_t switch_stun_packet_attribute_add_password ( switch_stun_packet_t packet,
char *  password,
uint16_t  ulen 
)

Definition at line 675 of file switch_stun.c.

References switch_stun_packet_t::first_attribute, switch_stun_packet_t::header, switch_stun_packet_header_t::length, switch_stun_packet_attribute_t::length, SWITCH_STUN_ATTR_PASSWORD, switch_stun_random_string(), switch_stun_packet_attribute_t::type, and switch_stun_packet_attribute_t::value.

676 {
678  int m = ulen % 4;
679  int padding = 0;
680 
681  if (m) {
682  padding = 4 - m;
683  }
684 
685  attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length));
686  attribute->type = htons(SWITCH_STUN_ATTR_PASSWORD);
687  attribute->length = htons(ulen);
688  if (password) {
689  memcpy(attribute->value, password, ulen);
690  } else {
691  switch_stun_random_string(attribute->value, ulen, NULL);
692  }
693 
694  packet->header.length += htons((u_short)(sizeof(switch_stun_packet_attribute_t) + padding)) + attribute->length;
695 
696  return 1;
697 }
void switch_stun_random_string(char *buf, uint16_t len, char *set)
Writes random characters into a buffer.
Definition: switch_stun.c:125
uint8_t first_attribute[]
Definition: switch_stun.h:134
switch_stun_packet_header_t header
Definition: switch_stun.h:133

◆ switch_stun_packet_attribute_add_priority()

uint8_t switch_stun_packet_attribute_add_priority ( switch_stun_packet_t packet,
uint32_t  priority 
)

Definition at line 532 of file switch_stun.c.

References switch_stun_packet_t::first_attribute, switch_stun_packet_t::header, switch_stun_packet_header_t::length, switch_stun_packet_attribute_t::length, SWITCH_STUN_ATTR_PRIORITY, switch_stun_packet_attribute_t::type, and switch_stun_packet_attribute_t::value.

Referenced by ice_out().

533 {
535 
536  priority = htonl(priority);
537  attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length));
538  attribute->type = htons(SWITCH_STUN_ATTR_PRIORITY);
539  attribute->length = htons(4);
540  memcpy(attribute->value, &priority, 4);
541 
542  packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length;
543  return 1;
544 }
uint8_t first_attribute[]
Definition: switch_stun.h:134
switch_stun_packet_header_t header
Definition: switch_stun.h:133

◆ switch_stun_packet_attribute_add_software()

uint8_t switch_stun_packet_attribute_add_software ( switch_stun_packet_t packet,
char *  software,
uint16_t  ulen 
)

Definition at line 651 of file switch_stun.c.

References switch_stun_packet_t::first_attribute, switch_stun_packet_t::header, switch_stun_packet_header_t::length, switch_stun_packet_attribute_t::length, SWITCH_STUN_ATTR_SOFTWARE, switch_stun_random_string(), switch_stun_packet_attribute_t::type, and switch_stun_packet_attribute_t::value.

Referenced by ice_out().

652 {
654  int m = ulen % 4;
655  int padding = 0;
656 
657  if (m) {
658  padding = 4 - m;
659  }
660 
661  attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length));
662  attribute->type = htons(SWITCH_STUN_ATTR_SOFTWARE);
663  attribute->length = htons(ulen);
664  if (software) {
665  memcpy(attribute->value, software, ulen);
666  } else {
667  switch_stun_random_string(attribute->value, ulen, NULL);
668  }
669 
670  packet->header.length += htons((u_short)(sizeof(switch_stun_packet_attribute_t) + padding)) + attribute->length;
671 
672  return 1;
673 }
void switch_stun_random_string(char *buf, uint16_t len, char *set)
Writes random characters into a buffer.
Definition: switch_stun.c:125
uint8_t first_attribute[]
Definition: switch_stun.h:134
switch_stun_packet_header_t header
Definition: switch_stun.h:133

◆ switch_stun_packet_attribute_add_use_candidate()

uint8_t switch_stun_packet_attribute_add_use_candidate ( switch_stun_packet_t packet)

Definition at line 585 of file switch_stun.c.

References switch_stun_packet_t::first_attribute, switch_stun_packet_t::header, switch_stun_packet_header_t::length, switch_stun_packet_attribute_t::length, SWITCH_STUN_ATTR_USE_CAND, and switch_stun_packet_attribute_t::type.

Referenced by ice_out().

586 {
588 
589  attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length));
590  attribute->type = htons(SWITCH_STUN_ATTR_USE_CAND);
591  attribute->length = htons(0);
592  packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length;
593  return 1;
594 }
uint8_t first_attribute[]
Definition: switch_stun.h:134
switch_stun_packet_header_t header
Definition: switch_stun.h:133

◆ switch_stun_packet_attribute_add_username()

uint8_t switch_stun_packet_attribute_add_username ( switch_stun_packet_t packet,
char *  username,
uint16_t  ulen 
)

Add a username packet attribute.

Parameters
packetthe packet to add the attribute to
usernamethe string representation of the username
ulenthe length of the username
Returns
true or false

Definition at line 627 of file switch_stun.c.

References switch_stun_packet_t::first_attribute, switch_stun_packet_t::header, switch_stun_packet_header_t::length, switch_stun_packet_attribute_t::length, SWITCH_STUN_ATTR_USERNAME, switch_stun_random_string(), switch_stun_packet_attribute_t::type, and switch_stun_packet_attribute_t::value.

Referenced by handle_ice(), ice_out(), and switch_stun_lookup().

628 {
630  int m = ulen % 4;
631  int padding = 0;
632 
633  if (m) {
634  padding = 4 - m;
635  }
636 
637  attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length));
638  attribute->type = htons(SWITCH_STUN_ATTR_USERNAME);
639  attribute->length = htons(ulen);
640  if (username) {
641  memcpy(attribute->value, username, ulen);
642  } else {
643  switch_stun_random_string(attribute->value, ulen, NULL);
644  }
645 
646  packet->header.length += htons((u_short)(sizeof(switch_stun_packet_attribute_t) + padding)) + attribute->length;
647 
648  return 1;
649 }
void switch_stun_random_string(char *buf, uint16_t len, char *set)
Writes random characters into a buffer.
Definition: switch_stun.c:125
uint8_t first_attribute[]
Definition: switch_stun.h:134
switch_stun_packet_header_t header
Definition: switch_stun.h:133

◆ switch_stun_packet_attribute_add_xor_binded_address()

uint8_t switch_stun_packet_attribute_add_xor_binded_address ( switch_stun_packet_t packet,
char *  ipstr,
uint16_t  port,
int  family 
)

Definition at line 496 of file switch_stun.c.

References switch_stun_ip_t::address, switch_stun_ip_t::family, switch_stun_packet_t::first_attribute, switch_stun_packet_t::header, switch_stun_packet_header_t::id, ip, switch_stun_packet_header_t::length, switch_stun_packet_attribute_t::length, switch_stun_ip_t::port, STUN_MAGIC_COOKIE, SWITCH_STUN_ATTR_XOR_MAPPED_ADDRESS, switch_stun_packet_attribute_t::type, v6_xor(), and switch_stun_packet_attribute_t::value.

Referenced by handle_ice().

497 {
500 
501  attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length));
502  attribute->type = htons(SWITCH_STUN_ATTR_XOR_MAPPED_ADDRESS);
503 
504  if (family == AF_INET6) {
505  attribute->length = htons(20);
506  } else {
507  attribute->length = htons(8);
508  }
509 
510  ip = (switch_stun_ip_t *) attribute->value;
511 
512  ip->port = htons(port ^ (STUN_MAGIC_COOKIE >> 16));
513 
514  if (family == AF_INET6) {
515  ip->family = 2;
516  } else {
517  ip->family = 1;
518  }
519 
520  if (family == AF_INET6) {
521  inet_pton(AF_INET6, ipstr, (struct in6_addr *) &ip->address);
522  v6_xor((uint8_t *)&ip->address, (uint8_t *)packet->header.id);
523  } else {
524  inet_pton(AF_INET, ipstr, (int *) &ip->address);
525  ip->address = htonl(ntohl(ip->address) ^ STUN_MAGIC_COOKIE);
526  }
527 
528  packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length;
529  return 1;
530 }
#define STUN_MAGIC_COOKIE
Definition: switch_stun.h:60
uint32_t address
Definition: switch_stun.h:141
uint8_t first_attribute[]
Definition: switch_stun.h:134
switch_stun_packet_header_t header
Definition: switch_stun.h:133
char * ip
Definition: switch_msrp.c:60
static void v6_xor(uint8_t *addr, const uint8_t *transaction_id)
Definition: switch_stun.c:110

◆ switch_stun_packet_attribute_get_mapped_address()

uint8_t switch_stun_packet_attribute_get_mapped_address ( switch_stun_packet_attribute_t attribute,
char *  ipstr,
switch_size_t  iplen,
uint16_t *  port 
)

Extract a mapped address (IP:PORT) from a packet attribute.

Parameters
attributethe attribute from which to extract
ipstra buffer to write the string representation of the ip
portthe port
Returns
true or false

Definition at line 384 of file switch_stun.c.

References switch_stun_ip_t::address, ip, switch_stun_ip_t::port, and switch_stun_packet_attribute_t::value.

Referenced by handle_ice(), and switch_stun_lookup().

385 {
387  uint8_t x, *i;
388  char *p = ipstr;
389 
390  ip = (switch_stun_ip_t *) attribute->value;
391  i = (uint8_t *) & ip->address;
392  *ipstr = 0;
393  for (x = 0; x < 4; x++) {
394  sprintf(p, "%u%s", i[x], x == 3 ? "" : ".");
395  p = ipstr + strlen(ipstr);
396  }
397  *port = ip->port;
398  return 1;
399 }
uint32_t address
Definition: switch_stun.h:141
char * ip
Definition: switch_msrp.c:60

◆ switch_stun_packet_attribute_get_username()

char* switch_stun_packet_attribute_get_username ( switch_stun_packet_attribute_t attribute,
char *  username,
uint16_t  len 
)

Extract a username from a packet attribute.

Parameters
attributethe attribute from which to extract
usernamea buffer to write the string representation of the username
lenthe maximum size of the username buffer
Returns
a pointer to the username or NULL

Definition at line 434 of file switch_stun.c.

References switch_stun_packet_attribute_t::length, and switch_stun_packet_attribute_t::value.

Referenced by handle_ice(), and switch_stun_lookup().

435 {
436  uint16_t cpylen;
437 
438  cpylen = attribute->length < len ? attribute->length : len;
439  return memcpy(username, attribute->value, cpylen);
440 }

◆ switch_stun_packet_attribute_get_xor_mapped_address()

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 
)

Definition at line 401 of file switch_stun.c.

References switch_stun_ip_t::address, switch_stun_ipv6_t::address, switch_stun_packet_header_t::cookie, switch_stun_ip_t::family, switch_stun_packet_header_t::id, if(), ip, switch_stun_ip_t::port, v6_xor(), and switch_stun_packet_attribute_t::value.

Referenced by handle_ice(), and switch_stun_lookup().

402 {
404  switch_stun_ipv6_t *ipv6;
405  uint8_t x, *i;
406  char *p = ipstr;
407 
408  ip = (switch_stun_ip_t *) attribute->value;
409 
410  if (ip->family == 2) {
411  uint8_t *v6addr;
412 
413  ipv6 = (switch_stun_ipv6_t *)attribute->value;
414  v6addr = (uint8_t *) &ipv6->address;
415  v6_xor(v6addr, (uint8_t *)header->id);
416  inet_ntop(AF_INET6, v6addr, ipstr, iplen);
417  } else {
418  ip->address ^= header->cookie;
419 
420  i = (uint8_t *) & ip->address;
421  *ipstr = 0;
422  for (x = 0; x < 4; x++) {
423  sprintf(p, "%u%s", i[x], x == 3 ? "" : ".");
424  p = ipstr + strlen(ipstr);
425  }
426  }
427 
428  ip->port ^= ntohl(header->cookie) >> 16;
429  *port = ip->port;
430 
431  return 1;
432 }
uint32_t address
Definition: switch_stun.h:141
uint8_t address[16]
Definition: switch_stun.h:148
if((uint32_t)(unpack->cur - unpack->buf) > unpack->buflen)
char * ip
Definition: switch_msrp.c:60
static void v6_xor(uint8_t *addr, const uint8_t *transaction_id)
Definition: switch_stun.c:110

◆ switch_stun_packet_build_header()

switch_stun_packet_t* switch_stun_packet_build_header ( switch_stun_message_t  type,
char *  id,
uint8_t *  buf 
)

Prepare a new outbound packet of a certian type and id.

Parameters
idid to use (NULL for an auto generated id)
typethe stun packet type
bufa pointer to data to use for the packet
Returns
a pointer to a ready-to-use stun packet

Definition at line 442 of file switch_stun.c.

References buf, switch_stun_packet_header_t::cookie, switch_stun_packet_header_t::id, switch_stun_packet_header_t::length, STUN_MAGIC_COOKIE, switch_stun_random_string(), and switch_stun_packet_header_t::type.

Referenced by handle_ice(), ice_out(), and switch_stun_lookup().

443 {
445 
446 
447  header = (switch_stun_packet_header_t *) buf;
448  header->type = htons(type);
449  header->length = 0;
450  header->cookie = htonl(STUN_MAGIC_COOKIE);
451 
452  if (id) {
453  memcpy(header->id, id, 12);
454  } else {
455  switch_stun_random_string(header->id, 12, NULL);
456  }
457 
458  return (switch_stun_packet_t *) buf;
459 }
#define STUN_MAGIC_COOKIE
Definition: switch_stun.h:60
switch_byte_t switch_byte_t * buf
void switch_stun_random_string(char *buf, uint16_t len, char *set)
Writes random characters into a buffer.
Definition: switch_stun.c:125

◆ switch_stun_packet_parse()

switch_stun_packet_t* switch_stun_packet_parse ( uint8_t *  buf,
uint32_t  len 
)

Prepare a raw packet for parsing.

Parameters
bufthe raw data
lenthe length of the data
Returns
a stun packet pointer to buf to use as an access point

Definition at line 144 of file switch_stun.c.

References switch_stun_ip_t::family, switch_stun_packet_t::header, if(), ip, switch_stun_packet_header_t::length, switch_stun_packet_attribute_t::length, switch_stun_ip_t::port, SWITCH_STUN_ALLOCATE_ERROR_RESPONSE, SWITCH_STUN_ALLOCATE_REQUEST, SWITCH_STUN_ALLOCATE_RESPONSE, SWITCH_STUN_ATTR_ALTERNATE_SERVER, SWITCH_STUN_ATTR_BANDWIDTH, SWITCH_STUN_ATTR_CHANGE_REQUEST, SWITCH_STUN_ATTR_CHANGED_ADDRESS, SWITCH_STUN_ATTR_DATA, SWITCH_STUN_ATTR_DESTINATION_ADDRESS, SWITCH_STUN_ATTR_ERROR_CODE, SWITCH_STUN_ATTR_LIFETIME, SWITCH_STUN_ATTR_MAGIC_COOKIE, SWITCH_STUN_ATTR_MAPPED_ADDRESS, SWITCH_STUN_ATTR_MESSAGE_INTEGRITY, SWITCH_STUN_ATTR_OPTIONS, SWITCH_STUN_ATTR_PASSWORD, SWITCH_STUN_ATTR_PRIORITY, SWITCH_STUN_ATTR_REFLECTED_FROM, SWITCH_STUN_ATTR_RESPONSE_ADDRESS, SWITCH_STUN_ATTR_SOFTWARE, SWITCH_STUN_ATTR_SOURCE_ADDRESS, SWITCH_STUN_ATTR_SOURCE_ADDRESS2, SWITCH_STUN_ATTR_TRANSPORT_PREFERENCES, SWITCH_STUN_ATTR_UNKNOWN_ATTRIBUTES, SWITCH_STUN_ATTR_USERNAME, SWITCH_STUN_ATTR_XOR_MAPPED_ADDRESS, SWITCH_STUN_ATTRIBUTE_MIN_LEN, switch_stun_attribute_padded_length, SWITCH_STUN_BINDING_ERROR_RESPONSE, SWITCH_STUN_BINDING_REQUEST, SWITCH_STUN_BINDING_RESPONSE, SWITCH_STUN_DATA_INDICATION, switch_stun_packet_first_attribute, SWITCH_STUN_PACKET_MIN_LEN, SWITCH_STUN_SEND_ERROR_RESPONSE, SWITCH_STUN_SEND_REQUEST, SWITCH_STUN_SEND_RESPONSE, SWITCH_STUN_SHARED_SECRET_ERROR_RESPONSE, SWITCH_STUN_SHARED_SECRET_REQUEST, SWITCH_STUN_SHARED_SECRET_RESPONSE, switch_stun_packet_header_t::type, switch_stun_packet_attribute_t::type, and switch_stun_packet_attribute_t::value.

Referenced by handle_ice(), and switch_stun_lookup().

145 {
146  switch_stun_packet_t *packet;
148  uint32_t bytes_left = len;
149  void *end_buf = buf + len;
150  int xlen = 0;
151 
152  if (len < SWITCH_STUN_PACKET_MIN_LEN) {
153  return NULL;
154  }
155 
156  packet = (switch_stun_packet_t *) buf;
157  packet->header.type = ntohs(packet->header.type);
158  packet->header.length = ntohs(packet->header.length);
159  if (packet->header.length > (bytes_left -= 20)) return NULL;
160 
161  /*
162  * Check packet type (RFC3489(bis?) values)
163  */
164  switch (packet->header.type) {
178  /* Valid */
179  break;
180 
181  default:
182  /* Invalid value */
183  return NULL;
184  }
185 
186  /*
187  * Check for length overflow
188  */
189  if (bytes_left <= 0) {
190  /* Invalid */
191  return NULL;
192  }
193 
194  /*
195  * No payload?
196  */
197  if (packet->header.length == 0) {
198  /* Invalid?! */
199  return NULL;
200  }
201 
202  /* check if we have enough bytes left for an attribute */
203  if (bytes_left < SWITCH_STUN_ATTRIBUTE_MIN_LEN) {
204  return NULL;
205  }
206 
208  do {
209  int16_t alen;
210 
211  if (bytes_left < 4) return NULL;
212 
213  attr->length = ntohs(attr->length);
214  attr->type = ntohs(attr->type);
215  bytes_left -= 4; /* attribute header consumed */
216 
218 
219  if (alen > (int)bytes_left || alen < 0) {
220  /*
221  * Note we simply don't "break" here out of the loop anymore because
222  * we don't want the upper layers to have to deal with attributes without a value
223  * (or worse: invalid length)
224  */
225  return NULL;
226  }
227 
228  /*
229  * Handle STUN attributes
230  */
231  switch (attr->type) {
232  case SWITCH_STUN_ATTR_MAPPED_ADDRESS: /* Address, we only care about this one, but parse the others too */
241  {
243  ip->port = ntohs(ip->port);
244  }
245  break;
247  {
249  uint32_t addr_length = 0;
250  ip = (switch_stun_ip_t *) attr->value;
251 
252  switch (ip->family) {
253  case 0x01: /* IPv4 */
254  addr_length = 4;
255  break;
256 
257  case 0x02: /* IPv6 */
258  addr_length = 16;
259  break;
260 
261  default: /* Invalid */
262  return NULL;
263  }
264 
265  /* attribute payload length must be == address length + size of other payload fields (family...) */
266  if (attr->length != addr_length + 4) {
267  /* Invalid */
268  return NULL;
269  }
270 
271  ip->port = ntohs(ip->port);
272  }
273  break;
274 
275  case SWITCH_STUN_ATTR_CHANGE_REQUEST: /* UInt32 */
279  {
280  uint32_t *val = (uint32_t *) attr->value;
281 
282  if (attr->length != sizeof(uint32_t)) {
283  /* Invalid */
284  return NULL;
285  }
286 
287  *val = ntohl(*val); /* should we do this here? */
288  }
289  break;
290  case SWITCH_STUN_ATTR_ERROR_CODE: /* ErrorCode */
291  {
292  uint32_t *u = (uint32_t *) attr->value;
293  *u = htonl(*u);
294  }
295  break;
296 
298  case SWITCH_STUN_ATTR_USERNAME: /* ByteString, multiple of 4 bytes */
299  case SWITCH_STUN_ATTR_PASSWORD: /* ByteString, multiple of 4 bytes */
300  case SWITCH_STUN_ATTR_DATA: /* ByteString */
301  case SWITCH_STUN_ATTR_TRANSPORT_PREFERENCES: /* TransportPrefs */
302  /*
303  * No length checking here, since we already checked against the padded length
304  * before
305  */
306  break;
307 
308  case SWITCH_STUN_ATTR_MESSAGE_INTEGRITY: /* ByteString, 20 bytes */
309  if (attr->length != 20) {
310  /* Invalid */
311  return NULL;
312  }
313  break;
314 
315  case SWITCH_STUN_ATTR_MAGIC_COOKIE: /* ByteString, 4 bytes */
316  if (attr->length != 4) {
317  /* Invalid */
318  return NULL;
319  }
320  break;
321 
322  case SWITCH_STUN_ATTR_UNKNOWN_ATTRIBUTES: /* UInt16List (= multiple of 2 bytes) */
323  if (attr->length % 2 != 0) {
324  return NULL;
325  }
326  break;
327 
328  default:
329  break;
330  }
331 
332  bytes_left -= alen; /* attribute value consumed, substract padded length */
333 
334  xlen += 4 + alen;
335 
336  attr = (switch_stun_packet_attribute_t *) (attr->value + alen);
337  if ((void *)attr > end_buf) {
338  break;
339  }
340  } while (xlen < packet->header.length);
341 
342  if ((uint32_t) (packet->header.length + 20) > (uint32_t) (len - bytes_left)) {
343  /*
344  * the packet length is longer than the length of all attributes?
345  * for now simply decrease the packet size
346  */
347  packet->header.length = (uint16_t) ((len - bytes_left) - 20);
348  }
349 
350  return packet;
351 }
#define SWITCH_STUN_PACKET_MIN_LEN
Definition: switch_stun.h:42
switch_byte_t switch_byte_t * buf
if((uint32_t)(unpack->cur - unpack->buf) > unpack->buflen)
#define switch_stun_packet_first_attribute(packet, attribute)
set a switch_stun_packet_attribute_t pointer to point at the first attribute in a packet ...
Definition: switch_stun.h:293
#define switch_stun_attribute_padded_length(attribute)
Obtain the padded length of an attribute&#39;s value.
Definition: switch_stun.h:284
switch_stun_packet_header_t header
Definition: switch_stun.h:133
char * ip
Definition: switch_msrp.c:60
#define SWITCH_STUN_ATTRIBUTE_MIN_LEN
Definition: switch_stun.h:43

◆ switch_stun_random_string()

void switch_stun_random_string ( char *  buf,
uint16_t  len,
char *  set 
)

Writes random characters into a buffer.

Parameters
bufthe buffer
lenthe length of the data
setthe set of chars to use (NULL for auto)

Definition at line 125 of file switch_stun.c.

References switch_rand(), and SWITCH_RAND_MAX.

Referenced by gen_ice(), generate_m(), random_string(), switch_core_media_gen_local_sdp(), switch_rtp_get_random(), switch_stun_lookup(), switch_stun_packet_attribute_add_controlled(), switch_stun_packet_attribute_add_controlling(), switch_stun_packet_attribute_add_password(), switch_stun_packet_attribute_add_software(), switch_stun_packet_attribute_add_username(), and switch_stun_packet_build_header().

126 {
127  char chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
128  int max;
129  uint16_t x;
130 
131  if (!set) {
132  set = chars;
133  }
134 
135  max = (int) strlen(set);
136 
137  for (x = 0; x < len; x++) {
138  int j = (int) (max * 1.0 * switch_rand() / (SWITCH_RAND_MAX + 1.0));
139  buf[x] = set[j];
140  }
141 }
switch_byte_t switch_byte_t * buf
int switch_rand(void)
#define SWITCH_RAND_MAX
Definition: switch_types.h:606

◆ switch_stun_value_to_name()

const char* switch_stun_value_to_name ( int32_t  type,
uint32_t  value 
)

Obtain a printable string form of a given value.

Parameters
typethe type of message
valuethe value to look up
Returns
a sring version of value

Definition at line 354 of file switch_stun.c.

References ATTR_TYPES, ERROR_TYPES, value_mapping::name, PACKET_TYPES, SWITCH_STUN_TYPE_ATTRIBUTE, SWITCH_STUN_TYPE_ERROR, SWITCH_STUN_TYPE_PACKET_TYPE, and value_mapping::value.

Referenced by handle_ice().

355 {
356  uint32_t x = 0;
357  const struct value_mapping *map = NULL;
358  switch (type) {
360  map = PACKET_TYPES;
361  break;
363  map = ATTR_TYPES;
364  break;
366  map = ERROR_TYPES;
367  break;
368  default:
369  map = NULL;
370  break;
371  }
372 
373  if (map) {
374  for (x = 0; map[x].value; x++) {
375  if (map[x].value == value) {
376  return map[x].name;
377  }
378  }
379  }
380 
381  return "INVALID";
382 }
const char *const const char *const const cJSON *const value
static const struct value_mapping ERROR_TYPES[]
Definition: switch_stun.c:97
const char * name
Definition: switch_stun.c:41
static const struct value_mapping PACKET_TYPES[]
Definition: switch_stun.c:44
static const struct value_mapping ATTR_TYPES[]
Definition: switch_stun.c:61
const uint32_t value
Definition: switch_stun.c:40