... | ... |
@@ -71,7 +71,6 @@ int do_action(struct action* a, struct sip_msg* msg) |
71 | 71 |
char *new_uri, *end, *crt; |
72 | 72 |
int len; |
73 | 73 |
int user; |
74 |
- int err; |
|
75 | 74 |
struct sip_uri uri; |
76 | 75 |
struct sip_uri* u; |
77 | 76 |
unsigned short port; |
... | ... |
@@ -100,19 +99,7 @@ int do_action(struct action* a, struct sip_msg* msg) |
100 | 99 |
u=&msg->parsed_uri; |
101 | 100 |
switch (a->p2_type){ |
102 | 101 |
case URIPORT_ST: |
103 |
- if (u->port.s){ |
|
104 |
- /*port=strtol(uri.port.s,&end,10);*/ |
|
105 |
- port=str2s((unsigned char*)u->port.s, |
|
106 |
- u->port.len, &err); |
|
107 |
- /*if ((end)&&(*end)){*/ |
|
108 |
- if (err){ |
|
109 |
- LOG(L_ERR, "ERROR: do_action: " |
|
110 |
- "forward: bad port in " |
|
111 |
- "uri: <%s>\n", u->port.s); |
|
112 |
- ret=E_BAD_URI; |
|
113 |
- goto error_fwd_uri; |
|
114 |
- } |
|
115 |
- }else port=0; |
|
102 |
+ port=u->port_no; |
|
116 | 103 |
break; |
117 | 104 |
case NUMBER_ST: |
118 | 105 |
port=a->p2.number; |
... | ... |
@@ -315,8 +315,8 @@ assign_stm: DEBUG EQUAL NUMBER { debug=$3; } |
315 | 315 |
| LISTEN EQUAL error { yyerror("ip address or hostname" |
316 | 316 |
"expected"); } |
317 | 317 |
| ALIAS EQUAL id_lst { |
318 |
- for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next) |
|
319 |
- add_alias(lst_tmp->s, strlen(lst_tmp->s)); |
|
318 |
+ for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next) |
|
319 |
+ add_alias(lst_tmp->s, strlen(lst_tmp->s), 0); |
|
320 | 320 |
} |
321 | 321 |
| ALIAS EQUAL error { yyerror(" hostname expected"); } |
322 | 322 |
| error EQUAL { yyerror("unknown config variable"); } |
... | ... |
@@ -70,7 +70,7 @@ struct socket_info* get_send_socket(union sockaddr_union* to) |
70 | 70 |
send_sock=0; |
71 | 71 |
/* check if we need to change the socket (different address families - |
72 | 72 |
* eg: ipv4 -> ipv6 or ipv6 -> ipv4) */ |
73 |
- if (to->s.sa_family!=bind_address->address.af){ |
|
73 |
+ if ((bind_address==0) ||(to->s.sa_family!=bind_address->address.af)){ |
|
74 | 74 |
switch(to->s.sa_family){ |
75 | 75 |
case AF_INET: send_sock=sendipv4; |
76 | 76 |
break; |
... | ... |
@@ -87,10 +87,11 @@ struct socket_info* get_send_socket(union sockaddr_union* to) |
87 | 87 |
|
88 | 88 |
|
89 | 89 |
|
90 |
-/* checks if the host is one of the address we listen on |
|
91 |
-* returns 1 if true, 0 if false, -1 on error |
|
90 |
+/* checks if the host:port is one of the address we listen on; |
|
91 |
+ * if port==0, the port number is ignored |
|
92 |
+ * returns 1 if true, 0 if false, -1 on error |
|
92 | 93 |
*/ |
93 |
-int check_self(str* host) |
|
94 |
+int check_self(str* host, unsigned short port) |
|
94 | 95 |
{ |
95 | 96 |
int r; |
96 | 97 |
|
... | ... |
@@ -102,6 +103,7 @@ int check_self(str* host) |
102 | 103 |
host->len, host->s, |
103 | 104 |
sock_info[r].name.len, sock_info[r].name.s |
104 | 105 |
); |
106 |
+ if ((port)&&(sock_info[r].port_no!=port)) continue; |
|
105 | 107 |
if ( (host->len==sock_info[r].name.len) && |
106 | 108 |
#ifdef USE_IPV6 |
107 | 109 |
(strncasecmp(host->s, sock_info[r].name.s, |
... | ... |
@@ -127,7 +129,7 @@ int check_self(str* host) |
127 | 129 |
} |
128 | 130 |
if (r==sock_no){ |
129 | 131 |
/* try to look into the aliases*/ |
130 |
- if (grep_aliases(host->s, host->len)==0){ |
|
132 |
+ if (grep_aliases(host->s, host->len, port)==0){ |
|
131 | 133 |
DBG("check_self: host != me\n"); |
132 | 134 |
return 0; |
133 | 135 |
} |
... | ... |
@@ -312,9 +314,11 @@ int forward_reply(struct sip_msg* msg) |
312 | 314 |
new_buf=0; |
313 | 315 |
/*check if first via host = us */ |
314 | 316 |
if (check_via){ |
315 |
- if (check_self(&(msg->via1->host))!=1){ |
|
317 |
+ if (check_self(&msg->via1->host, |
|
318 |
+ msg->via1->port?msg->via1->port:SIP_PORT)!=1){ |
|
316 | 319 |
LOG(L_NOTICE, "ERROR: forward_reply: host in first via!=me :" |
317 |
- " %.*s\n", msg->via1->host.len, msg->via1->host.s); |
|
320 |
+ " %.*s:%d\n", msg->via1->host.len, msg->via1->host.s |
|
321 |
+ msg->via1->port); |
|
318 | 322 |
/* send error msg back? */ |
319 | 323 |
goto error; |
320 | 324 |
} |
... | ... |
@@ -367,7 +371,7 @@ int forward_reply(struct sip_msg* msg) |
367 | 371 |
#endif |
368 | 372 |
} |
369 | 373 |
|
370 |
- DBG(" reply forwarded to %s:%d\n",msg->via2->host.s, |
|
374 |
+ DBG(" reply forwarded to %s:%d\n", msg->via2->host.s, |
|
371 | 375 |
(unsigned short) msg->via2->port); |
372 | 376 |
|
373 | 377 |
pkg_free(new_buf); |
... | ... |
@@ -37,7 +37,7 @@ |
37 | 37 |
|
38 | 38 |
|
39 | 39 |
struct socket_info* get_send_socket(union sockaddr_union* su); |
40 |
-int check_self(str* host); |
|
40 |
+int check_self(str* host, unsigned short port); |
|
41 | 41 |
int forward_request( struct sip_msg* msg, struct proxy_l* p); |
42 | 42 |
int update_sock_struct_from_via( union sockaddr_union* to, |
43 | 43 |
struct via_body* via ); |
... | ... |
@@ -78,6 +78,7 @@ struct socket_info{ |
78 | 78 |
unsigned short port_no; /* port number */ |
79 | 79 |
str port_no_str; /* port number converted to string -- optimization*/ |
80 | 80 |
int is_ip; /* 1 if name is an ip address, 0 if not -- optimization*/ |
81 |
+ int is_lo; /* 1 if is a loopback, 0 if not */ |
|
81 | 82 |
union sockaddr_union su; |
82 | 83 |
}; |
83 | 84 |
|
... | ... |
@@ -266,7 +266,7 @@ int addresses_no=0; /* number of names/ips */ |
266 | 266 |
#endif |
267 | 267 |
struct socket_info sock_info[MAX_LISTEN];/*all addresses we listen/send from*/ |
268 | 268 |
int sock_no=0; /* number of addresses/open sockets*/ |
269 |
-struct socket_info* bind_address; /* pointer to the crt. proc. |
|
269 |
+struct socket_info* bind_address=0; /* pointer to the crt. proc. |
|
270 | 270 |
listening address*/ |
271 | 271 |
int bind_idx; /* same as above but index in the bound[] array */ |
272 | 272 |
struct socket_info* sendipv4; /* ipv4 socket to use when msg. comes from ipv6*/ |
... | ... |
@@ -588,7 +588,8 @@ int main_loop() |
588 | 588 |
/* create the listening socket (for each address)*/ |
589 | 589 |
if (udp_init(&sock_info[r])==-1) goto error; |
590 | 590 |
/* get first ipv4/ipv6 socket*/ |
591 |
- if ((sendipv4==0)&&(sock_info[r].address.af==AF_INET)) |
|
591 |
+ if ((sock_info[r].address.af==AF_INET)&& |
|
592 |
+ ((sendipv4==0)||(sendipv4->is_lo))) |
|
592 | 593 |
sendipv4=&sock_info[r]; |
593 | 594 |
#ifdef USE_IPV6 |
594 | 595 |
if((sendipv6==0)&&(sock_info[r].address.af==AF_INET6)) |
... | ... |
@@ -803,10 +804,11 @@ int add_interfaces(char* if_name, int family, unsigned short port) |
803 | 804 |
continue; |
804 | 805 |
} |
805 | 806 |
|
806 |
- if (if_name==0){ /* ignore down ifs only if listening on all of them*/ |
|
807 |
- memcpy(&ifrcopy, ifr, sizeof(ifrcopy)); |
|
808 |
- /*get flags*/ |
|
809 |
- if (ioctl(s, SIOCGIFFLAGS, &ifrcopy)!=-1){ /* ignore errors */ |
|
807 |
+ /*get flags*/ |
|
808 |
+ memcpy(&ifrcopy, ifr, sizeof(ifrcopy)); |
|
809 |
+ if (ioctl(s, SIOCGIFFLAGS, &ifrcopy)!=-1){ /* ignore errors */ |
|
810 |
+ /* ignore down ifs only if listening on all of them*/ |
|
811 |
+ if (if_name==0){ |
|
810 | 812 |
/* if if not up, skip it*/ |
811 | 813 |
if (!(ifrcopy.ifr_flags & IFF_UP)) continue; |
812 | 814 |
} |
... | ... |
@@ -832,6 +834,9 @@ int add_interfaces(char* if_name, int family, unsigned short port) |
832 | 834 |
strncpy(sock_info[sock_no].name.s, tmp, |
833 | 835 |
sock_info[sock_no].name.len+1); |
834 | 836 |
sock_info[sock_no].port_no=port; |
837 |
+ /* mark if loopback */ |
|
838 |
+ if (ifrcopy.ifr_flags & IFF_LOOPBACK) |
|
839 |
+ sock_info[sock_no].is_lo=1; |
|
835 | 840 |
sock_no++; |
836 | 841 |
ret=0; |
837 | 842 |
}else{ |
... | ... |
@@ -1194,6 +1199,29 @@ int main(int argc, char** argv) |
1194 | 1199 |
printf("Listening on \n"); |
1195 | 1200 |
#endif |
1196 | 1201 |
for (r=0; r<sock_no;r++){ |
1202 |
+ /* fix port number, port_no should be !=0 here */ |
|
1203 |
+ if (sock_info[r].port_no==0) sock_info[r].port_no=port_no; |
|
1204 |
+ port_no_str_len=snprintf(port_no_str, MAX_PORT_LEN, ":%d", |
|
1205 |
+ (unsigned short) sock_info[r].port_no); |
|
1206 |
+ if (port_no_str_len<0){ |
|
1207 |
+ fprintf(stderr, "ERROR: bad port number: %d\n", |
|
1208 |
+ sock_info[r].port_no); |
|
1209 |
+ goto error; |
|
1210 |
+ } |
|
1211 |
+ /* on some systems snprintf returns really strange things if it does |
|
1212 |
+ not have enough space */ |
|
1213 |
+ port_no_str_len= |
|
1214 |
+ (port_no_str_len<MAX_PORT_LEN)?port_no_str_len:MAX_PORT_LEN; |
|
1215 |
+ sock_info[r].port_no_str.s=(char*)malloc(strlen(port_no_str)+1); |
|
1216 |
+ if (sock_info[r].port_no_str.s==0){ |
|
1217 |
+ fprintf(stderr, "Out of memory.\n"); |
|
1218 |
+ goto error; |
|
1219 |
+ } |
|
1220 |
+ strncpy(sock_info[r].port_no_str.s, port_no_str, |
|
1221 |
+ strlen(port_no_str)+1); |
|
1222 |
+ sock_info[r].port_no_str.len=strlen(port_no_str); |
|
1223 |
+ |
|
1224 |
+ /* get "official hostnames", all the aliases etc. */ |
|
1197 | 1225 |
he=resolvehost(sock_info[r].name.s); |
1198 | 1226 |
if (he==0){ |
1199 | 1227 |
DPrint("ERROR: could not resolve %s\n", sock_info[r].name.s); |
... | ... |
@@ -1201,7 +1229,8 @@ int main(int argc, char** argv) |
1201 | 1229 |
} |
1202 | 1230 |
/* check if we got the official name */ |
1203 | 1231 |
if (strcasecmp(he->h_name, sock_info[r].name.s)!=0){ |
1204 |
- if (add_alias(sock_info[r].name.s, sock_info[r].name.len)<0){ |
|
1232 |
+ if (add_alias(sock_info[r].name.s, sock_info[r].name.len, |
|
1233 |
+ sock_info[r].port_no)<0){ |
|
1205 | 1234 |
LOG(L_ERR, "ERROR: main: add_alias failed\n"); |
1206 | 1235 |
} |
1207 | 1236 |
/* change the oficial name */ |
... | ... |
@@ -1216,7 +1245,7 @@ int main(int argc, char** argv) |
1216 | 1245 |
} |
1217 | 1246 |
/* add the aliases*/ |
1218 | 1247 |
for(h=he->h_aliases; h && *h; h++) |
1219 |
- if (add_alias(*h, strlen(*h))<0){ |
|
1248 |
+ if (add_alias(*h, strlen(*h), sock_info[r].port_no)<0){ |
|
1220 | 1249 |
LOG(L_ERR, "ERROR: main: add_alias failed\n"); |
1221 | 1250 |
} |
1222 | 1251 |
hostent2ip_addr(&sock_info[r].address, he, 0); /*convert to ip_addr |
... | ... |
@@ -1242,36 +1271,17 @@ int main(int argc, char** argv) |
1242 | 1271 |
sock_info[r].name.s); |
1243 | 1272 |
}else{ |
1244 | 1273 |
/* add the aliases*/ |
1245 |
- if (add_alias(he->h_name, strlen(he->h_name))<0){ |
|
1274 |
+ if (add_alias(he->h_name, strlen(he->h_name), |
|
1275 |
+ sock_info[r].port_no)<0){ |
|
1246 | 1276 |
LOG(L_ERR, "ERROR: main: add_alias failed\n"); |
1247 | 1277 |
} |
1248 | 1278 |
for(h=he->h_aliases; h && *h; h++) |
1249 |
- if (add_alias(*h, strlen(*h))<0){ |
|
1279 |
+ if (add_alias(*h,strlen(*h),sock_info[r].port_no)<0){ |
|
1250 | 1280 |
LOG(L_ERR, "ERROR: main: add_alias failed\n"); |
1251 | 1281 |
} |
1252 | 1282 |
} |
1253 | 1283 |
}else{ sock_info[r].is_ip=0; }; |
1254 | 1284 |
|
1255 |
- if (sock_info[r].port_no==0) sock_info[r].port_no=port_no; |
|
1256 |
- port_no_str_len=snprintf(port_no_str, MAX_PORT_LEN, ":%d", |
|
1257 |
- (unsigned short) sock_info[r].port_no); |
|
1258 |
- if (port_no_str_len<0){ |
|
1259 |
- fprintf(stderr, "ERROR: bad port number: %d\n", |
|
1260 |
- sock_info[r].port_no); |
|
1261 |
- goto error; |
|
1262 |
- } |
|
1263 |
- /* on some systems snprintf returns really strange things if it does |
|
1264 |
- not have enough space */ |
|
1265 |
- port_no_str_len= |
|
1266 |
- (port_no_str_len<MAX_PORT_LEN)?port_no_str_len:MAX_PORT_LEN; |
|
1267 |
- sock_info[r].port_no_str.s=(char*)malloc(strlen(port_no_str)+1); |
|
1268 |
- if (sock_info[r].port_no_str.s==0){ |
|
1269 |
- fprintf(stderr, "Out of memory.\n"); |
|
1270 |
- goto error; |
|
1271 |
- } |
|
1272 |
- strncpy(sock_info[r].port_no_str.s, port_no_str, strlen(port_no_str)+1); |
|
1273 |
- sock_info[r].port_no_str.len=strlen(port_no_str); |
|
1274 |
- |
|
1275 | 1285 |
#ifdef EXTRA_DEBUG |
1276 | 1286 |
printf(" %.*s [%s]:%s\n", sock_info[r].name.len, |
1277 | 1287 |
sock_info[r].name.s, |
... | ... |
@@ -1298,7 +1308,8 @@ int main(int argc, char** argv) |
1298 | 1308 |
(strncmp(sock_info[t].name.s, sock_info[r].name.s, |
1299 | 1309 |
sock_info[r].name.len)!=0)) |
1300 | 1310 |
) |
1301 |
- add_alias(sock_info[t].name.s, sock_info[t].name.len); |
|
1311 |
+ add_alias(sock_info[t].name.s, sock_info[t].name.len, |
|
1312 |
+ sock_info[t].port_no); |
|
1302 | 1313 |
|
1303 | 1314 |
/* free space*/ |
1304 | 1315 |
free(sock_info[t].name.s); |
... | ... |
@@ -1320,7 +1331,11 @@ int main(int argc, char** argv) |
1320 | 1331 |
sock_info[r].address_str.s, sock_info[r].port_no_str.s); |
1321 | 1332 |
|
1322 | 1333 |
printf("Aliases: "); |
1323 |
- for(a=aliases; a; a=a->next) printf("%.*s ", a->alias.len, a->alias.s); |
|
1334 |
+ for(a=aliases; a; a=a->next) |
|
1335 |
+ if (a->port) |
|
1336 |
+ printf("%.*s:%d ", a->alias.len, a->alias.s, a->port); |
|
1337 |
+ else |
|
1338 |
+ printf("%.*s:* ", a->alias.len, a->alias.s); |
|
1324 | 1339 |
printf("\n"); |
1325 | 1340 |
if (sock_no==0){ |
1326 | 1341 |
fprintf(stderr, "ERROR: no listening sockets"); |
... | ... |
@@ -35,6 +35,7 @@ |
35 | 35 |
|
36 | 36 |
struct host_alias{ |
37 | 37 |
str alias; |
38 |
+ unsigned short port; |
|
38 | 39 |
struct host_alias* next; |
39 | 40 |
}; |
40 | 41 |
|
... | ... |
@@ -43,13 +44,14 @@ extern struct host_alias* aliases; |
43 | 44 |
|
44 | 45 |
|
45 | 46 |
|
46 |
-/* returns 1 if name is in the alias list*/ |
|
47 |
-static inline int grep_aliases(char* name, int len) |
|
47 |
+/* returns 1 if name is in the alias list; if port=0, port no is ignored*/ |
|
48 |
+static inline int grep_aliases(char* name, int len, unsigned short port) |
|
48 | 49 |
{ |
49 | 50 |
struct host_alias* a; |
50 | 51 |
|
51 | 52 |
for(a=aliases;a;a=a->next) |
52 |
- if ((a->alias.len==len) && (strncasecmp(a->alias.s, name, len)==0)) |
|
53 |
+ if ((a->alias.len==len) && ((a->port==0) || (port==0) || |
|
54 |
+ (a->port==port)) && (strncasecmp(a->alias.s, name, len)==0)) |
|
53 | 55 |
return 1; |
54 | 56 |
return 0; |
55 | 57 |
} |
... | ... |
@@ -57,13 +59,14 @@ static inline int grep_aliases(char* name, int len) |
57 | 59 |
|
58 | 60 |
|
59 | 61 |
/* adds an alias to the list (only if it isn't already there) |
62 |
+ * if port==0, the alias will match all the ports |
|
60 | 63 |
* returns 1 if a new alias was added, 0 if the alias was already on the list |
61 | 64 |
* and -1 on error */ |
62 |
-static inline int add_alias(char* name, int len) |
|
65 |
+static inline int add_alias(char* name, int len, unsigned short port) |
|
63 | 66 |
{ |
64 | 67 |
struct host_alias* a; |
65 | 68 |
|
66 |
- if (grep_aliases(name,len)) return 0; |
|
69 |
+ if ((port) && grep_aliases(name,len, port)) return 0; |
|
67 | 70 |
a=0; |
68 | 71 |
a=(struct host_alias*)malloc(sizeof(struct host_alias)); |
69 | 72 |
if(a==0) goto error; |
... | ... |
@@ -72,6 +75,7 @@ static inline int add_alias(char* name, int len) |
72 | 75 |
a->alias.len=len; |
73 | 76 |
memcpy(a->alias.s, name, len); |
74 | 77 |
a->alias.s[len]=0; /* null terminate for easier printing*/ |
78 |
+ a->port=port; |
|
75 | 79 |
a->next=aliases; |
76 | 80 |
aliases=a; |
77 | 81 |
return 1; |
... | ... |
@@ -42,6 +42,7 @@ int parse_uri(char *buf, int len, struct sip_uri* uri) |
42 | 42 |
char* next, *end; |
43 | 43 |
char *user, *passwd, *host, *port, *params, *headers, *ipv6; |
44 | 44 |
int host_len, port_len, params_len, headers_len; |
45 |
+ int err; |
|
45 | 46 |
int ret; |
46 | 47 |
|
47 | 48 |
|
... | ... |
@@ -208,7 +209,15 @@ int parse_uri(char *buf, int len, struct sip_uri* uri) |
208 | 209 |
uri->headers.len=headers_len; |
209 | 210 |
uri->headers.s[headers_len]=0; |
210 | 211 |
}else uri->headers.s=0; |
211 |
- |
|
212 |
+ |
|
213 |
+ err=0; |
|
214 |
+ if (uri->port.s) uri->port_no=str2s(uri->port.s, uri->port.len, &err); |
|
215 |
+ if (err){ |
|
216 |
+ LOG(L_DBG, "ERROR: parse_uri: bad port number in sip uri: %s\n", |
|
217 |
+ uri->port.s); |
|
218 |
+ ser_error=ret=E_BAD_URI; |
|
219 |
+ goto error; |
|
220 |
+ } |
|
212 | 221 |
return ret; |
213 | 222 |
error: |
214 | 223 |
free_uri(uri); |
... | ... |
@@ -262,7 +262,7 @@ error: |
262 | 262 |
|
263 | 263 |
|
264 | 264 |
|
265 |
-/* eval_elem helping function, returns a op param */ |
|
265 |
+/* eval_elem helping function, returns an op param */ |
|
266 | 266 |
static int comp_ip(struct ip_addr* ip, void* param, int op, int subtype) |
267 | 267 |
{ |
268 | 268 |
struct hostent* he; |
... | ... |
@@ -305,7 +305,7 @@ static int comp_ip(struct ip_addr* ip, void* param, int op, int subtype) |
305 | 305 |
case MYSELF_ST: /* check if it's one of our addresses*/ |
306 | 306 |
tmp.s=ip_addr2a(ip); |
307 | 307 |
tmp.len=strlen(tmp.s); |
308 |
- ret=check_self(&tmp); |
|
308 |
+ ret=check_self(&tmp, 0); |
|
309 | 309 |
break; |
310 | 310 |
default: |
311 | 311 |
LOG(L_CRIT, "BUG: comp_ip: invalid type for " |
... | ... |
@@ -338,7 +338,9 @@ static int eval_elem(struct expr* e, struct sip_msg* msg) |
338 | 338 |
if(msg->new_uri.s){ |
339 | 339 |
if (e->subtype==MYSELF_ST){ |
340 | 340 |
if (parse_sip_msg_uri(msg)<0) ret=-1; |
341 |
- else ret=check_self(&msg->parsed_uri.host); |
|
341 |
+ else ret=check_self(&msg->parsed_uri.host, |
|
342 |
+ msg->parsed_uri.port_no? |
|
343 |
+ msg->parsed_uri.port_no:SIP_PORT); |
|
342 | 344 |
}else{ |
343 | 345 |
ret=comp_str(msg->new_uri.s, e->r.param, |
344 | 346 |
e->op, e->subtype); |
... | ... |
@@ -346,7 +348,9 @@ static int eval_elem(struct expr* e, struct sip_msg* msg) |
346 | 348 |
}else{ |
347 | 349 |
if (e->subtype==MYSELF_ST){ |
348 | 350 |
if (parse_sip_msg_uri(msg)<0) ret=-1; |
349 |
- else ret=check_self(&msg->parsed_uri.host); |
|
351 |
+ else ret=check_self(&msg->parsed_uri.host, |
|
352 |
+ msg->parsed_uri.port_no? |
|
353 |
+ msg->parsed_uri.port_no:SIP_PORT); |
|
350 | 354 |
}else{ |
351 | 355 |
ret=comp_str(msg->first_line.u.request.uri.s, |
352 | 356 |
e->r.param, e->op, e->subtype); |