James Kuszmaul | 82f6c04 | 2021-01-17 11:30:16 -0800 | [diff] [blame^] | 1 | /** |
| 2 | * @file re_sip.h Session Initiation Protocol |
| 3 | * |
| 4 | * Copyright (C) 2010 Creytiv.com |
| 5 | */ |
| 6 | |
| 7 | |
| 8 | enum { |
| 9 | SIP_PORT = 5060, |
| 10 | SIP_PORT_TLS = 5061, |
| 11 | }; |
| 12 | |
| 13 | /** SIP Transport */ |
| 14 | enum sip_transp { |
| 15 | SIP_TRANSP_NONE = -1, |
| 16 | SIP_TRANSP_UDP = 0, |
| 17 | SIP_TRANSP_TCP, |
| 18 | SIP_TRANSP_TLS, |
| 19 | SIP_TRANSPC, |
| 20 | }; |
| 21 | |
| 22 | |
| 23 | /** SIP Header ID (perfect hash value) */ |
| 24 | enum sip_hdrid { |
| 25 | SIP_HDR_ACCEPT = 3186, |
| 26 | SIP_HDR_ACCEPT_CONTACT = 232, |
| 27 | SIP_HDR_ACCEPT_ENCODING = 708, |
| 28 | SIP_HDR_ACCEPT_LANGUAGE = 2867, |
| 29 | SIP_HDR_ACCEPT_RESOURCE_PRIORITY = 1848, |
| 30 | SIP_HDR_ALERT_INFO = 274, |
| 31 | SIP_HDR_ALLOW = 2429, |
| 32 | SIP_HDR_ALLOW_EVENTS = 66, |
| 33 | SIP_HDR_ANSWER_MODE = 2905, |
| 34 | SIP_HDR_AUTHENTICATION_INFO = 3144, |
| 35 | SIP_HDR_AUTHORIZATION = 2503, |
| 36 | SIP_HDR_CALL_ID = 3095, |
| 37 | SIP_HDR_CALL_INFO = 586, |
| 38 | SIP_HDR_CONTACT = 229, |
| 39 | SIP_HDR_CONTENT_DISPOSITION = 1425, |
| 40 | SIP_HDR_CONTENT_ENCODING = 580, |
| 41 | SIP_HDR_CONTENT_LANGUAGE = 3371, |
| 42 | SIP_HDR_CONTENT_LENGTH = 3861, |
| 43 | SIP_HDR_CONTENT_TYPE = 809, |
| 44 | SIP_HDR_CSEQ = 746, |
| 45 | SIP_HDR_DATE = 1027, |
| 46 | SIP_HDR_ENCRYPTION = 3125, |
| 47 | SIP_HDR_ERROR_INFO = 21, |
| 48 | SIP_HDR_EVENT = 3286, |
| 49 | SIP_HDR_EXPIRES = 1983, |
| 50 | SIP_HDR_FLOW_TIMER = 584, |
| 51 | SIP_HDR_FROM = 1963, |
| 52 | SIP_HDR_HIDE = 283, |
| 53 | SIP_HDR_HISTORY_INFO = 2582, |
| 54 | SIP_HDR_IDENTITY = 2362, |
| 55 | SIP_HDR_IDENTITY_INFO = 980, |
| 56 | SIP_HDR_IN_REPLY_TO = 1577, |
| 57 | SIP_HDR_JOIN = 3479, |
| 58 | SIP_HDR_MAX_BREADTH = 3701, |
| 59 | SIP_HDR_MAX_FORWARDS = 3549, |
| 60 | SIP_HDR_MIME_VERSION = 3659, |
| 61 | SIP_HDR_MIN_EXPIRES = 1121, |
| 62 | SIP_HDR_MIN_SE = 2847, |
| 63 | SIP_HDR_ORGANIZATION = 3247, |
| 64 | SIP_HDR_P_ACCESS_NETWORK_INFO = 1662, |
| 65 | SIP_HDR_P_ANSWER_STATE = 42, |
| 66 | SIP_HDR_P_ASSERTED_IDENTITY = 1233, |
| 67 | SIP_HDR_P_ASSOCIATED_URI = 900, |
| 68 | SIP_HDR_P_CALLED_PARTY_ID = 3347, |
| 69 | SIP_HDR_P_CHARGING_FUNCTION_ADDRESSES = 2171, |
| 70 | SIP_HDR_P_CHARGING_VECTOR = 25, |
| 71 | SIP_HDR_P_DCS_TRACE_PARTY_ID = 3027, |
| 72 | SIP_HDR_P_DCS_OSPS = 1788, |
| 73 | SIP_HDR_P_DCS_BILLING_INFO = 2017, |
| 74 | SIP_HDR_P_DCS_LAES = 693, |
| 75 | SIP_HDR_P_DCS_REDIRECT = 1872, |
| 76 | SIP_HDR_P_EARLY_MEDIA = 2622, |
| 77 | SIP_HDR_P_MEDIA_AUTHORIZATION = 1035, |
| 78 | SIP_HDR_P_PREFERRED_IDENTITY = 1263, |
| 79 | SIP_HDR_P_PROFILE_KEY = 1904, |
| 80 | SIP_HDR_P_REFUSED_URI_LIST = 1047, |
| 81 | SIP_HDR_P_SERVED_USER = 1588, |
| 82 | SIP_HDR_P_USER_DATABASE = 2827, |
| 83 | SIP_HDR_P_VISITED_NETWORK_ID = 3867, |
| 84 | SIP_HDR_PATH = 2741, |
| 85 | SIP_HDR_PERMISSION_MISSING = 1409, |
| 86 | SIP_HDR_PRIORITY = 3520, |
| 87 | SIP_HDR_PRIV_ANSWER_MODE = 2476, |
| 88 | SIP_HDR_PRIVACY = 3150, |
| 89 | SIP_HDR_PROXY_AUTHENTICATE = 116, |
| 90 | SIP_HDR_PROXY_AUTHORIZATION = 2363, |
| 91 | SIP_HDR_PROXY_REQUIRE = 3562, |
| 92 | SIP_HDR_RACK = 2523, |
| 93 | SIP_HDR_REASON = 3732, |
| 94 | SIP_HDR_RECORD_ROUTE = 278, |
| 95 | SIP_HDR_REFER_SUB = 2458, |
| 96 | SIP_HDR_REFER_TO = 1521, |
| 97 | SIP_HDR_REFERRED_BY = 3456, |
| 98 | SIP_HDR_REJECT_CONTACT = 285, |
| 99 | SIP_HDR_REPLACES = 2534, |
| 100 | SIP_HDR_REPLY_TO = 2404, |
| 101 | SIP_HDR_REQUEST_DISPOSITION = 3715, |
| 102 | SIP_HDR_REQUIRE = 3905, |
| 103 | SIP_HDR_RESOURCE_PRIORITY = 1643, |
| 104 | SIP_HDR_RESPONSE_KEY = 1548, |
| 105 | SIP_HDR_RETRY_AFTER = 409, |
| 106 | SIP_HDR_ROUTE = 661, |
| 107 | SIP_HDR_RSEQ = 445, |
| 108 | SIP_HDR_SECURITY_CLIENT = 1358, |
| 109 | SIP_HDR_SECURITY_SERVER = 811, |
| 110 | SIP_HDR_SECURITY_VERIFY = 519, |
| 111 | SIP_HDR_SERVER = 973, |
| 112 | SIP_HDR_SERVICE_ROUTE = 1655, |
| 113 | SIP_HDR_SESSION_EXPIRES = 1979, |
| 114 | SIP_HDR_SIP_ETAG = 1997, |
| 115 | SIP_HDR_SIP_IF_MATCH = 3056, |
| 116 | SIP_HDR_SUBJECT = 1043, |
| 117 | SIP_HDR_SUBSCRIPTION_STATE = 2884, |
| 118 | SIP_HDR_SUPPORTED = 119, |
| 119 | SIP_HDR_TARGET_DIALOG = 3450, |
| 120 | SIP_HDR_TIMESTAMP = 938, |
| 121 | SIP_HDR_TO = 1449, |
| 122 | SIP_HDR_TRIGGER_CONSENT = 3180, |
| 123 | SIP_HDR_UNSUPPORTED = 982, |
| 124 | SIP_HDR_USER_AGENT = 4064, |
| 125 | SIP_HDR_VIA = 3961, |
| 126 | SIP_HDR_WARNING = 2108, |
| 127 | SIP_HDR_WWW_AUTHENTICATE = 2763, |
| 128 | |
| 129 | SIP_HDR_NONE = -1 |
| 130 | }; |
| 131 | |
| 132 | |
| 133 | enum { |
| 134 | SIP_T1 = 500, |
| 135 | SIP_T2 = 4000, |
| 136 | SIP_T4 = 5000, |
| 137 | }; |
| 138 | |
| 139 | |
| 140 | /** SIP Via header */ |
| 141 | struct sip_via { |
| 142 | struct pl sentby; |
| 143 | struct sa addr; |
| 144 | struct pl params; |
| 145 | struct pl branch; |
| 146 | struct pl val; |
| 147 | enum sip_transp tp; |
| 148 | }; |
| 149 | |
| 150 | /** SIP Address */ |
| 151 | struct sip_addr { |
| 152 | struct pl dname; |
| 153 | struct pl auri; |
| 154 | struct uri uri; |
| 155 | struct pl params; |
| 156 | }; |
| 157 | |
| 158 | /** SIP Tag address */ |
| 159 | struct sip_taddr { |
| 160 | struct pl dname; |
| 161 | struct pl auri; |
| 162 | struct uri uri; |
| 163 | struct pl params; |
| 164 | struct pl tag; |
| 165 | struct pl val; |
| 166 | }; |
| 167 | |
| 168 | /** SIP CSeq header */ |
| 169 | struct sip_cseq { |
| 170 | struct pl met; |
| 171 | uint32_t num; |
| 172 | }; |
| 173 | |
| 174 | /** SIP Header */ |
| 175 | struct sip_hdr { |
| 176 | struct le le; /**< Linked-list element */ |
| 177 | struct le he; /**< Hash-table element */ |
| 178 | struct pl name; /**< SIP Header name */ |
| 179 | struct pl val; /**< SIP Header value */ |
| 180 | enum sip_hdrid id; /**< SIP Header id (unique) */ |
| 181 | }; |
| 182 | |
| 183 | /** SIP Message */ |
| 184 | struct sip_msg { |
| 185 | struct sa src; /**< Source network address */ |
| 186 | struct sa dst; /**< Destination network address */ |
| 187 | struct pl ver; /**< SIP Version number */ |
| 188 | struct pl met; /**< Request method */ |
| 189 | struct pl ruri; /**< Raw request URI */ |
| 190 | struct uri uri; /**< Parsed request URI */ |
| 191 | uint16_t scode; /**< Response status code */ |
| 192 | struct pl reason; /**< Response reason phrase */ |
| 193 | struct list hdrl; /**< List of SIP Headers (struct sip_hdr) */ |
| 194 | struct sip_via via; /**< Parsed first Via header */ |
| 195 | struct sip_taddr to; /**< Parsed To header */ |
| 196 | struct sip_taddr from; /**< Parsed From header */ |
| 197 | struct sip_cseq cseq; /**< Parsed CSeq header */ |
| 198 | struct msg_ctype ctyp; /**< Content Type */ |
| 199 | struct pl callid; /**< Cached Call-ID header */ |
| 200 | struct pl maxfwd; /**< Cached Max-Forwards header */ |
| 201 | struct pl expires; /**< Cached Expires header */ |
| 202 | struct pl clen; /**< Cached Content-Length header */ |
| 203 | struct hash *hdrht; /**< Hash-table with all SIP headers */ |
| 204 | struct mbuf *mb; /**< Buffer containing the SIP message */ |
| 205 | void *sock; /**< Transport socket */ |
| 206 | uint64_t tag; /**< Opaque tag */ |
| 207 | enum sip_transp tp; /**< SIP Transport */ |
| 208 | bool req; /**< True if Request, False if Response */ |
| 209 | }; |
| 210 | |
| 211 | /** SIP Loop-state */ |
| 212 | struct sip_loopstate { |
| 213 | uint32_t failc; |
| 214 | uint16_t last_scode; |
| 215 | }; |
| 216 | |
| 217 | /** SIP Contact */ |
| 218 | struct sip_contact { |
| 219 | const char *uri; |
| 220 | const struct sa *addr; |
| 221 | enum sip_transp tp; |
| 222 | }; |
| 223 | |
| 224 | struct sip; |
| 225 | struct sip_lsnr; |
| 226 | struct sip_request; |
| 227 | struct sip_strans; |
| 228 | struct sip_auth; |
| 229 | struct sip_dialog; |
| 230 | struct sip_keepalive; |
| 231 | struct dnsc; |
| 232 | |
| 233 | typedef bool(sip_msg_h)(const struct sip_msg *msg, void *arg); |
| 234 | typedef int(sip_send_h)(enum sip_transp tp, const struct sa *src, |
| 235 | const struct sa *dst, struct mbuf *mb, void *arg); |
| 236 | typedef void(sip_resp_h)(int err, const struct sip_msg *msg, void *arg); |
| 237 | typedef void(sip_cancel_h)(void *arg); |
| 238 | typedef void(sip_exit_h)(void *arg); |
| 239 | typedef int(sip_auth_h)(char **username, char **password, const char *realm, |
| 240 | void *arg); |
| 241 | typedef bool(sip_hdr_h)(const struct sip_hdr *hdr, const struct sip_msg *msg, |
| 242 | void *arg); |
| 243 | typedef void(sip_keepalive_h)(int err, void *arg); |
| 244 | |
| 245 | |
| 246 | /* sip */ |
| 247 | int sip_alloc(struct sip **sipp, struct dnsc *dnsc, uint32_t ctsz, |
| 248 | uint32_t stsz, uint32_t tcsz, const char *software, |
| 249 | sip_exit_h *exith, void *arg); |
| 250 | void sip_close(struct sip *sip, bool force); |
| 251 | int sip_listen(struct sip_lsnr **lsnrp, struct sip *sip, bool req, |
| 252 | sip_msg_h *msgh, void *arg); |
| 253 | int sip_debug(struct re_printf *pf, const struct sip *sip); |
| 254 | int sip_send(struct sip *sip, void *sock, enum sip_transp tp, |
| 255 | const struct sa *dst, struct mbuf *mb); |
| 256 | |
| 257 | |
| 258 | /* transport */ |
| 259 | int sip_transp_add(struct sip *sip, enum sip_transp tp, |
| 260 | const struct sa *laddr, ...); |
| 261 | void sip_transp_flush(struct sip *sip); |
| 262 | bool sip_transp_isladdr(const struct sip *sip, enum sip_transp tp, |
| 263 | const struct sa *laddr); |
| 264 | const char *sip_transp_name(enum sip_transp tp); |
| 265 | const char *sip_transp_param(enum sip_transp tp); |
| 266 | uint16_t sip_transp_port(enum sip_transp tp, uint16_t port); |
| 267 | int sip_transp_laddr(struct sip *sip, struct sa *laddr, enum sip_transp tp, |
| 268 | const struct sa *dst); |
| 269 | |
| 270 | |
| 271 | /* request */ |
| 272 | int sip_request(struct sip_request **reqp, struct sip *sip, bool stateful, |
| 273 | const char *met, int metl, const char *uri, int uril, |
| 274 | const struct uri *route, struct mbuf *mb, size_t sortkey, |
| 275 | sip_send_h *sendh, sip_resp_h *resph, void *arg); |
| 276 | int sip_requestf(struct sip_request **reqp, struct sip *sip, bool stateful, |
| 277 | const char *met, const char *uri, const struct uri *route, |
| 278 | struct sip_auth *auth, sip_send_h *sendh, sip_resp_h *resph, |
| 279 | void *arg, const char *fmt, ...); |
| 280 | int sip_drequestf(struct sip_request **reqp, struct sip *sip, bool stateful, |
| 281 | const char *met, struct sip_dialog *dlg, uint32_t cseq, |
| 282 | struct sip_auth *auth, sip_send_h *sendh, sip_resp_h *resph, |
| 283 | void *arg, const char *fmt, ...); |
| 284 | void sip_request_cancel(struct sip_request *req); |
| 285 | bool sip_request_loops(struct sip_loopstate *ls, uint16_t scode); |
| 286 | void sip_loopstate_reset(struct sip_loopstate *ls); |
| 287 | |
| 288 | |
| 289 | /* reply */ |
| 290 | int sip_strans_alloc(struct sip_strans **stp, struct sip *sip, |
| 291 | const struct sip_msg *msg, sip_cancel_h *cancelh, |
| 292 | void *arg); |
| 293 | int sip_strans_reply(struct sip_strans **stp, struct sip *sip, |
| 294 | const struct sip_msg *msg, const struct sa *dst, |
| 295 | uint16_t scode, struct mbuf *mb); |
| 296 | int sip_treplyf(struct sip_strans **stp, struct mbuf **mbp, struct sip *sip, |
| 297 | const struct sip_msg *msg, bool rec_route, uint16_t scode, |
| 298 | const char *reason, const char *fmt, ...); |
| 299 | int sip_treply(struct sip_strans **stp, struct sip *sip, |
| 300 | const struct sip_msg *msg, uint16_t scode, const char *reason); |
| 301 | int sip_replyf(struct sip *sip, const struct sip_msg *msg, uint16_t scode, |
| 302 | const char *reason, const char *fmt, ...); |
| 303 | int sip_reply(struct sip *sip, const struct sip_msg *msg, uint16_t scode, |
| 304 | const char *reason); |
| 305 | void sip_reply_addr(struct sa *addr, const struct sip_msg *msg, bool rport); |
| 306 | |
| 307 | |
| 308 | /* auth */ |
| 309 | int sip_auth_authenticate(struct sip_auth *auth, const struct sip_msg *msg); |
| 310 | int sip_auth_alloc(struct sip_auth **authp, sip_auth_h *authh, |
| 311 | void *arg, bool ref); |
| 312 | void sip_auth_reset(struct sip_auth *auth); |
| 313 | |
| 314 | |
| 315 | /* contact */ |
| 316 | void sip_contact_set(struct sip_contact *contact, const char *uri, |
| 317 | const struct sa *addr, enum sip_transp tp); |
| 318 | int sip_contact_print(struct re_printf *pf, |
| 319 | const struct sip_contact *contact); |
| 320 | |
| 321 | |
| 322 | /* dialog */ |
| 323 | int sip_dialog_alloc(struct sip_dialog **dlgp, |
| 324 | const char *uri, const char *to_uri, |
| 325 | const char *from_name, const char *from_uri, |
| 326 | const char *routev[], uint32_t routec); |
| 327 | int sip_dialog_accept(struct sip_dialog **dlgp, const struct sip_msg *msg); |
| 328 | int sip_dialog_create(struct sip_dialog *dlg, const struct sip_msg *msg); |
| 329 | int sip_dialog_fork(struct sip_dialog **dlgp, struct sip_dialog *odlg, |
| 330 | const struct sip_msg *msg); |
| 331 | int sip_dialog_update(struct sip_dialog *dlg, const struct sip_msg *msg); |
| 332 | bool sip_dialog_rseq_valid(struct sip_dialog *dlg, const struct sip_msg *msg); |
| 333 | const char *sip_dialog_callid(const struct sip_dialog *dlg); |
| 334 | uint32_t sip_dialog_lseq(const struct sip_dialog *dlg); |
| 335 | bool sip_dialog_established(const struct sip_dialog *dlg); |
| 336 | bool sip_dialog_cmp(const struct sip_dialog *dlg, const struct sip_msg *msg); |
| 337 | bool sip_dialog_cmp_half(const struct sip_dialog *dlg, |
| 338 | const struct sip_msg *msg); |
| 339 | |
| 340 | |
| 341 | /* msg */ |
| 342 | int sip_msg_decode(struct sip_msg **msgp, struct mbuf *mb); |
| 343 | const struct sip_hdr *sip_msg_hdr(const struct sip_msg *msg, |
| 344 | enum sip_hdrid id); |
| 345 | const struct sip_hdr *sip_msg_hdr_apply(const struct sip_msg *msg, |
| 346 | bool fwd, enum sip_hdrid id, |
| 347 | sip_hdr_h *h, void *arg); |
| 348 | const struct sip_hdr *sip_msg_xhdr(const struct sip_msg *msg, |
| 349 | const char *name); |
| 350 | const struct sip_hdr *sip_msg_xhdr_apply(const struct sip_msg *msg, |
| 351 | bool fwd, const char *name, |
| 352 | sip_hdr_h *h, void *arg); |
| 353 | uint32_t sip_msg_hdr_count(const struct sip_msg *msg, enum sip_hdrid id); |
| 354 | uint32_t sip_msg_xhdr_count(const struct sip_msg *msg, const char *name); |
| 355 | bool sip_msg_hdr_has_value(const struct sip_msg *msg, enum sip_hdrid id, |
| 356 | const char *value); |
| 357 | bool sip_msg_xhdr_has_value(const struct sip_msg *msg, const char *name, |
| 358 | const char *value); |
| 359 | struct tcp_conn *sip_msg_tcpconn(const struct sip_msg *msg); |
| 360 | void sip_msg_dump(const struct sip_msg *msg); |
| 361 | |
| 362 | int sip_addr_decode(struct sip_addr *addr, const struct pl *pl); |
| 363 | int sip_via_decode(struct sip_via *via, const struct pl *pl); |
| 364 | int sip_cseq_decode(struct sip_cseq *cseq, const struct pl *pl); |
| 365 | |
| 366 | |
| 367 | /* keepalive */ |
| 368 | int sip_keepalive_start(struct sip_keepalive **kap, struct sip *sip, |
| 369 | const struct sip_msg *msg, uint32_t interval, |
| 370 | sip_keepalive_h *kah, void *arg); |