00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00033 #include <string.h>
00034 #include <stdio.h>
00035
00036 #include "../../mem/mem.h"
00037 #include "../../data_lump.h"
00038 #include "../../parser/parse_param.h"
00039 #include "../../dset.h"
00040
00041 #include "path.h"
00042 #include "path_mod.h"
00043
00044 #define PATH_PREFIX "Path: <sip:"
00045 #define PATH_PREFIX_LEN (sizeof(PATH_PREFIX)-1)
00046
00047 #define PATH_LR_PARAM ";lr"
00048 #define PATH_LR_PARAM_LEN (sizeof(PATH_LR_PARAM)-1)
00049
00050 #define PATH_RC_PARAM ";received="
00051 #define PATH_RC_PARAM_LEN (sizeof(PATH_RC_PARAM)-1)
00052
00053 #define PATH_CRLF ">\r\n"
00054 #define PATH_CRLF_LEN (sizeof(PATH_CRLF)-1)
00055
00056 static int prepend_path(struct sip_msg* _m, str *user, int recv)
00057 {
00058 struct lump *l;
00059 char *prefix, *suffix, *crlf;
00060 int prefix_len, suffix_len;
00061 struct hdr_field *hf;
00062 str rcv_addr = {0, 0};
00063 char *src_ip;
00064
00065 prefix = suffix = crlf = 0;
00066
00067 prefix_len = PATH_PREFIX_LEN + (user->len ? (user->len+1) : 0);
00068 prefix = pkg_malloc(prefix_len);
00069 if (!prefix) {
00070 LM_ERR("no pkg memory left for prefix\n");
00071 goto out1;
00072 }
00073 memcpy(prefix, PATH_PREFIX, PATH_PREFIX_LEN);
00074 if (user->len) {
00075 memcpy(prefix + PATH_PREFIX_LEN, user->s, user->len);
00076 memcpy(prefix + prefix_len - 1, "@", 1);
00077 }
00078
00079 suffix_len = PATH_LR_PARAM_LEN + (recv ? PATH_RC_PARAM_LEN : 0);
00080 suffix = pkg_malloc(suffix_len);
00081 if (!suffix) {
00082 LM_ERR("no pkg memory left for suffix\n");
00083 goto out1;
00084 }
00085 memcpy(suffix, PATH_LR_PARAM, PATH_LR_PARAM_LEN);
00086 if(recv)
00087 memcpy(suffix+PATH_LR_PARAM_LEN, PATH_RC_PARAM, PATH_RC_PARAM_LEN);
00088
00089 crlf = pkg_malloc(PATH_CRLF_LEN);
00090 if (!crlf) {
00091 LM_ERR("no pkg memory left for crlf\n");
00092 goto out1;
00093 }
00094 memcpy(crlf, PATH_CRLF, PATH_CRLF_LEN);
00095
00096 if (parse_headers(_m, HDR_PATH_F, 0) < 0) {
00097 LM_ERR("failed to parse message for Path header\n");
00098 goto out1;
00099 }
00100 for (hf = _m->headers; hf; hf = hf->next) {
00101 if (hf->type == HDR_PATH_T) {
00102 break;
00103 }
00104 }
00105 if (hf)
00106
00107 l = anchor_lump(_m, hf->name.s - _m->buf, 0, 0);
00108 else
00109
00110 l = anchor_lump(_m, _m->unparsed - _m->buf, 0, 0);
00111 if (!l) {
00112 LM_ERR("failed to get anchor\n");
00113 goto out1;
00114 }
00115
00116 l = insert_new_lump_before(l, prefix, prefix_len, 0);
00117 if (!l) goto out1;
00118 l = insert_subst_lump_before(l, SUBST_SND_ALL, 0);
00119 if (!l) goto out2;
00120 l = insert_new_lump_before(l, suffix, suffix_len, 0);
00121 if (!l) goto out2;
00122 if (recv) {
00123
00124 src_ip = ip_addr2a(&_m->rcv.src_ip);
00125 rcv_addr.s = pkg_malloc(6 + IP_ADDR_MAX_STR_SIZE + 22);
00126 if(!rcv_addr.s) {
00127 LM_ERR("no pkg memory left for receive-address\n");
00128 goto out3;
00129 }
00130 switch (_m->rcv.proto) {
00131 case PROTO_UDP:
00132 rcv_addr.len = snprintf(rcv_addr.s, 6 + IP_ADDR_MAX_STR_SIZE + 6, "\"sip:%s:%u\"", src_ip, _m->rcv.src_port);
00133 break;
00134 case PROTO_TCP:
00135 rcv_addr.len = snprintf(rcv_addr.s, 6 + IP_ADDR_MAX_STR_SIZE + 20, "\"sip:%s:%u;transport=tcp\"", src_ip, _m->rcv.src_port);
00136 break;
00137 case PROTO_TLS:
00138 rcv_addr.len = snprintf(rcv_addr.s, 6 + IP_ADDR_MAX_STR_SIZE + 20, "\"sip:%s:%u;transport=tls\"", src_ip, _m->rcv.src_port);
00139 break;
00140 case PROTO_SCTP:
00141 rcv_addr.len = snprintf(rcv_addr.s, 6 + IP_ADDR_MAX_STR_SIZE + 21, "\"sip:%s:%u;transport=sctp\"", src_ip, _m->rcv.src_port);
00142 break;
00143 }
00144
00145 l = insert_new_lump_before(l, rcv_addr.s, rcv_addr.len, 0);
00146 if (!l) goto out3;
00147 }
00148 l = insert_new_lump_before(l, crlf, CRLF_LEN+1, 0);
00149 if (!l) goto out4;
00150
00151 return 1;
00152
00153 out1:
00154 if (prefix) pkg_free(prefix);
00155 out2:
00156 if (suffix) pkg_free(suffix);
00157 out3:
00158 if (rcv_addr.s) pkg_free(rcv_addr.s);
00159 out4:
00160 if (crlf) pkg_free(crlf);
00161
00162 LM_ERR("failed to insert prefix lump\n");
00163
00164 return -1;
00165 }
00166
00170 int add_path(struct sip_msg* _msg, char* _a, char* _b)
00171 {
00172 str user = {0,0};
00173 return prepend_path(_msg, &user, 0);
00174 }
00175
00180 int add_path_usr(struct sip_msg* _msg, char* _usr, char* _b)
00181 {
00182 return prepend_path(_msg, (str*)_usr, 0);
00183 }
00184
00189 int add_path_received(struct sip_msg* _msg, char* _a, char* _b)
00190 {
00191 str user = {0,0};
00192 return prepend_path(_msg, &user, 1);
00193 }
00194
00199 int add_path_received_usr(struct sip_msg* _msg, char* _usr, char* _b)
00200 {
00201 return prepend_path(_msg, (str*)_usr, 1);
00202 }
00203
00207 void path_rr_callback(struct sip_msg *_m, str *r_param, void *cb_param)
00208 {
00209 param_hooks_t hooks;
00210 param_t *params;
00211
00212 if (parse_params(r_param, CLASS_CONTACT, &hooks, ¶ms) != 0) {
00213 LM_ERR("failed to parse route parameters\n");
00214 return;
00215 }
00216
00217 if (hooks.contact.received) {
00218 if (set_dst_uri(_m, &hooks.contact.received->body) != 0) {
00219 LM_ERR("failed to set dst-uri\n");
00220 free_params(params);
00221 return;
00222 }
00223
00224
00225 ruri_mark_new();
00226 }
00227 free_params(params);
00228 }