1 /** 2 * @file re_stun.h Session Traversal Utilities for (NAT) (STUN) 3 * 4 * Copyright (C) 2010 Creytiv.com 5 */ 6 7 8 /** STUN Protocol values */ 9 enum { 10 STUN_PORT = 3478, /**< STUN Port number */ 11 STUNS_PORT = 5349, /**< STUNS Port number */ 12 STUN_HEADER_SIZE = 20, /**< Number of bytes in header */ 13 STUN_ATTR_HEADER_SIZE = 4, /**< Size of attribute header */ 14 STUN_TID_SIZE = 12, /**< Number of bytes in transaction ID */ 15 STUN_DEFAULT_RTO = 500, /**< Default Retrans Timeout in [ms] */ 16 STUN_DEFAULT_RC = 7, /**< Default number of retransmits */ 17 STUN_DEFAULT_RM = 16, /**< Wait time after last request is sent */ 18 STUN_DEFAULT_TI = 39500 /**< Reliable timeout */ 19 }; 20 21 /** STUN Address Family */ 22 enum stun_af { 23 STUN_AF_IPv4 = 0x01, /**< IPv4 Address Family */ 24 STUN_AF_IPv6 = 0x02 /**< IPv6 Address Family */ 25 }; 26 27 /** STUN Transport */ 28 enum stun_transp { 29 STUN_TRANSP_UDP = IPPROTO_UDP, /**< UDP-transport (struct udp_sock) */ 30 STUN_TRANSP_TCP = IPPROTO_TCP, /**< TCP-transport (struct tcp_conn) */ 31 STUN_TRANSP_DTLS, /**< DTLS-transport (struct tls_conn) */ 32 }; 33 34 /** STUN Methods */ 35 enum stun_method { 36 STUN_METHOD_BINDING = 0x001, 37 STUN_METHOD_ALLOCATE = 0x003, 38 STUN_METHOD_REFRESH = 0x004, 39 STUN_METHOD_SEND = 0x006, 40 STUN_METHOD_DATA = 0x007, 41 STUN_METHOD_CREATEPERM = 0x008, 42 STUN_METHOD_CHANBIND = 0x009, 43 }; 44 45 /** STUN Message class */ 46 enum stun_msg_class { 47 STUN_CLASS_REQUEST = 0x0, /**< STUN Request */ 48 STUN_CLASS_INDICATION = 0x1, /**< STUN Indication */ 49 STUN_CLASS_SUCCESS_RESP = 0x2, /**< STUN Success Response */ 50 STUN_CLASS_ERROR_RESP = 0x3 /**< STUN Error Response */ 51 }; 52 53 /** STUN Attributes */ 54 enum stun_attrib { 55 /* Comprehension-required range (0x0000-0x7FFF) */ 56 STUN_ATTR_MAPPED_ADDR = 0x0001, 57 STUN_ATTR_CHANGE_REQ = 0x0003, 58 STUN_ATTR_USERNAME = 0x0006, 59 STUN_ATTR_MSG_INTEGRITY = 0x0008, 60 STUN_ATTR_ERR_CODE = 0x0009, 61 STUN_ATTR_UNKNOWN_ATTR = 0x000a, 62 STUN_ATTR_CHANNEL_NUMBER = 0x000c, 63 STUN_ATTR_LIFETIME = 0x000d, 64 STUN_ATTR_XOR_PEER_ADDR = 0x0012, 65 STUN_ATTR_DATA = 0x0013, 66 STUN_ATTR_REALM = 0x0014, 67 STUN_ATTR_NONCE = 0x0015, 68 STUN_ATTR_XOR_RELAY_ADDR = 0x0016, 69 STUN_ATTR_REQ_ADDR_FAMILY = 0x0017, 70 STUN_ATTR_EVEN_PORT = 0x0018, 71 STUN_ATTR_REQ_TRANSPORT = 0x0019, 72 STUN_ATTR_DONT_FRAGMENT = 0x001a, 73 STUN_ATTR_XOR_MAPPED_ADDR = 0x0020, 74 STUN_ATTR_RSV_TOKEN = 0x0022, 75 STUN_ATTR_PRIORITY = 0x0024, 76 STUN_ATTR_USE_CAND = 0x0025, 77 STUN_ATTR_PADDING = 0x0026, 78 STUN_ATTR_RESP_PORT = 0x0027, 79 80 /* Comprehension-optional range (0x8000-0xFFFF) */ 81 STUN_ATTR_SOFTWARE = 0x8022, 82 STUN_ATTR_ALT_SERVER = 0x8023, 83 STUN_ATTR_FINGERPRINT = 0x8028, 84 STUN_ATTR_CONTROLLED = 0x8029, 85 STUN_ATTR_CONTROLLING = 0x802a, 86 STUN_ATTR_RESP_ORIGIN = 0x802b, 87 STUN_ATTR_OTHER_ADDR = 0x802c, 88 }; 89 90 91 struct stun_change_req { 92 bool ip; 93 bool port; 94 }; 95 96 struct stun_errcode { 97 uint16_t code; 98 char *reason; 99 }; 100 101 struct stun_unknown_attr { 102 uint16_t typev[8]; 103 uint32_t typec; 104 }; 105 106 struct stun_even_port { 107 bool r; 108 }; 109 110 /** Defines a STUN attribute */ 111 struct stun_attr { 112 struct le le; 113 uint16_t type; 114 union { 115 /* generic types */ 116 struct sa sa; 117 char *str; 118 uint64_t uint64; 119 uint32_t uint32; 120 uint16_t uint16; 121 uint8_t uint8; 122 struct mbuf mb; 123 124 /* actual attributes */ 125 struct sa mapped_addr; 126 struct stun_change_req change_req; 127 char *username; 128 uint8_t msg_integrity[20]; 129 struct stun_errcode err_code; 130 struct stun_unknown_attr unknown_attr; 131 uint16_t channel_number; 132 uint32_t lifetime; 133 struct sa xor_peer_addr; 134 struct mbuf data; 135 char *realm; 136 char *nonce; 137 struct sa xor_relay_addr; 138 uint8_t req_addr_family; 139 struct stun_even_port even_port; 140 uint8_t req_transport; 141 struct sa xor_mapped_addr; 142 uint64_t rsv_token; 143 uint32_t priority; 144 struct mbuf padding; 145 uint16_t resp_port; 146 char *software; 147 struct sa alt_server; 148 uint32_t fingerprint; 149 uint64_t controlled; 150 uint64_t controlling; 151 struct sa resp_origin; 152 struct sa other_addr; 153 } v; 154 }; 155 156 157 /** STUN Configuration */ 158 struct stun_conf { 159 uint32_t rto; /**< RTO Retransmission TimeOut [ms] */ 160 uint32_t rc; /**< Rc Retransmission count (default 7) */ 161 uint32_t rm; /**< Rm Max retransmissions (default 16) */ 162 uint32_t ti; /**< Ti Timeout for reliable transport [ms] */ 163 uint8_t tos; /**< Type-of-service field */ 164 }; 165 166 167 extern const char *stun_software; 168 struct stun; 169 struct stun_msg; 170 struct stun_ctrans; 171 172 typedef void(stun_resp_h)(int err, uint16_t scode, const char *reason, 173 const struct stun_msg *msg, void *arg); 174 typedef void(stun_ind_h)(struct stun_msg *msg, void *arg); 175 typedef bool(stun_attr_h)(const struct stun_attr *attr, void *arg); 176 177 int stun_alloc(struct stun **stunp, const struct stun_conf *conf, 178 stun_ind_h *indh, void *arg); 179 struct stun_conf *stun_conf(struct stun *stun); 180 int stun_send(int proto, void *sock, const struct sa *dst, struct mbuf *mb); 181 int stun_recv(struct stun *stun, struct mbuf *mb); 182 int stun_ctrans_recv(struct stun *stun, const struct stun_msg *msg, 183 const struct stun_unknown_attr *ua); 184 struct re_printf; 185 int stun_debug(struct re_printf *pf, const struct stun *stun); 186 187 int stun_request(struct stun_ctrans **ctp, struct stun *stun, int proto, 188 void *sock, const struct sa *dst, size_t presz, 189 uint16_t method, const uint8_t *key, size_t keylen, bool fp, 190 stun_resp_h *resph, void *arg, uint32_t attrc, ...); 191 int stun_reply(int proto, void *sock, const struct sa *dst, size_t presz, 192 const struct stun_msg *req, const uint8_t *key, 193 size_t keylen, bool fp, uint32_t attrc, ...); 194 int stun_ereply(int proto, void *sock, const struct sa *dst, size_t presz, 195 const struct stun_msg *req, uint16_t scode, 196 const char *reason, const uint8_t *key, size_t keylen, 197 bool fp, uint32_t attrc, ...); 198 int stun_indication(int proto, void *sock, const struct sa *dst, size_t presz, 199 uint16_t method, const uint8_t *key, size_t keylen, 200 bool fp, uint32_t attrc, ...); 201 202 int stun_msg_vencode(struct mbuf *mb, uint16_t method, uint8_t cls, 203 const uint8_t *tid, const struct stun_errcode *ec, 204 const uint8_t *key, size_t keylen, bool fp, 205 uint8_t padding, uint32_t attrc, va_list ap); 206 int stun_msg_encode(struct mbuf *mb, uint16_t method, uint8_t cls, 207 const uint8_t *tid, const struct stun_errcode *ec, 208 const uint8_t *key, size_t keylen, bool fp, 209 uint8_t padding, uint32_t attrc, ...); 210 int stun_msg_decode(struct stun_msg **msgpp, struct mbuf *mb, 211 struct stun_unknown_attr *ua); 212 uint16_t stun_msg_type(const struct stun_msg *msg); 213 uint16_t stun_msg_class(const struct stun_msg *msg); 214 uint16_t stun_msg_method(const struct stun_msg *msg); 215 bool stun_msg_mcookie(const struct stun_msg *msg); 216 const uint8_t *stun_msg_tid(const struct stun_msg *msg); 217 struct stun_attr *stun_msg_attr(const struct stun_msg *msg, uint16_t type); 218 struct stun_attr *stun_msg_attr_apply(const struct stun_msg *msg, 219 stun_attr_h *h, void *arg); 220 int stun_msg_chk_mi(const struct stun_msg *msg, const uint8_t *key, 221 size_t keylen); 222 int stun_msg_chk_fingerprint(const struct stun_msg *msg); 223 void stun_msg_dump(const struct stun_msg *msg); 224 225 const char *stun_class_name(uint16_t cls); 226 const char *stun_method_name(uint16_t method); 227 const char *stun_attr_name(uint16_t type); 228 const char *stun_transp_name(enum stun_transp tp); 229 230 231 /* DNS Discovery of a STUN Server */ 232 extern const char *stun_proto_udp; 233 extern const char *stun_proto_tcp; 234 235 extern const char *stun_usage_binding; 236 extern const char *stuns_usage_binding; 237 extern const char *stun_usage_relay; 238 extern const char *stuns_usage_relay; 239 extern const char *stun_usage_behavior; 240 extern const char *stuns_usage_behavior; 241 242 243 /** 244 * Defines the STUN Server Discovery handler 245 * 246 * @param err Errorcode 247 * @param srv IP Address and port of STUN Server 248 * @param arg Handler argument 249 */ 250 typedef void (stun_dns_h)(int err, const struct sa *srv, void *arg); 251 252 struct stun_dns; 253 struct dnsc; 254 int stun_server_discover(struct stun_dns **dnsp, struct dnsc *dnsc, 255 const char *service, const char *proto, 256 int af, const char *domain, uint16_t port, 257 stun_dns_h *dnsh, void *arg); 258 259 260 /* NAT Keepalives */ 261 struct stun_keepalive; 262 263 /** 264 * Defines the STUN Keepalive Mapped-Address handler 265 * 266 * @param err Errorcode 267 * @param map Mapped Address 268 * @param arg Handler argument 269 */ 270 typedef void (stun_mapped_addr_h)(int err, const struct sa *map, void *arg); 271 272 273 int stun_keepalive_alloc(struct stun_keepalive **skap, 274 int proto, void *sock, int layer, 275 const struct sa *dst, const struct stun_conf *conf, 276 stun_mapped_addr_h *mah, void *arg); 277 void stun_keepalive_enable(struct stun_keepalive *ska, uint32_t interval); 278 279 280 /* STUN Reason Phrase */ 281 extern const char *stun_reason_300; 282 extern const char *stun_reason_400; 283 extern const char *stun_reason_401; 284 extern const char *stun_reason_403; 285 extern const char *stun_reason_420; 286 extern const char *stun_reason_437; 287 extern const char *stun_reason_438; 288 extern const char *stun_reason_440; 289 extern const char *stun_reason_441; 290 extern const char *stun_reason_442; 291 extern const char *stun_reason_443; 292 extern const char *stun_reason_486; 293 extern const char *stun_reason_500; 294 extern const char *stun_reason_508; 295