|
@@ -49,83 +49,72 @@ typedef enum {
|
|
|
#define PATH_PREFIX "Path: <sip:"
|
|
|
#define PATH_PREFIX_LEN (sizeof(PATH_PREFIX)-1)
|
|
|
|
|
|
-#define PATH_LR_PARAM ";lr"
|
|
|
-#define PATH_LR_PARAM_LEN (sizeof(PATH_LR_PARAM)-1)
|
|
|
-
|
|
|
-#define PATH_RC_PARAM ";received="
|
|
|
-#define PATH_RC_PARAM_LEN (sizeof(PATH_RC_PARAM)-1)
|
|
|
-
|
|
|
-#define PATH_OB_PARAM ";ob"
|
|
|
-#define PATH_OB_PARAM_LEN (sizeof(PATH_OB_PARAM)-1)
|
|
|
-
|
|
|
-#define PATH_CRLF ">\r\n"
|
|
|
-#define PATH_CRLF_LEN (sizeof(PATH_CRLF)-1)
|
|
|
-
|
|
|
-#define ALLOC_AND_COPY_PATH_HDR() \
|
|
|
- if ((suffix = pkg_malloc(suffix_len)) == NULL) { \
|
|
|
- LM_ERR("no pkg memory left for suffix\n"); \
|
|
|
- goto out1; \
|
|
|
- } \
|
|
|
- memcpy(suffix, PATH_LR_PARAM, PATH_LR_PARAM_LEN);
|
|
|
-
|
|
|
-static int prepend_path(struct sip_msg* _m, str *user, path_param_t param)
|
|
|
+const static char *proto_strings[] = {
|
|
|
+ [PROTO_TCP] = "%3Btransport%3Dtcp",
|
|
|
+ [PROTO_TLS] = "%3Btransport%3Dtls",
|
|
|
+ [PROTO_SCTP] = "%3Btransport%3Dsctp",
|
|
|
+ [PROTO_WS] = "%3Btransport%3Dws",
|
|
|
+ [PROTO_WSS] = "%3Btransport%3Dws",
|
|
|
+};
|
|
|
+
|
|
|
+static int prepend_path(struct sip_msg* _m, str *user, path_param_t param, str *add_params)
|
|
|
{
|
|
|
struct lump *l;
|
|
|
- char *prefix, *suffix, *crlf;
|
|
|
+ char *prefix, *suffix, *cp;
|
|
|
+ const char *proto_str;
|
|
|
int prefix_len, suffix_len;
|
|
|
struct hdr_field *hf;
|
|
|
- str rcv_addr = {0, 0};
|
|
|
- char *src_ip;
|
|
|
-
|
|
|
- prefix = suffix = crlf = 0;
|
|
|
|
|
|
- prefix_len = PATH_PREFIX_LEN + (user->len ? (user->len+1) : 0);
|
|
|
- prefix = pkg_malloc(prefix_len);
|
|
|
- if (!prefix) {
|
|
|
- LM_ERR("no pkg memory left for prefix\n");
|
|
|
+ /* maximum possible length of suffix */
|
|
|
+ suffix_len = strlen(";lr;received=sip::12345%3Btransport%3Dsctp;ob;>\r\n")
|
|
|
+ + IP_ADDR_MAX_STR_SIZE + (add_params ? add_params->len : 0) + 1;
|
|
|
+
|
|
|
+ cp = suffix = pkg_malloc(suffix_len);
|
|
|
+ if (!suffix) {
|
|
|
+ LM_ERR("no pkg memory left for suffix\n");
|
|
|
goto out1;
|
|
|
}
|
|
|
- memcpy(prefix, PATH_PREFIX, PATH_PREFIX_LEN);
|
|
|
- if (user->len) {
|
|
|
- memcpy(prefix + PATH_PREFIX_LEN, user->s, user->len);
|
|
|
- memcpy(prefix + prefix_len - 1, "@", 1);
|
|
|
- }
|
|
|
+
|
|
|
+ cp += sprintf(cp, ";lr");
|
|
|
|
|
|
switch(param) {
|
|
|
default:
|
|
|
- suffix_len = PATH_LR_PARAM_LEN;
|
|
|
- ALLOC_AND_COPY_PATH_HDR();
|
|
|
break;
|
|
|
case PATH_PARAM_RECEIVED:
|
|
|
- suffix_len = PATH_LR_PARAM_LEN + PATH_RC_PARAM_LEN;
|
|
|
- ALLOC_AND_COPY_PATH_HDR();
|
|
|
- memcpy(suffix + PATH_LR_PARAM_LEN, PATH_RC_PARAM,
|
|
|
- PATH_RC_PARAM_LEN);
|
|
|
+ if (_m->rcv.proto < (sizeof(proto_strings) / sizeof(*proto_strings)))
|
|
|
+ proto_str = proto_strings[(unsigned int) _m->rcv.proto];
|
|
|
+ else
|
|
|
+ proto_str = NULL;
|
|
|
+
|
|
|
+ cp += sprintf(cp, ";received=sip:%s:%hu%s", ip_addr2a(&_m->rcv.src_ip),
|
|
|
+ _m->rcv.src_port, proto_str ? : "");
|
|
|
break;
|
|
|
case PATH_PARAM_OB:
|
|
|
- suffix_len = PATH_LR_PARAM_LEN + PATH_OB_PARAM_LEN;
|
|
|
- ALLOC_AND_COPY_PATH_HDR();
|
|
|
- memcpy(suffix + PATH_LR_PARAM_LEN, PATH_OB_PARAM,
|
|
|
- PATH_OB_PARAM_LEN);
|
|
|
+ cp += sprintf(cp, ";ob");
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- crlf = pkg_malloc(PATH_CRLF_LEN);
|
|
|
- if (!crlf) {
|
|
|
- LM_ERR("no pkg memory left for crlf\n");
|
|
|
- goto out1;
|
|
|
+ if (add_params && add_params->len)
|
|
|
+ cp += sprintf(cp, ";%.*s", add_params->len, add_params->s);
|
|
|
+
|
|
|
+ cp += sprintf(cp, ">\r\n");
|
|
|
+
|
|
|
+ prefix_len = PATH_PREFIX_LEN + (user ? user->len : 0) + 2;
|
|
|
+ prefix = pkg_malloc(prefix_len);
|
|
|
+ if (!prefix) {
|
|
|
+ LM_ERR("no pkg memory left for prefix\n");
|
|
|
+ goto out2;
|
|
|
}
|
|
|
- memcpy(crlf, PATH_CRLF, PATH_CRLF_LEN);
|
|
|
+ if (user && user->len)
|
|
|
+ prefix_len = sprintf(prefix, PATH_PREFIX "%.*s@", user->len, user->s);
|
|
|
+ else
|
|
|
+ prefix_len = sprintf(prefix, PATH_PREFIX);
|
|
|
|
|
|
if (parse_headers(_m, HDR_PATH_F, 0) < 0) {
|
|
|
LM_ERR("failed to parse message for Path header\n");
|
|
|
- goto out1;
|
|
|
- }
|
|
|
- for (hf = _m->headers; hf; hf = hf->next) {
|
|
|
- if (hf->type == HDR_PATH_T) {
|
|
|
- break;
|
|
|
- }
|
|
|
+ goto out3;
|
|
|
}
|
|
|
+ hf = get_hdr(_m, HDR_PATH_T);
|
|
|
if (hf)
|
|
|
/* path found, add ours in front of that */
|
|
|
l = anchor_lump(_m, hf->name.s - _m->buf, 0, 0);
|
|
@@ -134,60 +123,24 @@ static int prepend_path(struct sip_msg* _m, str *user, path_param_t param)
|
|
|
l = anchor_lump(_m, _m->unparsed - _m->buf, 0, 0);
|
|
|
if (!l) {
|
|
|
LM_ERR("failed to get anchor\n");
|
|
|
- goto out1;
|
|
|
+ goto out3;
|
|
|
}
|
|
|
|
|
|
l = insert_new_lump_before(l, prefix, prefix_len, 0);
|
|
|
- if (!l) goto out1;
|
|
|
+ if (!l) goto out3;
|
|
|
l = insert_subst_lump_before(l, SUBST_SND_ALL, 0);
|
|
|
if (!l) goto out2;
|
|
|
- l = insert_new_lump_before(l, suffix, suffix_len, 0);
|
|
|
+ l = insert_new_lump_before(l, suffix, cp - suffix, 0);
|
|
|
if (!l) goto out2;
|
|
|
- if (param == PATH_PARAM_RECEIVED) {
|
|
|
- /* TODO: agranig: optimize this one! */
|
|
|
- src_ip = ip_addr2a(&_m->rcv.src_ip);
|
|
|
- rcv_addr.s = pkg_malloc(6 + IP_ADDR_MAX_STR_SIZE + 24); /* sip:<ip>:<port>%3Btransport%3Dsctp\0 */
|
|
|
- if(!rcv_addr.s) {
|
|
|
- LM_ERR("no pkg memory left for receive-address\n");
|
|
|
- goto out3;
|
|
|
- }
|
|
|
- switch (_m->rcv.proto) {
|
|
|
- case PROTO_UDP:
|
|
|
- rcv_addr.len = snprintf(rcv_addr.s, 6 + IP_ADDR_MAX_STR_SIZE + 4, "sip:%s:%u", src_ip, _m->rcv.src_port);
|
|
|
- break;
|
|
|
- case PROTO_TCP:
|
|
|
- rcv_addr.len = snprintf(rcv_addr.s, 6 + IP_ADDR_MAX_STR_SIZE + 22, "sip:%s:%u%%3Btransport%%3Dtcp", src_ip, _m->rcv.src_port);
|
|
|
- break;
|
|
|
- case PROTO_TLS:
|
|
|
- rcv_addr.len = snprintf(rcv_addr.s, 6 + IP_ADDR_MAX_STR_SIZE + 22, "sip:%s:%u%%3Btransport%%3Dtls", src_ip, _m->rcv.src_port);
|
|
|
- break;
|
|
|
- case PROTO_SCTP:
|
|
|
- rcv_addr.len = snprintf(rcv_addr.s, 6 + IP_ADDR_MAX_STR_SIZE + 23, "sip:%s:%u%%3Btransport%%3Dsctp", src_ip, _m->rcv.src_port);
|
|
|
- break;
|
|
|
- case PROTO_WS:
|
|
|
- case PROTO_WSS:
|
|
|
- rcv_addr.len = snprintf(rcv_addr.s, 6 + IP_ADDR_MAX_STR_SIZE + 21, "sip:%s:%u%%3Btransport%%3Dws", src_ip, _m->rcv.src_port);
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- l = insert_new_lump_before(l, rcv_addr.s, rcv_addr.len, 0);
|
|
|
- if (!l) goto out3;
|
|
|
- }
|
|
|
- l = insert_new_lump_before(l, crlf, CRLF_LEN+1, 0);
|
|
|
- if (!l) goto out4;
|
|
|
-
|
|
|
+
|
|
|
return 1;
|
|
|
-
|
|
|
-out1:
|
|
|
- if (prefix) pkg_free(prefix);
|
|
|
-out2:
|
|
|
- if (suffix) pkg_free(suffix);
|
|
|
-out3:
|
|
|
- if (rcv_addr.s) pkg_free(rcv_addr.s);
|
|
|
-out4:
|
|
|
- if (crlf) pkg_free(crlf);
|
|
|
|
|
|
- LM_ERR("failed to insert prefix lump\n");
|
|
|
+out3:
|
|
|
+ pkg_free(prefix);
|
|
|
+out2:
|
|
|
+ pkg_free(suffix);
|
|
|
+out1:
|
|
|
+ LM_ERR("failed to insert Path header\n");
|
|
|
|
|
|
return -1;
|
|
|
}
|
|
@@ -215,7 +168,7 @@ int add_path(struct sip_msg* _msg, char* _a, char* _b)
|
|
|
param = PATH_PARAM_OB;
|
|
|
}
|
|
|
|
|
|
- ret = prepend_path(_msg, &user, param);
|
|
|
+ ret = prepend_path(_msg, &user, param, NULL);
|
|
|
|
|
|
if (user.s != NULL)
|
|
|
pkg_free(user.s);
|
|
@@ -227,9 +180,17 @@ int add_path(struct sip_msg* _msg, char* _a, char* _b)
|
|
|
* Prepend own uri to Path header and take care of given
|
|
|
* user.
|
|
|
*/
|
|
|
-int add_path_usr(struct sip_msg* _msg, char* _usr, char* _b)
|
|
|
+int add_path_usr(struct sip_msg* _msg, char* _usr, char* _parms)
|
|
|
{
|
|
|
- return prepend_path(_msg, (str*)_usr, PATH_PARAM_NONE);
|
|
|
+ str user = {0,0};
|
|
|
+ str parms = {0,0};
|
|
|
+
|
|
|
+ if (_usr)
|
|
|
+ get_str_fparam(&user, _msg, (fparam_t *) _usr);
|
|
|
+ if (_parms)
|
|
|
+ get_str_fparam(&parms, _msg, (fparam_t *) _parms);
|
|
|
+
|
|
|
+ return prepend_path(_msg, &user, PATH_PARAM_NONE, &parms);
|
|
|
}
|
|
|
|
|
|
/*! \brief
|
|
@@ -238,17 +199,24 @@ int add_path_usr(struct sip_msg* _msg, char* _usr, char* _b)
|
|
|
*/
|
|
|
int add_path_received(struct sip_msg* _msg, char* _a, char* _b)
|
|
|
{
|
|
|
- str user = {0,0};
|
|
|
- return prepend_path(_msg, &user, PATH_PARAM_RECEIVED);
|
|
|
+ return prepend_path(_msg, NULL, PATH_PARAM_RECEIVED, NULL);
|
|
|
}
|
|
|
|
|
|
/*! \brief
|
|
|
* Prepend own uri to Path header and append received address as
|
|
|
* "received"-param to that uri and take care of given user.
|
|
|
*/
|
|
|
-int add_path_received_usr(struct sip_msg* _msg, char* _usr, char* _b)
|
|
|
+int add_path_received_usr(struct sip_msg* _msg, char* _usr, char* _parms)
|
|
|
{
|
|
|
- return prepend_path(_msg, (str*)_usr, PATH_PARAM_RECEIVED);
|
|
|
+ str user = {0,0};
|
|
|
+ str parms = {0,0};
|
|
|
+
|
|
|
+ if (_usr)
|
|
|
+ get_str_fparam(&user, _msg, (fparam_t *) _usr);
|
|
|
+ if (_parms)
|
|
|
+ get_str_fparam(&parms, _msg, (fparam_t *) _parms);
|
|
|
+
|
|
|
+ return prepend_path(_msg, &user, PATH_PARAM_RECEIVED, &parms);
|
|
|
}
|
|
|
|
|
|
/*! \brief
|