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_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 277 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 278 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 286 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 304 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 295 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 297 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 1228 of file switch_stun.c.

References crc32Lookup.

Referenced by switch_stun_packet_attribute_add_fingerprint().

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

696 {
697  switch_sockaddr_t *addr = NULL;
698  char buf[30];
699  switch_status_t res;
700 
701  res = switch_sockaddr_info_get(&addr, host, SWITCH_UNSPEC, 0, 0, pool);
702  (void)res;
703 
704  return switch_core_strdup(pool, switch_str_nil(switch_get_addr(buf, sizeof(buf), addr)));
705 
706 }
#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 863 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().

864 {
866  char *stun_ip = NULL;
868  char *p;
869  char ip_buf[256] = "";
870  char *ip = NULL;
871  switch_port_t port = 0;
872  switch_memory_pool_t *local_pool = NULL;
873  char *error = "";
874 
875  if (!sourceip || !external_pool) {
876  *external_ip = NULL;
877  goto end;
878  }
879 
880  ip = ip_buf;
881 
882  if (!strncasecmp(sourceip, "host:", 5)) {
883  status = (*external_ip = switch_stun_host_lookup(sourceip + 5, external_pool)) ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
884  }
885  else if (!strncasecmp(sourceip, "stun:", 5)) {
886 
887  switch_core_new_memory_pool(&local_pool);
888 
889  stun_ip = switch_core_strdup(local_pool, sourceip + 5);
890 
891  switch_assert(stun_ip);
892 
893  if ((p = strchr(stun_ip, ':'))) {
894  int iport;
895  *p++ = '\0';
896  iport = atoi(p);
897  if (iport > 0 && iport < 0xFFFF) {
898  stun_port = (switch_port_t)iport;
899  }
900  }
901 
902  switch_find_local_ip(ip_buf, sizeof(ip_buf), NULL, AF_INET);
903 
904  if (zstr(stun_ip)) {
905  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "STUN Failed! NO STUN SERVER\n");
906  }
907  else {
908  if ((switch_stun_lookup(&ip, &port, stun_ip, stun_port, &error, local_pool)) == SWITCH_STATUS_SUCCESS && ip && port) {
909  *external_ip = switch_core_strdup(external_pool, ip);
910  status = SWITCH_STATUS_SUCCESS;
911  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "External ip address detected using STUN: %s\n", ip);
912  }
913  else {
914  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "STUN Failed! [%s]\n", error);
915  }
916  }
917 
918  if (status != SWITCH_STATUS_SUCCESS) {
919  *external_ip = "";
920  }
921 
922  switch_core_destroy_memory_pool(&local_pool);
923  }
924  else {
925  *external_ip = switch_core_strdup(external_pool, sourceip);
926  status = SWITCH_STATUS_SUCCESS;
927  }
928 
929 end:
930 
931  return status;
932 }
#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:695
#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:708

◆ 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 708 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().

