James Kuszmaul | 82f6c04 | 2021-01-17 11:30:16 -0800 | [diff] [blame^] | 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; |