/** * @file re_sip.h Session Initiation Protocol * * Copyright (C) 2010 Creytiv.com */ enum { SIP_PORT = 5060, SIP_PORT_TLS = 5061, }; /** SIP Transport */ enum sip_transp { SIP_TRANSP_NONE = -1, SIP_TRANSP_UDP = 0, SIP_TRANSP_TCP, SIP_TRANSP_TLS, SIP_TRANSPC, }; /** SIP Header ID (perfect hash value) */ enum sip_hdrid { SIP_HDR_ACCEPT = 3186, SIP_HDR_ACCEPT_CONTACT = 232, SIP_HDR_ACCEPT_ENCODING = 708, SIP_HDR_ACCEPT_LANGUAGE = 2867, SIP_HDR_ACCEPT_RESOURCE_PRIORITY = 1848, SIP_HDR_ALERT_INFO = 274, SIP_HDR_ALLOW = 2429, SIP_HDR_ALLOW_EVENTS = 66, SIP_HDR_ANSWER_MODE = 2905, SIP_HDR_AUTHENTICATION_INFO = 3144, SIP_HDR_AUTHORIZATION = 2503, SIP_HDR_CALL_ID = 3095, SIP_HDR_CALL_INFO = 586, SIP_HDR_CONTACT = 229, SIP_HDR_CONTENT_DISPOSITION = 1425, SIP_HDR_CONTENT_ENCODING = 580, SIP_HDR_CONTENT_LANGUAGE = 3371, SIP_HDR_CONTENT_LENGTH = 3861, SIP_HDR_CONTENT_TYPE = 809, SIP_HDR_CSEQ = 746, SIP_HDR_DATE = 1027, SIP_HDR_ENCRYPTION = 3125, SIP_HDR_ERROR_INFO = 21, SIP_HDR_EVENT = 3286, SIP_HDR_EXPIRES = 1983, SIP_HDR_FLOW_TIMER = 584, SIP_HDR_FROM = 1963, SIP_HDR_HIDE = 283, SIP_HDR_HISTORY_INFO = 2582, SIP_HDR_IDENTITY = 2362, SIP_HDR_IDENTITY_INFO = 980, SIP_HDR_IN_REPLY_TO = 1577, SIP_HDR_JOIN = 3479, SIP_HDR_MAX_BREADTH = 3701, SIP_HDR_MAX_FORWARDS = 3549, SIP_HDR_MIME_VERSION = 3659, SIP_HDR_MIN_EXPIRES = 1121, SIP_HDR_MIN_SE = 2847, SIP_HDR_ORGANIZATION = 3247, SIP_HDR_P_ACCESS_NETWORK_INFO = 1662, SIP_HDR_P_ANSWER_STATE = 42, SIP_HDR_P_ASSERTED_IDENTITY = 1233, SIP_HDR_P_ASSOCIATED_URI = 900, SIP_HDR_P_CALLED_PARTY_ID = 3347, SIP_HDR_P_CHARGING_FUNCTION_ADDRESSES = 2171, SIP_HDR_P_CHARGING_VECTOR = 25, SIP_HDR_P_DCS_TRACE_PARTY_ID = 3027, SIP_HDR_P_DCS_OSPS = 1788, SIP_HDR_P_DCS_BILLING_INFO = 2017, SIP_HDR_P_DCS_LAES = 693, SIP_HDR_P_DCS_REDIRECT = 1872, SIP_HDR_P_EARLY_MEDIA = 2622, SIP_HDR_P_MEDIA_AUTHORIZATION = 1035, SIP_HDR_P_PREFERRED_IDENTITY = 1263, SIP_HDR_P_PROFILE_KEY = 1904, SIP_HDR_P_REFUSED_URI_LIST = 1047, SIP_HDR_P_SERVED_USER = 1588, SIP_HDR_P_USER_DATABASE = 2827, SIP_HDR_P_VISITED_NETWORK_ID = 3867, SIP_HDR_PATH = 2741, SIP_HDR_PERMISSION_MISSING = 1409, SIP_HDR_PRIORITY = 3520, SIP_HDR_PRIV_ANSWER_MODE = 2476, SIP_HDR_PRIVACY = 3150, SIP_HDR_PROXY_AUTHENTICATE = 116, SIP_HDR_PROXY_AUTHORIZATION = 2363, SIP_HDR_PROXY_REQUIRE = 3562, SIP_HDR_RACK = 2523, SIP_HDR_REASON = 3732, SIP_HDR_RECORD_ROUTE = 278, SIP_HDR_REFER_SUB = 2458, SIP_HDR_REFER_TO = 1521, SIP_HDR_REFERRED_BY = 3456, SIP_HDR_REJECT_CONTACT = 285, SIP_HDR_REPLACES = 2534, SIP_HDR_REPLY_TO = 2404, SIP_HDR_REQUEST_DISPOSITION = 3715, SIP_HDR_REQUIRE = 3905, SIP_HDR_RESOURCE_PRIORITY = 1643, SIP_HDR_RESPONSE_KEY = 1548, SIP_HDR_RETRY_AFTER = 409, SIP_HDR_ROUTE = 661, SIP_HDR_RSEQ = 445, SIP_HDR_SECURITY_CLIENT = 1358, SIP_HDR_SECURITY_SERVER = 811, SIP_HDR_SECURITY_VERIFY = 519, SIP_HDR_SERVER = 973, SIP_HDR_SERVICE_ROUTE = 1655, SIP_HDR_SESSION_EXPIRES = 1979, SIP_HDR_SIP_ETAG = 1997, SIP_HDR_SIP_IF_MATCH = 3056, SIP_HDR_SUBJECT = 1043, SIP_HDR_SUBSCRIPTION_STATE = 2884, SIP_HDR_SUPPORTED = 119, SIP_HDR_TARGET_DIALOG = 3450, SIP_HDR_TIMESTAMP = 938, SIP_HDR_TO = 1449, SIP_HDR_TRIGGER_CONSENT = 3180, SIP_HDR_UNSUPPORTED = 982, SIP_HDR_USER_AGENT = 4064, SIP_HDR_VIA = 3961, SIP_HDR_WARNING = 2108, SIP_HDR_WWW_AUTHENTICATE = 2763, SIP_HDR_NONE = -1 }; enum { SIP_T1 = 500, SIP_T2 = 4000, SIP_T4 = 5000, }; /** SIP Via header */ struct sip_via { struct pl sentby; struct sa addr; struct pl params; struct pl branch; struct pl val; enum sip_transp tp; }; /** SIP Address */ struct sip_addr { struct pl dname; struct pl auri; struct uri uri; struct pl params; }; /** SIP Tag address */ struct sip_taddr { struct pl dname; struct pl auri; struct uri uri; struct pl params; struct pl tag; struct pl val; }; /** SIP CSeq header */ struct sip_cseq { struct pl met; uint32_t num; }; /** SIP Header */ struct sip_hdr { struct le le; /**< Linked-list element */ struct le he; /**< Hash-table element */ struct pl name; /**< SIP Header name */ struct pl val; /**< SIP Header value */ enum sip_hdrid id; /**< SIP Header id (unique) */ }; /** SIP Message */ struct sip_msg { struct sa src; /**< Source network address */ struct sa dst; /**< Destination network address */ struct pl ver; /**< SIP Version number */ struct pl met; /**< Request method */ struct pl ruri; /**< Raw request URI */ struct uri uri; /**< Parsed request URI */ uint16_t scode; /**< Response status code */ struct pl reason; /**< Response reason phrase */ struct list hdrl; /**< List of SIP Headers (struct sip_hdr) */ struct sip_via via; /**< Parsed first Via header */ struct sip_taddr to; /**< Parsed To header */ struct sip_taddr from; /**< Parsed From header */ struct sip_cseq cseq; /**< Parsed CSeq header */ struct msg_ctype ctyp; /**< Content Type */ struct pl callid; /**< Cached Call-ID header */ struct pl maxfwd; /**< Cached Max-Forwards header */ struct pl expires; /**< Cached Expires header */ struct pl clen; /**< Cached Content-Length header */ struct hash *hdrht; /**< Hash-table with all SIP headers */ struct mbuf *mb; /**< Buffer containing the SIP message */ void *sock; /**< Transport socket */ uint64_t tag; /**< Opaque tag */ enum sip_transp tp; /**< SIP Transport */ bool req; /**< True if Request, False if Response */ }; /** SIP Loop-state */ struct sip_loopstate { uint32_t failc; uint16_t last_scode; }; /** SIP Contact */ struct sip_contact { const char *uri; const struct sa *addr; enum sip_transp tp; }; struct sip; struct sip_lsnr; struct sip_request; struct sip_strans; struct sip_auth; struct sip_dialog; struct sip_keepalive; struct dnsc; typedef bool(sip_msg_h)(const struct sip_msg *msg, void *arg); typedef int(sip_send_h)(enum sip_transp tp, const struct sa *src, const struct sa *dst, struct mbuf *mb, void *arg); typedef void(sip_resp_h)(int err, const struct sip_msg *msg, void *arg); typedef void(sip_cancel_h)(void *arg); typedef void(sip_exit_h)(void *arg); typedef int(sip_auth_h)(char **username, char **password, const char *realm, void *arg); typedef bool(sip_hdr_h)(const struct sip_hdr *hdr, const struct sip_msg *msg, void *arg); typedef void(sip_keepalive_h)(int err, void *arg); /* sip */ int sip_alloc(struct sip **sipp, struct dnsc *dnsc, uint32_t ctsz, uint32_t stsz, uint32_t tcsz, const char *software, sip_exit_h *exith, void *arg); void sip_close(struct sip *sip, bool force); int sip_listen(struct sip_lsnr **lsnrp, struct sip *sip, bool req, sip_msg_h *msgh, void *arg); int sip_debug(struct re_printf *pf, const struct sip *sip); int sip_send(struct sip *sip, void *sock, enum sip_transp tp, const struct sa *dst, struct mbuf *mb); /* transport */ int sip_transp_add(struct sip *sip, enum sip_transp tp, const struct sa *laddr, ...); void sip_transp_flush(struct sip *sip); bool sip_transp_isladdr(const struct sip *sip, enum sip_transp tp, const struct sa *laddr); const char *sip_transp_name(enum sip_transp tp); const char *sip_transp_param(enum sip_transp tp); uint16_t sip_transp_port(enum sip_transp tp, uint16_t port); int sip_transp_laddr(struct sip *sip, struct sa *laddr, enum sip_transp tp, const struct sa *dst); /* request */ int sip_request(struct sip_request **reqp, struct sip *sip, bool stateful, const char *met, int metl, const char *uri, int uril, const struct uri *route, struct mbuf *mb, size_t sortkey, sip_send_h *sendh, sip_resp_h *resph, void *arg); int sip_requestf(struct sip_request **reqp, struct sip *sip, bool stateful, const char *met, const char *uri, const struct uri *route, struct sip_auth *auth, sip_send_h *sendh, sip_resp_h *resph, void *arg, const char *fmt, ...); int sip_drequestf(struct sip_request **reqp, struct sip *sip, bool stateful, const char *met, struct sip_dialog *dlg, uint32_t cseq, struct sip_auth *auth, sip_send_h *sendh, sip_resp_h *resph, void *arg, const char *fmt, ...); void sip_request_cancel(struct sip_request *req); bool sip_request_loops(struct sip_loopstate *ls, uint16_t scode); void sip_loopstate_reset(struct sip_loopstate *ls); /* reply */ int sip_strans_alloc(struct sip_strans **stp, struct sip *sip, const struct sip_msg *msg, sip_cancel_h *cancelh, void *arg); int sip_strans_reply(struct sip_strans **stp, struct sip *sip, const struct sip_msg *msg, const struct sa *dst, uint16_t scode, struct mbuf *mb); int sip_treplyf(struct sip_strans **stp, struct mbuf **mbp, struct sip *sip, const struct sip_msg *msg, bool rec_route, uint16_t scode, const char *reason, const char *fmt, ...); int sip_treply(struct sip_strans **stp, struct sip *sip, const struct sip_msg *msg, uint16_t scode, const char *reason); int sip_replyf(struct sip *sip, const struct sip_msg *msg, uint16_t scode, const char *reason, const char *fmt, ...); int sip_reply(struct sip *sip, const struct sip_msg *msg, uint16_t scode, const char *reason); void sip_reply_addr(struct sa *addr, const struct sip_msg *msg, bool rport); /* auth */ int sip_auth_authenticate(struct sip_auth *auth, const struct sip_msg *msg); int sip_auth_alloc(struct sip_auth **authp, sip_auth_h *authh, void *arg, bool ref); void sip_auth_reset(struct sip_auth *auth); /* contact */ void sip_contact_set(struct sip_contact *contact, const char *uri, const struct sa *addr, enum sip_transp tp); int sip_contact_print(struct re_printf *pf, const struct sip_contact *contact); /* dialog */ int sip_dialog_alloc(struct sip_dialog **dlgp, const char *uri, const char *to_uri, const char *from_name, const char *from_uri, const char *routev[], uint32_t routec); int sip_dialog_accept(struct sip_dialog **dlgp, const struct sip_msg *msg); int sip_dialog_create(struct sip_dialog *dlg, const struct sip_msg *msg); int sip_dialog_fork(struct sip_dialog **dlgp, struct sip_dialog *odlg, const struct sip_msg *msg); int sip_dialog_update(struct sip_dialog *dlg, const struct sip_msg *msg); bool sip_dialog_rseq_valid(struct sip_dialog *dlg, const struct sip_msg *msg); const char *sip_dialog_callid(const struct sip_dialog *dlg); uint32_t sip_dialog_lseq(const struct sip_dialog *dlg); bool sip_dialog_established(const struct sip_dialog *dlg); bool sip_dialog_cmp(const struct sip_dialog *dlg, const struct sip_msg *msg); bool sip_dialog_cmp_half(const struct sip_dialog *dlg, const struct sip_msg *msg); /* msg */ int sip_msg_decode(struct sip_msg **msgp, struct mbuf *mb); const struct sip_hdr *sip_msg_hdr(const struct sip_msg *msg, enum sip_hdrid id); const struct sip_hdr *sip_msg_hdr_apply(const struct sip_msg *msg, bool fwd, enum sip_hdrid id, sip_hdr_h *h, void *arg); const struct sip_hdr *sip_msg_xhdr(const struct sip_msg *msg, const char *name); const struct sip_hdr *sip_msg_xhdr_apply(const struct sip_msg *msg, bool fwd, const char *name, sip_hdr_h *h, void *arg); uint32_t sip_msg_hdr_count(const struct sip_msg *msg, enum sip_hdrid id); uint32_t sip_msg_xhdr_count(const struct sip_msg *msg, const char *name); bool sip_msg_hdr_has_value(const struct sip_msg *msg, enum sip_hdrid id, const char *value); bool sip_msg_xhdr_has_value(const struct sip_msg *msg, const char *name, const char *value); struct tcp_conn *sip_msg_tcpconn(const struct sip_msg *msg); void sip_msg_dump(const struct sip_msg *msg); int sip_addr_decode(struct sip_addr *addr, const struct pl *pl); int sip_via_decode(struct sip_via *via, const struct pl *pl); int sip_cseq_decode(struct sip_cseq *cseq, const struct pl *pl); /* keepalive */ int sip_keepalive_start(struct sip_keepalive **kap, struct sip *sip, const struct sip_msg *msg, uint32_t interval, sip_keepalive_h *kah, void *arg);