710 {
711  switch_sockaddr_t *local_addr = NULL, *remote_addr = NULL, *from_addr = NULL;
712  switch_socket_t *sock = NULL;
713  uint8_t buf[260] = { 0 };
714  uint8_t *start = buf;
715  void *end_buf;
716  switch_stun_packet_t *packet;
718  switch_size_t bytes = 0;
719  char username[33] = { 0 };
720  char rip[50] = { 0 };
721  uint16_t rport = 0;
722  switch_time_t started = 0;
723  int funny = 0;
724  int size = sizeof(buf);
725  int xlen = sizeof(switch_stun_packet_header_t);
726  switch_status_t res;
727 
728  switch_assert(err);
729 
730  if (*err && !strcmp(*err, "funny")) {
731  funny = 1;
732  }
733 
734  *err = "Success";
735 
736  res = switch_sockaddr_info_get(&from_addr, NULL, SWITCH_UNSPEC, 0, 0, pool);
737  (void)res;
738 
739  if (switch_sockaddr_info_get(&local_addr, *ip, SWITCH_UNSPEC, *port, 0, pool) != SWITCH_STATUS_SUCCESS) {
740  *err = "Local Address Error!";
741 
742  return SWITCH_STATUS_FALSE;
743  }
744 
745  if (switch_sockaddr_info_get(&remote_addr, stunip, SWITCH_UNSPEC, stunport, 0, pool) != SWITCH_STATUS_SUCCESS) {
746  *err = "Remote Address Error!";
747 
748  return SWITCH_STATUS_FALSE;
749  }
750 
751  if (switch_socket_create(&sock, AF_INET, SOCK_DGRAM, 0, pool) != SWITCH_STATUS_SUCCESS) {
752  *err = "Socket Error!";
753 
754  return SWITCH_STATUS_FALSE;
755  }
756 
757  if (switch_socket_bind(sock, local_addr) != SWITCH_STATUS_SUCCESS) {
758  *err = "Bind Error!";
759 
760  return SWITCH_STATUS_FALSE;
761  }
762 
763  if (funny) {
764  *start++ = 0;
765  *start++ = 0;
766  *start++ = 0x22;
767  *start++ = 0x22;
768  }
769 
772  switch_stun_random_string(username, 32, NULL);
773  switch_stun_packet_attribute_add_username(packet, username, 32);
774  bytes = switch_stun_packet_length(packet);
775 
776  if (funny) {
777  packet = (switch_stun_packet_t *) buf;
778  bytes += 4;
779  buf[bytes++] = 0;
780  buf[bytes++] = 0;
781  buf[bytes++] = 0;
782  buf[bytes++] = 0;
783  }
784 
785  switch_socket_sendto(sock, remote_addr, 0, (void *) packet, &bytes);
786  started = switch_micro_time_now();
787 
788  *ip = NULL;
789  *port = 0;
790 
791  for (;;) {
792  bytes = sizeof(buf);
793  if (switch_socket_recvfrom(from_addr, sock, 0, (char *) &buf, &bytes) == SWITCH_STATUS_SUCCESS && bytes > 0) {
794  break;
795  }
796 
797  if (((unsigned int)((switch_micro_time_now() - started) / 1000)) > 5000) {
798  *err = "Timeout";
800  switch_socket_close(sock);
801 
802  return SWITCH_STATUS_TIMEOUT;
803  }
805  }
806 
807  switch_socket_close(sock);
808 
809  if (funny) {
810  size -= 4;
811  }
812 
813  packet = switch_stun_packet_parse(start, size);
814  if (!packet) {
815  *err = "Invalid STUN/ICE packet";
816 
817  return SWITCH_STATUS_FALSE;
818  }
819 
820  end_buf = buf + ((sizeof(buf) > packet->header.length) ? packet->header.length : sizeof(buf));
821 
823  switch_assert(attr);
824 
825  do {
826  switch (attr->type) {
828  if (funny) {
829  switch_stun_ip_t *tmp = (switch_stun_ip_t *) attr->value;
830  tmp->address ^= ntohl(0xabcdabcd);
831  }
832 
833  switch_stun_packet_attribute_get_mapped_address(attr, rip, sizeof(rip), &rport);
834  break;
836  switch_stun_packet_attribute_get_xor_mapped_address(attr, &packet->header, rip, sizeof(rip), &rport);
837  break;
839  switch_stun_packet_attribute_get_username(attr, username, 32);
840  break;
841  }
842 
843  if (!switch_stun_packet_next_attribute(attr, end_buf)) {
844  break;
845  }
846 
847  xlen += 4 + switch_stun_attribute_padded_length(attr);
848 
849  } while (xlen <= packet->header.length);
850 
851  if (packet->header.type == SWITCH_STUN_BINDING_RESPONSE) {
852  *ip = switch_core_strdup(pool, rip);
853  *port = rport;
854 
855  return SWITCH_STATUS_SUCCESS;
856  } else {
857  *err = "Invalid Reply";
858  }
859 
860  return SWITCH_STATUS_FALSE;
861 }
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:438
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:623
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:286
#define switch_stun_attribute_padded_length(attribute)
Obtain the padded length of an attribute&#39;s value.
Definition: switch_stun.h:277
#define switch_stun_packet_length(packet)
Obtain the correct length in bytes of a stun packet.
Definition: switch_stun.h:304
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:295
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:430
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 458 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.

