|
@@ -37,6 +37,7 @@
|
|
|
#include "dprint.h"
|
|
|
#include "config.h"
|
|
|
#include "parser/parser_f.h"
|
|
|
+#include "parser/parse_uri.h"
|
|
|
#include "parser/msg_parser.h"
|
|
|
#include "ut.h"
|
|
|
#include "hash_func.h"
|
|
@@ -719,3 +720,160 @@ int msg_get_src_addr(sip_msg_t *msg, str *uri, int mode)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * add alias parameter with encoding of source address
|
|
|
+ * - nuri->s must point to a buffer of nuri->len size
|
|
|
+ */
|
|
|
+int uri_add_rcv_alias(sip_msg_t *msg, str *uri, str *nuri)
|
|
|
+{
|
|
|
+ char* p;
|
|
|
+ str ip, port;
|
|
|
+ int len;
|
|
|
+
|
|
|
+ if (msg==NULL || uri==NULL || nuri==NULL) {
|
|
|
+ LM_ERR("invalid parameter value\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ ip.s = ip_addr2a(&msg->rcv.src_ip);
|
|
|
+ ip.len = strlen(ip.s);
|
|
|
+
|
|
|
+ port.s = int2str(msg->rcv.src_port, &port.len);
|
|
|
+
|
|
|
+ /*uri;alias=[ip]~port~proto*/
|
|
|
+ len = uri->len+ip.len+port.len+12;
|
|
|
+ if(len>=nuri->len) {
|
|
|
+ LM_ERR("not enough space for new uri: %d\n", len);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ p = nuri->s;
|
|
|
+ memcpy(p, uri->s, uri->len);
|
|
|
+ p += uri->len;
|
|
|
+ memcpy(p, ";alias=", 7);
|
|
|
+ p += 7;
|
|
|
+ if (msg->rcv.src_ip.af == AF_INET6)
|
|
|
+ *p++ = '[';
|
|
|
+ memcpy(p, ip.s, ip.len);
|
|
|
+ p += ip.len;
|
|
|
+ if (msg->rcv.src_ip.af == AF_INET6)
|
|
|
+ *p++ = ']';
|
|
|
+ *p++ = '~';
|
|
|
+ memcpy(p, port.s, port.len);
|
|
|
+ p += port.len;
|
|
|
+ *p++ = '~';
|
|
|
+ *p++ = msg->rcv.proto + '0';
|
|
|
+ nuri->len = p - nuri->s;
|
|
|
+ nuri->s[nuri->len] = '\0';
|
|
|
+
|
|
|
+ LM_DBG("encoded <%.*s> => [%.*s]\n",
|
|
|
+ uri->len, uri->s, nuri->len, nuri->s);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * restore from alias parameter with encoding of source address
|
|
|
+ * - nuri->s must point to a buffer of nuri->len size
|
|
|
+ * - suri->s must point to a buffer of suri->len size
|
|
|
+ */
|
|
|
+int uri_restore_rcv_alias(str *uri, str *nuri, str *suri)
|
|
|
+{
|
|
|
+ char* p;
|
|
|
+ str skip;
|
|
|
+ str ip, port, sproto;
|
|
|
+ int proto;
|
|
|
+
|
|
|
+ if (uri==NULL || nuri==NULL || suri==NULL) {
|
|
|
+ LM_ERR("invalid parameter value\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* sip:x;alias=1.1.1.1~0~0 */
|
|
|
+ if(uri->len < 23) {
|
|
|
+ /* no alias possible */
|
|
|
+ return -2;
|
|
|
+ }
|
|
|
+ p = uri->s + uri->len-18;
|
|
|
+ skip.s = 0;
|
|
|
+ while(p>uri->s+5) {
|
|
|
+ if(strncmp(p, ";alias=", 7)==0) {
|
|
|
+ skip.s = p;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ p--;
|
|
|
+ }
|
|
|
+ if(skip.s==0) {
|
|
|
+ /* alias parameter not found */
|
|
|
+ return -2;
|
|
|
+ }
|
|
|
+ p += 7;
|
|
|
+ ip.s = p;
|
|
|
+ p = (char*)memchr(ip.s, '~', (size_t)(uri->s+uri->len-ip.s));
|
|
|
+ if(p==NULL) {
|
|
|
+ /* proper alias parameter not found */
|
|
|
+ return -2;
|
|
|
+ }
|
|
|
+ ip.len = p - ip.s;
|
|
|
+ p++;
|
|
|
+ if(p>=uri->s+uri->len) {
|
|
|
+ /* proper alias parameter not found */
|
|
|
+ return -2;
|
|
|
+ }
|
|
|
+ port.s = p;
|
|
|
+ p = (char*)memchr(port.s, '~', (size_t)(uri->s+uri->len-port.s));
|
|
|
+ if(p==NULL) {
|
|
|
+ /* proper alias parameter not found */
|
|
|
+ return -2;
|
|
|
+ }
|
|
|
+ port.len = p - port.s;
|
|
|
+ p++;
|
|
|
+ if(p>=uri->s+uri->len) {
|
|
|
+ /* proper alias parameter not found */
|
|
|
+ return -2;
|
|
|
+ }
|
|
|
+ proto = (int)(*p - '0');
|
|
|
+ p++;
|
|
|
+
|
|
|
+ if(p!=uri->s+uri->len && *p!=';') {
|
|
|
+ /* proper alias parameter not found */
|
|
|
+ return -2;
|
|
|
+ }
|
|
|
+ skip.len = (int)(p - skip.s);
|
|
|
+
|
|
|
+ if(suri->len<=4+ip.len+1+port.len+11/*;transport=*/+4) {
|
|
|
+ LM_ERR("address buffer too small\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ if(nuri->len<=uri->len - skip.len) {
|
|
|
+ LM_ERR("uri buffer too small\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ p = nuri->s;
|
|
|
+ memcpy(p, uri->s, (size_t)(skip.s-uri->s));
|
|
|
+ p += skip.s-uri->s;
|
|
|
+ memcpy(p, skip.s+skip.len, (size_t)(uri->s+uri->len - skip.s - skip.len));
|
|
|
+ p += uri->s+uri->len - skip.s - skip.len;
|
|
|
+ nuri->len = p - nuri->s;
|
|
|
+
|
|
|
+ p = suri->s;
|
|
|
+ strncpy(p, "sip:", 4);
|
|
|
+ p += 4;
|
|
|
+ strncpy(p, ip.s, ip.len);
|
|
|
+ p += ip.len;
|
|
|
+ *p++ = ':';
|
|
|
+ strncpy(p, port.s, port.len);
|
|
|
+ p += port.len;
|
|
|
+ proto_type_to_str((unsigned short)proto, &sproto);
|
|
|
+ if(sproto.len>0 && proto!=PROTO_UDP) {
|
|
|
+ strncpy(p, ";transport=", 11);
|
|
|
+ p += 11;
|
|
|
+ strncpy(p, sproto.s, sproto.len);
|
|
|
+ p += sproto.len;
|
|
|
+ }
|
|
|
+ suri->len = p - suri->s;
|
|
|
+
|
|
|
+ LM_DBG("decoded <%.*s> => [%.*s] [%.*s]\n",
|
|
|
+ uri->len, uri->s, nuri->len, nuri->s, suri->len, suri->s);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|