else
return SIP_DEFAULT_SERV; /* 5060 */
}
+
+/**@SIP_HEADER sip_identity Identity Header
+ *
+ * The Identity header field specifies the "logical" recipient of the
+ * request. It is defined in @RFC8224 with semantics shown below,
+ * though for now it's parsed to a single 'value' field.
+ *
+ * @code
+ * Identity = "Identity" HCOLON signed-identity-digest SEMI
+ * ident-info *( SEMI ident-info-params )
+ * signed-identity-digest = 1*(base64-char / ".")
+ * ident-info = "info" EQUAL ident-info-uri
+ * ident-info-uri = LAQUOT absoluteURI RAQUOT
+ * ident-info-params = ident-info-alg / ident-type /
+ * ident-info-extension
+ * ident-info-alg = "alg" EQUAL token
+ * ident-type = "ppt" EQUAL token
+ * ident-info-extension = generic-param
+ *
+ * base64-char = ALPHA / DIGIT / "/" / "+"
+ * @endcode
+ *
+ * The parsed Identity header is stored in #sip_identity_t structure.
+ */
+
+/**@ingroup sip_identity
+ * @typedef typedef struct sip_identity_s sip_identity_t;
+ *
+ * The structure #sip_identity_t contains representation of @Identity header.
+ *
+ * The #sip_identity_t is defined as follows:
+ * @code
+ * typedef struct {
+ * sip_common_t id_common[1]; // Common fragment info
+ * sip_error_t *id_next; // Link to next (dummy)
+ * char const *id_value; // Identity
+ * char const *id_info; // Info param containing URL of the cert, with no '<','>'
+ * } sip_identity_t;
+ * @endcode
+ *
+ */
+
+static msg_xtra_f sip_identity_dup_xtra;
+static msg_dup_f sip_identity_dup_one;
+static msg_update_f sip_identity_update;
+
+msg_hclass_t sip_identity_class[] =
+SIP_HEADER_CLASS(identity, "Identity", "", id_common, single, identity);
+
+issize_t sip_identity_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
+{
+ sip_identity_t *id = (sip_identity_t *)h;
+ char const *p = NULL, *pp = NULL, *ppp = NULL, *ib = NULL, *ie = NULL;
+ size_t len = 0;
+
+ id->id_value = strdup(s);
+ id->id_info = NULL;
+
+ p = strstr(s, "info=");
+ if (p) {
+ ib = p + 5;
+ ie = strchr(p, ';');
+ pp = strchr(p, '<');
+
+ if (!ie) return 0;
+
+ if (pp && pp < ie) {
+
+ // info= with opening '<'
+ // must contain closing '>' before ';'
+ ppp = strchr(pp, '>');
+ if (!ppp || ppp > ie) {
+ return 0;
+ } else {
+ ib = pp + 1;
+ ie = ppp - 1;
+ }
+ }
+
+ len = ie - ib + 1;
+ id->id_info = strndup(ib, len);
+ }
+
+ return 0;
+}
+
+issize_t sip_identity_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
+{
+ sip_identity_t const *id = (sip_identity_t *)h;
+
+ return snprintf(b, bsiz, "%s", id->id_value);
+}
+
+isize_t sip_identity_dup_xtra(sip_header_t const *h, isize_t offset)
+{
+ sip_identity_t const *id = (sip_identity_t *)h;
+ return offset + MSG_STRING_SIZE(id->id_value);
+}
+
+char *sip_identity_dup_one(sip_header_t *dst, sip_header_t const *src,
+ char *b, isize_t xtra)
+{
+ sip_identity_t *id = (sip_identity_t *)dst;
+ sip_identity_t const *o = (sip_identity_t *)src;
+
+ MSG_STRING_DUP(b, id->id_value, o->id_value);
+
+ return b;
+}
+
+static int sip_identity_update(msg_common_t *h,
+ char const *name, isize_t namelen,
+ char const *value)
+{
+ sip_identity_t *id = (sip_identity_t *)h;
+
+ id->id_value = strdup(value);
+ return 0;
+}
/* RFC 3323 - @Privacy */
typedef struct sip_privacy_s sip_privacy_t;
+/* SIP Identity Header, e.g. STIR-Shaken SIP Identity Header, RFC 8224 */
+typedef struct sip_identity_s sip_identity_t;
+
/* RFC 3327 - @Path */
typedef struct sip_route_s sip_path_t;
sip_to_t *sip_to; /**< To (t) */
sip_call_id_t *sip_call_id; /**< Call-ID (i) */
sip_cseq_t *sip_cseq; /**< CSeq */
+ sip_identity_t *sip_identity; /**< Identity */
sip_contact_t *sip_contact; /**< Contact (m) */
sip_rseq_t *sip_rseq; /**< RSeq */
sip_rack_t *sip_rack; /**< RAck */
char const *cs_method_name; /**< Method name */
};
+/**@ingroup sip_identity
+ * @brief Structure for @Identity SIP header.
+ */
+struct sip_identity_s
+{
+ sip_common_t id_common[1]; /**< Common fragment info */
+ sip_error_t *id_next; /**< Link to next (dummy) */
+ char const *id_value; /**< Identity text as shown in SIP Header */
+ char const *id_info; /**< Info param containing URL of the cert */
+};
+
/**@ingroup sip_contact
* @brief Structure for @Contact header field.
*/
sip_separator_t sh_separator[1];
sip_payload_t sh_payload[1];
+ sip_identity_t sh_identity[1];
};
SOFIA_END_DECLS