459 {
462 
463  attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length));
464  attribute->type = htons(SWITCH_STUN_ATTR_XOR_MAPPED_ADDRESS);
465 
466  if (family == AF_INET6) {
467  attribute->length = htons(20);
468  } else {
469  attribute->length = htons(8);
470  }
471 
472  ip = (switch_stun_ip_t *) attribute->value;
473 
474  ip->port = htons(port ^ (STUN_MAGIC_COOKIE >> 16));
475 
476  if (family == AF_INET6) {
477  ip->family = 2;
478  } else {
479  ip->family = 1;
480  }
481 
482  if (family == AF_INET6) {
483  inet_pton(AF_INET6, ipstr, (struct in6_addr *) &ip->address);
484  } else {
485  inet_pton(AF_INET, ipstr, (int *) &ip->address);
486  }
487 
488  packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length;
489  return 1;
490 }
#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 607 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().

608 {
610  char buf[8];
611 
612  switch_stun_random_string(buf, 8, NULL);
613 
614  attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length));
615  attribute->type = htons(SWITCH_STUN_ATTR_CONTROLLED);
616  attribute->length = htons(8);
617  memcpy(attribute->value, buf, 8);
618  packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length;
619  return 1;
620 }
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 592 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().

593 {
595  char buf[8];
596 
597  switch_stun_random_string(buf, 8, NULL);
598 
599  attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length));
600  attribute->type = htons(SWITCH_STUN_ATTR_CONTROLLING);
601  attribute->length = htons(8);
602  memcpy(attribute->value, buf, 8);
603  packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length;
604  return 1;
605 }
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 559 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().

560 {
562  uint32_t crc;
563  uint16_t xlen;
564 
565  attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length));
566  attribute->type = htons(SWITCH_STUN_ATTR_FINGERPRINT);
567  attribute->length = htons(4);
568 
569  xlen = ntohs(packet->header.length) + sizeof(switch_stun_packet_header_t);
570 
571  packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length;
572 
573  crc = htonl(switch_crc32_8bytes(packet, xlen) ^ 0x5354554e);
574 
575  memcpy(attribute->value, &crc, 4);
576 
577  return 1;
578 }
uint32_t switch_crc32_8bytes(const void *data, size_t length)
Definition: switch_stun.c:1228
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 542 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().

543 {
545  uint16_t xlen;
546 
547  attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length));
548  attribute->type = htons(SWITCH_STUN_ATTR_MESSAGE_INTEGRITY);
549  attribute->length = htons(20);
550 
551  xlen = ntohs(packet->header.length) + sizeof(switch_stun_packet_header_t);
552  packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length;
553 
554  HMAC(EVP_sha1(), (unsigned char *)pass, (int)strlen(pass), (void *)packet, xlen, (void *)attribute->value, NULL);
555 
556  return 1;
557 }
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 671 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.

672 {
674  int m = ulen % 4;
675  int padding = 0;
676 
677  if (m) {
678  padding = 4 - m;
679  }
680 
681  attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length));
682  attribute->type = htons(SWITCH_STUN_ATTR_PASSWORD);
683  attribute->length = htons(ulen);
684  if (password) {
685  memcpy(attribute->value, password, ulen);
686  } else {
687  switch_stun_random_string(attribute->value, ulen, NULL);
688  }
689 
690  packet->header.length += htons((u_short)(sizeof(switch_stun_packet_attribute_t) + padding)) + attribute->length;
691 
692  return 1;
693 }
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 528 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().

529 {
531 
532  priority = htonl(priority);
533  attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length));
534  attribute->type = htons(SWITCH_STUN_ATTR_PRIORITY);
535  attribute->length = htons(4);
536  memcpy(attribute->value, &priority, 4);
537 
538  packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length;
539  return 1;
540 }
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 647 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().

648 {
650  int m = ulen % 4;
651  int padding = 0;
652 
653  if (m) {
654  padding = 4 - m;
655  }
656 
657  attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length));
658  attribute->type = htons(SWITCH_STUN_ATTR_SOFTWARE);
659  attribute->length = htons(ulen);
660  if (software) {
661  memcpy(attribute->value, software, ulen);
662  } else {
663  switch_stun_random_string(attribute->value, ulen, NULL);
664  }
665 
666  packet->header.length += htons((u_short)(sizeof(switch_stun_packet_attribute_t) + padding)) + attribute->length;
667 
668  return 1;
669 }
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 581 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().

582 {
584 
585  attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length));
586  attribute->type = htons(SWITCH_STUN_ATTR_USE_CAND);
587  attribute->length = htons(0);
588  packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length;
589  return 1;
590 }
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 623 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().

624 {
626  int m = ulen % 4;
627  int padding = 0;
628 
629  if (m) {
630  padding = 4 - m;
631  }
632 
633  attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length));
634  attribute->type = htons(SWITCH_STUN_ATTR_USERNAME);
635  attribute->length = htons(ulen);
636  if (username) {
637  memcpy(attribute->value, username, ulen);
638  } else {
639  switch_stun_random_string(attribute->value, ulen, NULL);
640  }
641 
642  packet->header.length += htons((u_short)(sizeof(switch_stun_packet_attribute_t) + padding)) + attribute->length;
643 
644  return 1;
645 }
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 492 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().

493 {
496 
497  attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length));
498  attribute->type = htons(SWITCH_STUN_ATTR_XOR_MAPPED_ADDRESS);
499 
500  if (family == AF_INET6) {
501  attribute->length = htons(20);
502  } else {
503  attribute->length = htons(8);
504  }
505 
506  ip = (switch_stun_ip_t *) attribute->value;
507 
508  ip->port = htons(port ^ (STUN_MAGIC_COOKIE >> 16));
509 
510  if (family == AF_INET6) {
511  ip->family = 2;
512  } else {
513  ip->family = 1;
514  }
515 
516  if (family == AF_INET6) {
517  inet_pton(AF_INET6, ipstr, (struct in6_addr *) &ip->address);
518  v6_xor((uint8_t *)&ip->address, (uint8_t *)packet->header.id);
519  } else {
520  inet_pton(AF_INET, ipstr, (int *) &ip->address);
521  ip->address = htonl(ntohl(ip->address) ^ STUN_MAGIC_COOKIE);
522  }
523 
524  packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length;
525  return 1;
526 }
#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 430 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().

431 {
432  uint16_t cpylen;
433 
434  cpylen = attribute->length < len ? attribute->length : len;
435  return memcpy(username, attribute->value, cpylen);
436 }

◆ 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_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  uint8_t x, *i;
405  char *p = ipstr;
406 
407  ip = (switch_stun_ip_t *) attribute->value;
408 
409  if (ip->family == 2) {
410  uint8_t *v6addr = (uint8_t *) &ip->address;
411  v6_xor(v6addr, (uint8_t *)header->id);
412  inet_ntop(AF_INET6, v6addr, ipstr, iplen);
413  } else {
414  ip->address ^= header->cookie;
415 
416  i = (uint8_t *) & ip->address;
417  *ipstr = 0;
418  for (x = 0; x < 4; x++) {
419  sprintf(p, "%u%s", i[x], x == 3 ? "" : ".");
420  p = ipstr + strlen(ipstr);
421  }
422  }
423 
424  ip->port ^= ntohl(header->cookie) >> 16;
425  *port = ip->port;
426 
427  return 1;
428 }
uint32_t address
Definition: switch_stun.h:141
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 438 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().

439 {
441 
442 
443  header = (switch_stun_packet_header_t *) buf;
444  header->type = htons(type);
445  header->length = 0;
446  header->cookie = htonl(STUN_MAGIC_COOKIE);
447 
448  if (id) {
449  memcpy(header->id, id, 12);
450  } else {
451  switch_stun_random_string(header->id, 12, NULL);
452  }
453 
454  return (switch_stun_packet_t *) buf;
455 }
#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:286
#define switch_stun_attribute_padded_length(attribute)
Obtain the padded length of an attribute&#39;s value.
Definition: switch_stun.h:277
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.

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 * rand() / (RAND_MAX + 1.0));
139  buf[x] = set[j];
140  }
141 }
switch_byte_t switch_byte_t * buf

◆ 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