Browse code

- more struct dest_info conversions (via_builder, tm: build_uac_req, assemble_via a.s.o) - basic support for comp=method (where mehtod=sigcomp|sergz) parsing (via, various uris) and adding (via, rr lumps). The code is compiled only if USE_COMP is defined. NOTE: for now the code is useless (no compression code yet and no compression hooks), so by default it's not compiled.

WARNING: lots of changes and very lightly tested

Andrei Pelinescu-Onciul authored on 21/04/2006 14:28:36
Showing 22 changed files
... ...
@@ -66,7 +66,7 @@ MAIN_NAME=ser
66 66
 VERSION = 0
67 67
 PATCHLEVEL = 10
68 68
 SUBLEVEL =   99
69
-EXTRAVERSION = -dev39
69
+EXTRAVERSION = -dev40
70 70
 
71 71
 SER_VER = $(shell expr $(VERSION) \* 1000000 + $(PATCHLEVEL) \* 1000 + \
72 72
 			$(SUBLEVEL) )
... ...
@@ -335,6 +335,10 @@ endif
335 335
 # -DHAVE_RESOLV_RES
336 336
 #		support for changing some of the resolver parameters present
337 337
 #		 (_res structure in <resolv.h>)
338
+# -DUSE_COMP
339
+#		compiles in comp=[sergz|sigcomp] support (parsing uri & via, 
340
+#		adding it to via, lumps a.s.o). WARNING: right now this option
341
+#		is useless since the compression code doesn't exist yet.
338 342
 
339 343
 
340 344
 DEFS+= $(extra_defs) \
... ...
@@ -146,7 +146,8 @@ int do_action(struct action* a, struct sip_msg* msg)
146 146
 				/*parse uri*/
147 147
 
148 148
 				if (msg->dst_uri.len) {
149
-					ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len, &next_hop);
149
+					ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len,
150
+									&next_hop);
150 151
 					u = &next_hop;
151 152
 				} else {
152 153
 					ret = parse_sip_msg_uri(msg);
... ...
@@ -212,6 +213,9 @@ int do_action(struct action* a, struct sip_msg* msg)
212 212
 					ret=E_BAD_ADDRESS;
213 213
 					goto error_fwd_uri;
214 214
 				}
215
+#ifdef USE_COMP
216
+				dst.comp=u->comp;
217
+#endif
215 218
 				ret=forward_request(msg, &dst);
216 219
 				if (ret>=0) ret=1;
217 220
 			}else if ((a->val[0].type==PROXY_ST) && (a->val[1].type==NUMBER_ST)){
... ...
@@ -99,6 +99,15 @@
99 99
 #define TRANSPORT_PARAM ";transport="
100 100
 #define TRANSPORT_PARAM_LEN (sizeof(TRANSPORT_PARAM) - 1)
101 101
 
102
+#define COMP_PARAM ";comp="
103
+#define COMP_PARAM_LEN (sizeof(COMP_PARAM)-1)
104
+
105
+#define SIGCOMP_NAME "sigcomp"
106
+#define SIGCOMP_NAME_LEN (sizeof(SIGCOMP_NAME)-1)
107
+
108
+#define SERGZ_NAME "sergz"
109
+#define SERGZ_NAME_LEN (sizeof(SERGZ_NAME)-1)
110
+
102 111
 #define TOTAG_TOKEN ";tag="
103 112
 #define TOTAG_TOKEN_LEN (sizeof(TOTAG_TOKEN)-1)
104 113
 
... ...
@@ -49,6 +49,7 @@
49 49
  *  2005-12-11  onsend_router support; forward_request to no longer
50 50
  *              pkg_malloc'ed (andrei)
51 51
  *  2006-04-12  forward_{request,reply} use now struct dest_info (andrei)
52
+ *  2006-04-21  basic comp via param support (andrei)
52 53
  */
53 54
 
54 55
 
... ...
@@ -315,8 +316,7 @@ int forward_request(struct sip_msg* msg, struct dest_info* send_info)
315 315
 		}
316 316
 	}
317 317
 
318
-	buf = build_req_buf_from_sip_req(msg, &len, send_info->send_sock,
319
-											send_info->proto);
318
+	buf = build_req_buf_from_sip_req(msg, &len, send_info);
320 319
 	if (!buf){
321 320
 		LOG(L_ERR, "ERROR: forward_request: building failed\n");
322 321
 		goto error;
... ...
@@ -468,7 +468,9 @@ int forward_reply(struct sip_msg* msg)
468 468
 
469 469
 	dst.proto=msg->via2->proto;
470 470
 	if (update_sock_struct_from_via( &dst.to, msg, msg->via2 )==-1) goto error;
471
-
471
+#ifdef USE_COMP
472
+	dst.comp=msg->via2->comp_no;
473
+#endif
472 474
 
473 475
 #ifdef USE_TCP
474 476
 	if (dst.proto==PROTO_TCP
... ...
@@ -30,6 +30,8 @@
30 30
  * --------
31 31
  *  2003-02-13  added struct dest_info (andrei)
32 32
  *  2003-04-06  all ports are stored/passed in host byte order now (andrei)
33
+ *  2006-04-20  comp support in recv_info and dest_info (andrei)
34
+ *  2006-04-21  added init_dst_from_rcv (andrei)
33 35
  */
34 36
 
35 37
 #ifndef ip_addr_h
... ...
@@ -46,7 +48,9 @@
46 46
 #include "dprint.h"
47 47
 
48 48
 enum sip_protos { PROTO_NONE, PROTO_UDP, PROTO_TCP, PROTO_TLS, PROTO_SCTP };
49
-
49
+#ifdef USE_COMP
50
+enum comp_methods { COMP_NONE, COMP_SIGCOMP, COMP_SERGZ };
51
+#endif
50 52
 
51 53
 struct ip_addr{
52 54
 	unsigned int af; /* address family: AF_INET6 or AF_INET */
... ...
@@ -100,21 +104,27 @@ struct receive_info{
100 100
 	struct ip_addr dst_ip;
101 101
 	unsigned short src_port; /* host byte order */
102 102
 	unsigned short dst_port; /* host byte order */
103
-	int proto;
104 103
 	int proto_reserved1; /* tcp stores the connection id here */
105 104
 	int proto_reserved2;
106 105
 	union sockaddr_union src_su; /* useful for replies*/
107 106
 	struct socket_info* bind_address; /* sock_info structure on which 
108 107
 									  the msg was received*/
108
+	short proto;
109
+#ifdef USE_COMP
110
+	short comp; /* compression */
111
+#endif
109 112
 	/* no need for dst_su yet */
110 113
 };
111 114
 
112 115
 
113 116
 struct dest_info{
114
-	int proto;
115
-	int id; /* tcp stores the connection id here */ 
116
-	union sockaddr_union to;
117 117
 	struct socket_info* send_sock;
118
+	union sockaddr_union to;
119
+	int id; /* tcp stores the connection id here */ 
120
+	short proto;
121
+#ifdef USE_COMP
122
+	short comp;
123
+#endif
118 124
 };
119 125
 
120 126
 
... ...
@@ -553,10 +563,23 @@ static inline struct hostent* ip_addr2he(str* name, struct ip_addr* ip)
553 553
 /* init a dest_info structure */
554 554
 #define init_dest_info(dst) \
555 555
 	do{ \
556
-		(dst)->proto=0; \
557
-		(dst)->id=0; \
558
-		(dst)->send_sock=0; \
559
-		memset(&(dst)->to, 0, sizeof(union sockaddr_union)); \
556
+		memset((dst), 0, sizeof(struct dest_info)); \
560 557
 	} while(0) 
561 558
 
559
+
560
+
561
+/* init a dest_info structure from a recv_info structure */
562
+inline static void init_dst_from_rcv(struct dest_info* dst,
563
+									struct receive_info* rcv)
564
+{
565
+		dst->send_sock=rcv->bind_address;
566
+		dst->to=rcv->src_su;
567
+		dst->id=rcv->proto_reserved1;
568
+		dst->proto=rcv->proto;
569
+#ifdef USE_COMP
570
+		dst->comp=rcv->comp;
571
+#endif
572
+}
573
+
574
+
562 575
 #endif
... ...
@@ -46,6 +46,7 @@
46 46
  *  2003-05-07  received, rport & i via shortcuts are also translated (andrei)
47 47
  *  2003-11-11  updated cloning of lump_rpl (bogdan)
48 48
  *  2004-03-31  alias shortcuts are also translated (andrei)
49
+ *  2006-04-20  via->comp is also translated (andrei)
49 50
  */
50 51
 
51 52
 #include "defs.h"
... ...
@@ -154,6 +155,12 @@ inline struct via_body* via_body_cloner( char* new_buf,
154 154
 					case PARAM_ALIAS:
155 155
 							new_via->alias = new_vp;
156 156
 							break;
157
+							
158
+#ifdef USE_COMP
159
+					case PARAM_COMP:
160
+							new_via->comp = new_vp;
161
+							break;
162
+#endif
157 163
 				}
158 164
 
159 165
 				if (last_new_vp)
... ...
@@ -230,7 +230,7 @@ int t_relay_to( struct sip_msg  *p_msg , struct proxy_l *proxy, int proto,
230 230
 		DBG( "SER: forwarding ACK  statelessly \n");
231 231
 		if (proxy==0) {
232 232
 			uri = GET_RURI(p_msg);
233
-			if (uri2dst(&dst, GET_NEXT_HOP(p_msg), proto)==0){
233
+			if (uri2dst(&dst, p_msg, GET_NEXT_HOP(p_msg), proto)==0){
234 234
 				ret=E_BAD_ADDRESS;
235 235
 				goto done;
236 236
 			}
... ...
@@ -239,6 +239,8 @@ int t_relay_to( struct sip_msg  *p_msg , struct proxy_l *proxy, int proto,
239 239
 			init_dest_info(&dst);
240 240
 			dst.proto=get_proto(proto, proxy->proto);
241 241
 			proxy2su(&dst.to, proxy);
242
+			/* dst->send_sock not set, but forward_request will take care
243
+			 * of it */
242 244
 			ret=forward_request( p_msg , &dst) ;
243 245
 		}
244 246
 		goto done;
... ...
@@ -49,6 +49,7 @@
49 49
  *              already canceled transaction is attempted (andrei)
50 50
  *  2006-02-07  named routes support (andrei)
51 51
  *  2006-04-18  add_uac simplified + switched to struct dest_info (andrei)
52
+ *  2006-04-20  pint_uac_request uses now struct dest_info (andrei)
52 53
  */
53 54
 
54 55
 #include "defs.h"
... ...
@@ -98,9 +99,8 @@ unsigned int get_on_branch(void)
98 98
 }
99 99
 
100 100
 
101
-char *print_uac_request( struct cell *t, struct sip_msg *i_req,
102
-	int branch, str *uri, unsigned int *len, struct socket_info *send_sock,
103
-	enum sip_protos proto )
101
+static char *print_uac_request( struct cell *t, struct sip_msg *i_req,
102
+	int branch, str *uri, unsigned int *len, struct dest_info* dst)
104 103
 {
105 104
 	char *buf, *shbuf;
106 105
 	str* msg_uri;
... ...
@@ -139,7 +139,7 @@ char *print_uac_request( struct cell *t, struct sip_msg *i_req,
139 139
 	run_trans_callbacks( TMCB_REQUEST_FWDED , t, i_req, 0, -i_req->REQ_METHOD);
140 140
 
141 141
 	/* ... and build it now */
142
-	buf=build_req_buf_from_sip_req( i_req, len, send_sock, proto );
142
+	buf=build_req_buf_from_sip_req( i_req, len, dst);
143 143
 #ifdef DBG_MSG_QA
144 144
 	if (buf[*len-1]==0) {
145 145
 		LOG(L_ERR, "ERROR: print_uac_request: sanity check failed\n");
... ...
@@ -246,25 +246,26 @@ int add_uac( struct cell *t, struct sip_msg *request, str *uri, str* next_hop,
246 246
 		goto error;
247 247
 	}
248 248
 
249
-	init_dest_info(&t->uac[branch].request.dst);
250 249
 	/* check DNS resolution */
251 250
 	if (proxy){
252 251
 		/* dst filled from the proxy */
252
+		init_dest_info(&t->uac[branch].request.dst);
253 253
 		t->uac[branch].request.dst.proto=get_proto(proto, proxy->proto);
254 254
 		proxy2su(&t->uac[branch].request.dst.to, proxy);
255
+		/* fill dst send_sock */
256
+		t->uac[branch].request.dst.send_sock =
257
+		get_send_socket( request, &t->uac[branch].request.dst.to,
258
+								t->uac[branch].request.dst.proto);
255 259
 	}else {
256
-		/* dst filled from the uri */
257
-		if (uri2dst(&t->uac[branch].request.dst,
260
+		/* dst filled from the uri & request (send_socket) */
261
+		if (uri2dst(&t->uac[branch].request.dst, request,
258 262
 						next_hop ? next_hop: uri, proto)==0){
259 263
 			ret=E_BAD_ADDRESS;
260 264
 			goto error;
261 265
 		}
262 266
 	}
263
-
264
-	/* fill dst send_sock */
265
-	t->uac[branch].request.dst.send_sock =
266
-			get_send_socket( request, &t->uac[branch].request.dst.to,
267
-								t->uac[branch].request.dst. proto);
267
+	
268
+	/* check if send_sock is ok */
268 269
 	if (t->uac[branch].request.dst.send_sock==0) {
269 270
 		LOG(L_ERR, "ERROR: add_uac: can't fwd to af %d, proto %d "
270 271
 			" (no corresponding listening socket)\n",
... ...
@@ -276,8 +277,7 @@ int add_uac( struct cell *t, struct sip_msg *request, str *uri, str* next_hop,
276 276
 
277 277
 	/* now message printing starts ... */
278 278
 	shbuf=print_uac_request( t, request, branch, uri, 
279
-		&len, t->uac[branch].request.dst.send_sock, 
280
-			t->uac[branch].request.dst.proto );
279
+							&len, &t->uac[branch].request.dst);
281 280
 	if (!shbuf) {
282 281
 		ret=ser_error=E_OUT_OF_MEM;
283 282
 		goto error01;
... ...
@@ -322,9 +322,8 @@ int e2e_cancel_branch( struct sip_msg *cancel_msg, struct cell *t_cancel,
322 322
 
323 323
 	/* print */
324 324
 	shbuf=print_uac_request( t_cancel, cancel_msg, branch, 
325
-		&t_invite->uac[branch].uri, &len, 
326
-		t_invite->uac[branch].request.dst.send_sock,
327
-		t_invite->uac[branch].request.dst.proto);
325
+							&t_invite->uac[branch].uri, &len, 
326
+							&t_invite->uac[branch].request.dst);
328 327
 	if (!shbuf) {
329 328
 		LOG(L_ERR, "ERROR: e2e_cancel_branch: printing e2e cancel failed\n");
330 329
 		ret=ser_error=E_OUT_OF_MEM;
... ...
@@ -45,9 +45,10 @@ typedef int (*taddblind_f)( /*struct cell *t */ );
45 45
 void t_on_branch(unsigned int go_to);
46 46
 unsigned int get_on_branch();
47 47
 int t_replicate(struct sip_msg *p_msg, struct proxy_l * proxy, int proto);
48
+/*  -- not use outside t_fwd.c for noe
48 49
 char *print_uac_request( struct cell *t, struct sip_msg *i_req,
49
-    int branch, str *uri, unsigned int *len, struct socket_info *send_sock,
50
-    enum sip_protos proto);
50
+    int branch, str *uri, unsigned int *len, struct dest_info *dst);
51
+*/
51 52
 void e2e_cancel( struct sip_msg *cancel_msg, struct cell *t_cancel, struct cell *t_invite );
52 53
 int e2e_cancel_branch( struct sip_msg *cancel_msg, struct cell *t_cancel, struct cell *t_invite, int branch );
53 54
 int add_uac(	struct cell *t, struct sip_msg *request, str *uri, str* next_hop,
... ...
@@ -82,7 +82,6 @@
82 82
  * 2005-12-09  added t_set_fr()  (andrei)
83 83
  * 2006-01-27  transaction lookup function will set up a cancel flag
84 84
  *             if the searched transaction was pre-canceled (andrei)
85
- * 
86 85
  */
87 86
 
88 87
 #include "defs.h"
... ...
@@ -988,6 +987,7 @@ int init_rb( struct retr_buf *rb, struct sip_msg *msg)
988 988
 
989 989
 	/* rb. timers are init. init_t()/new_cell() */
990 990
 	via=msg->via1;
991
+	/* rb->dst is already init (0) by new_t()/build_cell() */
991 992
 	if (!reply_to_via) {
992 993
 		update_sock_struct_from_ip( &rb->dst.to, msg );
993 994
 		proto=msg->rcv.proto;
... ...
@@ -1003,6 +1003,9 @@ int init_rb( struct retr_buf *rb, struct sip_msg *msg)
1003 1003
 	}
1004 1004
 	rb->dst.proto=proto;
1005 1005
 	rb->dst.id=msg->rcv.proto_reserved1;
1006
+#ifdef USE_COMP
1007
+	rb->dst.comp=via->comp_no;
1008
+#endif
1006 1009
 	/* turn off mhomed for generating replies -- they are ideally sent to where
1007 1010
 	   request came from to make life with NATs and other beasts easier
1008 1011
 	*/
... ...
@@ -38,6 +38,8 @@
38 38
  * 2003-10-02  added via_builder set host/port support (andrei)
39 39
  * 2004-02-11  FIFO/CANCEL + alignments (hash=f(callid,cseq)) (uli+jiri)
40 40
  * 2004-02-13: t->is_invite and t->local replaced with flags (bogdan)
41
+ * 2006-04-21  build_uac_req, assemble_via use struct dest_info now;
42
+ *              uri2sock replaced with uri2dst (andrei)
41 43
  */
42 44
 
43 45
 #include "defs.h"
... ...
@@ -100,8 +102,8 @@ char *build_local(struct cell *Trans,unsigned int branch,
100 100
 	branch_str.s=branch_buf;
101 101
 	branch_str.len=branch_len;
102 102
 	set_hostport(&hp, (is_local(Trans))?0:(Trans->uas.request));
103
-	via=via_builder(&via_len, Trans->uac[branch].request.dst.send_sock,
104
-		&branch_str, 0, Trans->uac[branch].request.dst.proto, &hp );
103
+	via=via_builder(&via_len, &Trans->uac[branch].request.dst,
104
+		&branch_str, 0, &hp );
105 105
 	if (!via)
106 106
 	{
107 107
 		LOG(L_ERR, "ERROR: build_local: "
... ...
@@ -355,7 +357,7 @@ static inline int get_contact_uri(struct sip_msg* msg, str* uri)
355 355
 
356 356
      /*
357 357
       * The function creates an ACK to 200 OK. Route set will be created
358
-      * and parsed and next_hop parameter will contain uri the which the
358
+      * and parsed and next_hop parameter will contain the uri to which the
359 359
       * request should be send. The function is used by tm when it generates
360 360
       * local ACK to 200 OK (on behalf of applications using uac
361 361
       */
... ...
@@ -370,8 +372,7 @@ char *build_dlg_ack(struct sip_msg* rpl, struct cell *Trans, unsigned int branch
370 370
 	struct hostport hp;
371 371
 	struct rte* list;
372 372
 	str contact, ruri, *cont;
373
-	struct socket_info* send_sock;
374
-	union sockaddr_union to_su;
373
+	struct dest_info dst;
375 374
 	
376 375
 	if (get_contact_uri(rpl, &contact) < 0) {
377 376
 		return 0;
... ...
@@ -399,9 +400,8 @@ char *build_dlg_ack(struct sip_msg* rpl, struct cell *Trans, unsigned int branch
399 399
 	
400 400
 	
401 401
 	     /* via */
402
-	send_sock = uri2sock(rpl, next_hop, &to_su, PROTO_NONE);
403
-	if (!send_sock) {
404
-		LOG(L_ERR, "build_dlg_ack: no socket found\n");
402
+	if ((uri2dst(&dst, rpl, next_hop, PROTO_NONE)==0) || (dst.send_sock==0)){
403
+			LOG(L_ERR, "build_dlg_ack: no socket found\n");
405 404
 		goto error;
406 405
 	}
407 406
 	
... ...
@@ -409,7 +409,7 @@ char *build_dlg_ack(struct sip_msg* rpl, struct cell *Trans, unsigned int branch
409 409
 	branch_str.s = branch_buf;
410 410
 	branch_str.len = branch_len;
411 411
 	set_hostport(&hp, 0);
412
-	via = via_builder(&via_len, send_sock, &branch_str, 0, send_sock->proto, &hp);
412
+	via = via_builder(&via_len, &dst, &branch_str, 0, &hp);
413 413
 	if (!via) {
414 414
 		LOG(L_ERR, "build_dlg_ack: No via header got from builder\n");
415 415
 		goto error;
... ...
@@ -529,7 +529,8 @@ static inline int print_cseq_num(str* _s, dlg_t* _d)
529 529
 /*
530 530
  * Create Via header
531 531
  */
532
-static inline int assemble_via(str* dest, struct cell* t, struct socket_info* sock, int branch)
532
+static inline int assemble_via(str* dest, struct cell* t, 
533
+								struct dest_info* dst, int branch)
533 534
 {
534 535
 	static char branch_buf[MAX_BRANCH_PARAM_LEN];
535 536
 	char* via;
... ...
@@ -551,7 +552,7 @@ static inline int assemble_via(str* dest, struct cell* t, struct socket_info* so
551 551
 #endif
552 552
 
553 553
 	set_hostport(&hp, 0);
554
-	via = via_builder(&via_len, sock, &branch_str, 0, sock->proto, &hp);
554
+	via = via_builder(&via_len, dst, &branch_str, 0, &hp);
555 555
 	if (!via) {
556 556
 		LOG(L_ERR, "assemble_via: via building failed\n");
557 557
 		return -2;
... ...
@@ -674,7 +675,7 @@ static inline char* print_callid(char* w, dlg_t* dialog, struct cell* t)
674 674
  * Create a request
675 675
  */
676 676
 char* build_uac_req(str* method, str* headers, str* body, dlg_t* dialog, int branch, 
677
-			struct cell *t, int* len, struct socket_info* send_sock)
677
+			struct cell *t, int* len, struct dest_info* dst)
678 678
 {
679 679
 	char* buf, *w;
680 680
 	str content_length, cseq, via;
... ...
@@ -693,7 +694,7 @@ char* build_uac_req(str* method, str* headers, str* body, dlg_t* dialog, int bra
693 693
 	}
694 694
 	*len = method->len + 1 + dialog->hooks.request_uri->len + 1 + SIP_VERSION_LEN + CRLF_LEN;
695 695
 
696
-	if (assemble_via(&via, t, send_sock, branch) < 0) {
696
+	if (assemble_via(&via, t, dst, branch) < 0) {
697 697
 		LOG(L_ERR, "build_uac_req(): Error while assembling Via\n");
698 698
 		return 0;
699 699
 	}
... ...
@@ -89,7 +89,7 @@ char *build_dlg_ack(struct sip_msg* rpl, struct cell *Trans, unsigned int branch
89 89
  * Create a request
90 90
  */
91 91
 char* build_uac_req(str* method, str* headers, str* body, dlg_t* dialog, int branch, 
92
-		    struct cell *t, int* len, struct socket_info* send_sock);
92
+		    struct cell *t, int* len, struct dest_info* dst);
93 93
 
94 94
 
95 95
 int t_calc_branch(struct cell *t,
... ...
@@ -322,13 +322,10 @@ static int send_local_ack(struct sip_msg* msg, str* next_hop,
322 322
 		LOG(L_ERR, "send_local_ack: Invalid parameter value\n");
323 323
 		return -1;
324 324
 	}
325
-	init_dest_info(&dst);
326
-	dst.send_sock = uri2sock(msg, next_hop, &dst.to, PROTO_NONE);
327
-	if (!dst.send_sock) {
325
+	if ((uri2dst(&dst, msg,  next_hop, PROTO_NONE)==0) || (dst.send_sock==0)){
328 326
 		LOG(L_ERR, "send_local_ack: no socket found\n");
329 327
 		return -1;
330 328
 	}
331
-	dst.id=0;
332 329
 	return msg_send(&dst, ack, ack_len);
333 330
 }
334 331
 
... ...
@@ -170,8 +170,7 @@ static inline unsigned int dlg2hash( dlg_t* dlg )
170 170
 int t_uac(str* method, str* headers, str* body, dlg_t* dialog,
171 171
 	  transaction_cb cb, void* cbp)
172 172
 {
173
-	struct socket_info* send_sock;
174
-	union sockaddr_union to_su;
173
+	struct dest_info dst;
175 174
 	struct cell *new_cell;
176 175
 	struct retr_buf *request;
177 176
 	char* buf;
... ...
@@ -189,8 +188,9 @@ int t_uac(str* method, str* headers, str* body, dlg_t* dialog,
189 189
 	DBG("DEBUG:tm:t_uac: next_hop=<%.*s>\n",dialog->hooks.next_hop->len,
190 190
 			dialog->hooks.next_hop->s);
191 191
 	/* it's a new message, so we will take the default socket */
192
-	send_sock = uri2sock(0, dialog->hooks.next_hop, &to_su, PROTO_NONE);
193
-	if (!send_sock) {
192
+	if ((uri2dst(&dst, 0, dialog->hooks.next_hop, PROTO_NONE)==0) ||
193
+			(dst.send_sock==0)){
194
+		ser_error = E_NO_SOCKET;
194 195
 		ret=ser_error;
195 196
 		LOG(L_ERR, "t_uac: no socket found\n");
196 197
 		goto error2;
... ...
@@ -233,11 +233,7 @@ int t_uac(str* method, str* headers, str* body, dlg_t* dialog,
233 233
 
234 234
 	request = &new_cell->uac[0].request;
235 235
 	
236
-	init_dest_info(&request->dst);
237
-	request->dst.to = to_su;
238
-	request->dst.send_sock = send_sock;
239
-	request->dst.proto = send_sock->proto;
240
-	request->dst.id = 0;
236
+	request->dst = dst;
241 237
 
242 238
 	hi=dlg2hash(dialog);
243 239
 	LOCK_HASH(hi);
... ...
@@ -245,7 +241,7 @@ int t_uac(str* method, str* headers, str* body, dlg_t* dialog,
245 245
 	UNLOCK_HASH(hi);
246 246
 
247 247
 	buf = build_uac_req(method, headers, body, dialog, 0, new_cell,
248
-		&buf_len, send_sock);
248
+		&buf_len, &dst);
249 249
 	if (!buf) {
250 250
 		LOG(L_ERR, "t_uac: Error while building message\n");
251 251
 		ret=E_OUT_OF_MEM;
... ...
@@ -135,13 +135,17 @@ inline static struct proxy_l *uri2proxy( str *uri, int proto )
135 135
 
136 136
 /*
137 137
  * Convert a URI into a dest_info structure
138
- * params: dst - will be filled
138
+ * params: msg - sip message used to set dst->send_sock, if 0 dst->send_sock
139
+ *               will be set to the default w/o using msg->force_send_socket 
140
+ *               (see get_send_socket()) 
141
+ *         dst - will be filled
139 142
  *         uri - uri in str form
140 143
  *         proto - if != PROTO_NONE, this protocol will be forced over the
141 144
  *                 uri_proto, otherwise the uri proto will be used
142 145
  * returns 0 on error, dst on success
143 146
  */
144
-inline static struct dest_info *uri2dst(struct dest_info* dst, str *uri, 
147
+inline static struct dest_info *uri2dst(struct dest_info* dst,
148
+										struct sip_msg *msg, str *uri, 
145 149
 											int proto )
146 150
 {
147 151
 	struct sip_uri parsed_uri;
... ...
@@ -165,37 +169,53 @@ inline static struct dest_info *uri2dst(struct dest_info* dst, str *uri,
165 165
 	
166 166
 	init_dest_info(dst);
167 167
 	dst->proto= get_proto(proto, uri_proto);
168
+#ifdef USE_COMP
169
+	dst->comp=parsed_uri.comp;
170
+#endif
168 171
 	sip_hostport2su(&dst->to, &parsed_uri.host, parsed_uri.port_no,
169 172
 						dst->proto);
173
+	if (msg){
174
+		dst->send_sock = get_send_socket(msg, &dst->to, dst->proto);
175
+		if (dst->send_sock==0) {
176
+			LOG(L_ERR, "ERROR: uri2sock: no corresponding socket for af %d\n", 
177
+					dst->to.s.sa_family);
178
+			/* ser_error = E_NO_SOCKET;*/
179
+			/* try to continue */
180
+		}
181
+	}
170 182
 	return dst;
171 183
 }
172 184
 
173 185
 
174 186
 
175 187
 /*
176
- * Convert a URI into socket_info
188
+ * Convert a URI into the corresponding sockaddr_union (address to send to) and
189
+ *  send socket_info (socket/address from which to send)
190
+ *  to_su is filled with the destination and the socket_info that will be 
191
+ *  used for sending is returned.
192
+ *  On error return 0.
193
+ *
194
+ *  NOTE: this function is deprecated, you should use uri2dst instead
177 195
  */
178 196
 static inline struct socket_info *uri2sock(struct sip_msg* msg, str *uri,
179 197
 									union sockaddr_union *to_su, int proto)
180 198
 {
181
-	struct socket_info* send_sock;
182 199
 	struct dest_info dst;
183 200
 
184
-	if (uri2dst(&dst, uri, proto)==0){
201
+	if (uri2dst(&dst, msg, uri, proto)==0){
185 202
 		LOG(L_ERR, "ERROR: uri2sock: Can't create a dst proxy\n");
186 203
 		ser_error=E_BAD_ADDRESS;
187 204
 		return 0;
188 205
 	}
189 206
 	*to_su=dst.to; /* copy su */
190 207
 	
191
-	/* we use dst->proto since uri2dst just set it correctly*/
192
-	send_sock = get_send_socket(msg, to_su, dst.proto);
193
-	if (!send_sock) {
208
+	/* we use dst->send_socket since uri2dst just set it correctly*/
209
+	if (dst.send_sock==0) {
194 210
 		LOG(L_ERR, "ERROR: uri2sock: no corresponding socket for af %d\n", 
195 211
 		    to_su->s.sa_family);
196 212
 		ser_error = E_NO_SOCKET;
197 213
 	}
198
-	return send_sock;
214
+	return dst.send_sock;
199 215
 }
200 216
 
201 217
 
... ...
@@ -56,6 +56,9 @@
56 56
  * 2003-10-08  receive_test function-alized (jiri)
57 57
  * 2003-10-20  added body_lump list (sip_msg), adjust_clen (andrei & jan)
58 58
  * 2003-11-11  type of rpl_lumps replaced by flags (bogdan)
59
+ * 2006-04-20  build_req_from_sip_req, via_builder and lump_* functions
60
+ *              use now struct dest_info; lumps & via comp param support
61
+ *              (rfc3486) (andrei)
59 62
  *
60 63
  */
61 64
 /* Via special params:
... ...
@@ -436,7 +439,7 @@ char* clen_builder(struct sip_msg* msg, int *clen_len, int diff)
436 436
  * returns 1 if cond is true, 0 if false */
437 437
 static inline int lump_check_opt(	enum lump_conditions cond,
438 438
 									struct sip_msg* msg,
439
-									struct socket_info* snd_s
439
+									struct dest_info* snd_i
440 440
 									)
441 441
 {
442 442
 	struct ip_addr* ip;
... ...
@@ -444,7 +447,7 @@ static inline int lump_check_opt(	enum lump_conditions cond,
444 444
 	int proto;
445 445
 
446 446
 #define get_ip_port_proto \
447
-			if (snd_s==0){ \
447
+			if ((snd_i==0) || (snd_i->send_sock==0)){ \
448 448
 				LOG(L_CRIT, "ERROR: lump_check_opt: null send socket\n"); \
449 449
 				return 1; /* we presume they are different :-) */ \
450 450
 			} \
... ...
@@ -466,30 +469,34 @@ static inline int lump_check_opt(	enum lump_conditions cond,
466 466
 		case COND_IF_DIFF_REALMS:
467 467
 			get_ip_port_proto;
468 468
 			/* faster tests first */
469
-			if ((port==snd_s->port_no)&&(proto==snd_s->proto)&&
470
-				(ip_addr_cmp(ip, &snd_s->address)))
469
+			if ((port==snd_i->send_sock->port_no) && 
470
+					(proto==snd_i->send_sock->proto) &&
471
+#ifdef USE_COMP
472
+					(msg->rcv.comp==snd_i->comp) &&
473
+#endif
474
+					(ip_addr_cmp(ip, &snd_i->send_sock->address)))
471 475
 				return 0;
472 476
 			else return 1;
473 477
 		case COND_IF_DIFF_AF:
474 478
 			get_ip_port_proto;
475
-			if (ip->af!=snd_s->address.af) return 1;
479
+			if (ip->af!=snd_i->send_sock->address.af) return 1;
476 480
 			else return 0;
477 481
 		case COND_IF_DIFF_PROTO:
478 482
 			get_ip_port_proto;
479
-			if (proto!=snd_s->proto) return 1;
483
+			if (proto!=snd_i->send_sock->proto) return 1;
480 484
 			else return 0;
481 485
 		case COND_IF_DIFF_PORT:
482 486
 			get_ip_port_proto;
483
-			if (port!=snd_s->port_no) return 1;
487
+			if (port!=snd_i->send_sock->port_no) return 1;
484 488
 			else return 0;
485 489
 		case COND_IF_DIFF_IP:
486 490
 			get_ip_port_proto;
487
-			if (ip_addr_cmp(ip, &snd_s->address)) return 0;
491
+			if (ip_addr_cmp(ip, &snd_i->send_sock->address)) return 0;
488 492
 			else return 1;
489 493
 		case COND_IF_RAND:
490 494
 			return (rand()>=RAND_MAX/2);
491 495
 		default:
492
-			LOG(L_CRIT, "BUG: lump_check_opt: unknown lump condition %d\n",
496
+			LOG(L_CRIT, "BUG: lump:w_check_opt: unknown lump condition %d\n",
493 497
 					cond);
494 498
 	}
495 499
 	return 0; /* false */
... ...
@@ -499,7 +506,8 @@ static inline int lump_check_opt(	enum lump_conditions cond,
499 499
 
500 500
 /* computes the "unpacked" len of a lump list,
501 501
    code moved from build_req_from_req */
502
-static inline int lumps_len(struct sip_msg* msg, struct lump* lumps, struct socket_info* send_sock)
502
+static inline int lumps_len(struct sip_msg* msg, struct lump* lumps, 
503
+								struct dest_info* send_info)
503 504
 {
504 505
 	int s_offset;
505 506
 	int new_len;
... ...
@@ -507,7 +515,46 @@ static inline int lumps_len(struct sip_msg* msg, struct lump* lumps, struct sock
507 507
 	struct lump* r;
508 508
 	str* send_address_str;
509 509
 	str* send_port_str;
510
+	struct socket_info* send_sock;
511
+	
512
+
513
+#ifdef USE_COMP
514
+	#define RCVCOMP_LUMP_LEN \
515
+						/* add;comp=xxx */ \
516
+					switch(msg->rcv.comp){ \
517
+						case COMP_NONE: \
518
+								break; \
519
+						case COMP_SIGCOMP: \
520
+								new_len+=COMP_PARAM_LEN+SIGCOMP_NAME_LEN; \
521
+								break; \
522
+						case COMP_SERGZ: \
523
+								new_len+=COMP_PARAM_LEN+SERGZ_NAME_LEN ; \
524
+								break; \
525
+						default: \
526
+						LOG(L_CRIT, "BUG: lumps_len: unknown comp %d\n", \
527
+								msg->rcv.comp); \
528
+					}
510 529
 
530
+	#define SENDCOMP_LUMP_LEN \
531
+					/* add;comp=xxx */ \
532
+					switch(send_info->comp){ \
533
+						case COMP_NONE: \
534
+								break; \
535
+						case COMP_SIGCOMP: \
536
+								new_len+=COMP_PARAM_LEN+SIGCOMP_NAME_LEN; \
537
+								break; \
538
+						case COMP_SERGZ: \
539
+								new_len+=COMP_PARAM_LEN+SERGZ_NAME_LEN ; \
540
+								break; \
541
+						default: \
542
+						LOG(L_CRIT, "BUG: lumps_len: unknown comp %d\n", \
543
+								send_info->comp); \
544
+					}
545
+#else
546
+	#define RCVCOMP_LUMP_LEN
547
+	#define SENDCOMP_LUMP_LEN
548
+#endif /*USE_COMP */
549
+	
511 550
 #define SUBST_LUMP_LEN(subst_l) \
512 551
 		switch((subst_l)->u.subst){ \
513 552
 			case SUBST_RCV_IP: \
... ...
@@ -574,6 +621,7 @@ static inline int lumps_len(struct sip_msg* msg, struct lump* lumps, struct sock
574 574
 						LOG(L_CRIT, "BUG: lumps_len: unknown proto %d\n", \
575 575
 								msg->rcv.bind_address->proto); \
576 576
 					}\
577
+					RCVCOMP_LUMP_LEN \
577 578
 				}else{ \
578 579
 					/* FIXME */ \
579 580
 					LOG(L_CRIT, "FIXME: null bind_address\n"); \
... ...
@@ -646,6 +694,7 @@ static inline int lumps_len(struct sip_msg* msg, struct lump* lumps, struct sock
646 646
 						LOG(L_CRIT, "BUG: lumps_len: unknown proto %d\n", \
647 647
 								send_sock->proto); \
648 648
 					}\
649
+					SENDCOMP_LUMP_LEN \
649 650
 				}else{ \
650 651
 					/* FIXME */ \
651 652
 					LOG(L_CRIT, "FIXME: lumps_len called with" \
... ...
@@ -658,7 +707,12 @@ static inline int lumps_len(struct sip_msg* msg, struct lump* lumps, struct sock
658 658
 				LOG(L_CRIT, "BUG: unknown subst type %d\n", \
659 659
 						(subst_l)->u.subst); \
660 660
 		}
661
-
661
+	
662
+	if (send_info){
663
+		send_sock=send_info->send_sock;
664
+	}else{
665
+		send_sock=0;
666
+	};
662 667
 	s_offset=0;
663 668
 	new_len=0;
664 669
 	/* init send_address_str & send_port_str */
... ...
@@ -674,7 +728,7 @@ static inline int lumps_len(struct sip_msg* msg, struct lump* lumps, struct sock
674 674
 
675 675
 	for(t=lumps;t;t=t->next){
676 676
 		/* skip if this is an OPT lump and the condition is not satisfied */
677
-		if ((t->op==LUMP_ADD_OPT) && !lump_check_opt(t->u.cond, msg, send_sock))
677
+		if ((t->op==LUMP_ADD_OPT)&& !lump_check_opt(t->u.cond, msg, send_info))
678 678
 			continue;
679 679
 		for(r=t->before;r;r=r->before){
680 680
 			switch(r->op){
... ...
@@ -687,7 +741,7 @@ static inline int lumps_len(struct sip_msg* msg, struct lump* lumps, struct sock
687 687
 				case LUMP_ADD_OPT:
688 688
 					/* skip if this is an OPT lump and the condition is
689 689
 					 * not satisfied */
690
-					if (!lump_check_opt(r->u.cond, msg, send_sock))
690
+					if (!lump_check_opt(r->u.cond, msg, send_info))
691 691
 						goto skip_before;
692 692
 					break;
693 693
 				default:
... ...
@@ -743,7 +797,7 @@ skip_before:
743 743
 				case LUMP_ADD_OPT:
744 744
 					/* skip if this is an OPT lump and the condition is
745 745
 					 * not satisfied */
746
-					if (!lump_check_opt(r->u.cond, msg, send_sock))
746
+					if (!lump_check_opt(r->u.cond, msg, send_info))
747 747
 						goto skip_after;
748 748
 					break;
749 749
 				default:
... ...
@@ -756,6 +810,8 @@ skip_after:
756 756
 		; /* to make gcc 3.* happy */
757 757
 	}
758 758
 	return new_len;
759
+#undef RCVCOMP_LUMP_LEN
760
+#undef SENDCOMP_LUMP_LEN
759 761
 }
760 762
 
761 763
 
... ...
@@ -768,7 +824,7 @@ static inline void process_lumps(	struct sip_msg* msg,
768 768
 									char* new_buf,
769 769
 									unsigned int* new_buf_offs,
770 770
 									unsigned int* orig_offs,
771
-									struct socket_info* send_sock)
771
+									struct dest_info* send_info)
772 772
 {
773 773
 	struct lump *t;
774 774
 	struct lump *r;
... ...
@@ -778,6 +834,58 @@ static inline void process_lumps(	struct sip_msg* msg,
778 778
 	int s_offset;
779 779
 	str* send_address_str;
780 780
 	str* send_port_str;
781
+	struct socket_info* send_sock;
782
+
783
+#ifdef USE_COMP
784
+	#define RCVCOMP_PARAM_ADD \
785
+				/* add ;comp=xxxx */ \
786
+				switch(msg->rcv.comp){ \
787
+					case COMP_NONE: \
788
+						break; \
789
+					case COMP_SIGCOMP: \
790
+						memcpy(new_buf+offset, COMP_PARAM, COMP_PARAM_LEN);\
791
+						offset+=COMP_PARAM_LEN; \
792
+						memcpy(new_buf+offset, SIGCOMP_NAME, \
793
+								SIGCOMP_NAME_LEN); \
794
+						offset+=SIGCOMP_NAME_LEN; \
795
+						break; \
796
+					case COMP_SERGZ: \
797
+						memcpy(new_buf+offset, COMP_PARAM, COMP_PARAM_LEN);\
798
+						offset+=COMP_PARAM_LEN; \
799
+						memcpy(new_buf+offset, SERGZ_NAME, SERGZ_NAME_LEN); \
800
+						offset+=SERGZ_NAME_LEN; \
801
+						break;\
802
+					default:\
803
+						LOG(L_CRIT, "BUG: process_lumps: unknown comp %d\n", \
804
+								msg->rcv.comp); \
805
+				}
806
+	
807
+	#define SENDCOMP_PARAM_ADD \
808
+				/* add ;comp=xxxx */ \
809
+				switch(send_info->comp){ \
810
+					case COMP_NONE: \
811
+						break; \
812
+					case COMP_SIGCOMP: \
813
+						memcpy(new_buf+offset, COMP_PARAM, COMP_PARAM_LEN);\
814
+						offset+=COMP_PARAM_LEN; \
815
+						memcpy(new_buf+offset, SIGCOMP_NAME, \
816
+								SIGCOMP_NAME_LEN); \
817
+						offset+=SIGCOMP_NAME_LEN; \
818
+						break; \
819
+					case COMP_SERGZ: \
820
+						memcpy(new_buf+offset, COMP_PARAM, COMP_PARAM_LEN);\
821
+						offset+=COMP_PARAM_LEN; \
822
+						memcpy(new_buf+offset, SERGZ_NAME, SERGZ_NAME_LEN); \
823
+						offset+=SERGZ_NAME_LEN; \
824
+						break;\
825
+					default:\
826
+						LOG(L_CRIT, "BUG: process_lumps: unknown comp %d\n", \
827
+								msg->rcv.comp); \
828
+				} 
829
+#else
830
+	#define RCVCOMP_PARAM_ADD
831
+	#define SENDCOMP_PARAM_ADD
832
+#endif /* USE_COMP */
781 833
 
782 834
 #define SUBST_LUMP(subst_l) \
783 835
 	switch((subst_l)->u.subst){ \
... ...
@@ -856,6 +964,7 @@ static inline void process_lumps(	struct sip_msg* msg,
856 856
 						LOG(L_CRIT, "BUG: process_lumps: unknown proto %d\n", \
857 857
 								msg->rcv.bind_address->proto); \
858 858
 				} \
859
+				RCVCOMP_PARAM_ADD \
859 860
 			}else{  \
860 861
 				/*FIXME*/ \
861 862
 				LOG(L_CRIT, "FIXME: process_lumps: null bind_address\n"); \
... ...
@@ -942,6 +1051,7 @@ static inline void process_lumps(	struct sip_msg* msg,
942 942
 						LOG(L_CRIT, "BUG: process_lumps: unknown proto %d\n", \
943 943
 								send_sock->proto); \
944 944
 				} \
945
+				SENDCOMP_PARAM_ADD \
945 946
 			}else{  \
946 947
 				/*FIXME*/ \
947 948
 				LOG(L_CRIT, "FIXME: process_lumps: null bind_address\n"); \
... ...
@@ -1008,11 +1118,15 @@ static inline void process_lumps(	struct sip_msg* msg,
1008 1008
 			}; \
1009 1009
 			break; \
1010 1010
 		default: \
1011
-					LOG(L_CRIT, "BUG: process_lumps: unknown subst type %d\n", \
1011
+				LOG(L_CRIT, "BUG: process_lumps: unknown subst type %d\n", \
1012 1012
 							(subst_l)->u.subst); \
1013
-	} \
1014
- \
1013
+	}
1015 1014
 
1015
+	if (send_info){
1016
+		send_sock=send_info->send_sock;
1017
+	}else{
1018
+		send_sock=0;
1019
+	}
1016 1020
 	/* init send_address_str & send_port_str */
1017 1021
 	if (msg->set_global_address.len)
1018 1022
 		send_address_str=&(msg->set_global_address);
... ...
@@ -1036,7 +1150,7 @@ static inline void process_lumps(	struct sip_msg* msg,
1036 1036
 				/* skip if this is an OPT lump and the condition is
1037 1037
 				 * not satisfied */
1038 1038
 				if ((t->op==LUMP_ADD_OPT) &&
1039
-						(!lump_check_opt(t->u.cond, msg, send_sock)))
1039
+						(!lump_check_opt(t->u.cond, msg, send_info)))
1040 1040
 					continue;
1041 1041
 				/* just add it here! */
1042 1042
 				/* process before  */
... ...
@@ -1053,7 +1167,7 @@ static inline void process_lumps(	struct sip_msg* msg,
1053 1053
 						case LUMP_ADD_OPT:
1054 1054
 							/* skip if this is an OPT lump and the condition is
1055 1055
 					 		* not satisfied */
1056
-							if (!lump_check_opt(r->u.cond, msg, send_sock))
1056
+							if (!lump_check_opt(r->u.cond, msg, send_info))
1057 1057
 								goto skip_before;
1058 1058
 							break;
1059 1059
 						default:
... ...
@@ -1094,7 +1208,7 @@ skip_before:
1094 1094
 						case LUMP_ADD_OPT:
1095 1095
 							/* skip if this is an OPT lump and the condition is
1096 1096
 					 		* not satisfied */
1097
-							if (!lump_check_opt(r->u.cond, msg, send_sock))
1097
+							if (!lump_check_opt(r->u.cond, msg, send_info))
1098 1098
 								goto skip_after;
1099 1099
 							break;
1100 1100
 						default:
... ...
@@ -1135,7 +1249,7 @@ skip_after:
1135 1135
 						case LUMP_ADD_OPT:
1136 1136
 							/* skip if this is an OPT lump and the condition is
1137 1137
 					 		* not satisfied */
1138
-							if (!lump_check_opt(r->u.cond, msg, send_sock))
1138
+							if (!lump_check_opt(r->u.cond, msg, send_info))
1139 1139
 								goto skip_nop_before;
1140 1140
 							break;
1141 1141
 						default:
... ...
@@ -1164,7 +1278,7 @@ skip_nop_before:
1164 1164
 						case LUMP_ADD_OPT:
1165 1165
 							/* skip if this is an OPT lump and the condition is
1166 1166
 					 		* not satisfied */
1167
-							if (!lump_check_opt(r->u.cond, msg, send_sock))
1167
+							if (!lump_check_opt(r->u.cond, msg, send_info))
1168 1168
 								goto skip_nop_after;
1169 1169
 							break;
1170 1170
 						default:
... ...
@@ -1182,6 +1296,8 @@ skip_nop_after:
1182 1182
 	}
1183 1183
 	*new_buf_offs=offset;
1184 1184
 	*orig_offs=s_offset;
1185
+#undef RCVCOMP_PARAM_ADD 
1186
+#undef SENDCOMP_PARAM_ADD
1185 1187
 }
1186 1188
 
1187 1189
 
... ...
@@ -1285,7 +1401,7 @@ error:
1285 1285
 
1286 1286
 char * build_req_buf_from_sip_req( struct sip_msg* msg,
1287 1287
 								unsigned int *returned_len,
1288
-								struct socket_info* send_sock, int proto)
1288
+								struct dest_info* send_info)
1289 1289
 {
1290 1290
 	unsigned int len, new_len, received_len, rport_len, uri_len, via_len, body_delta;
1291 1291
 	char* line_buf;
... ...
@@ -1343,8 +1459,8 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
1343 1343
 	     /* Calculate message body difference and adjust
1344 1344
 	      * Content-Length
1345 1345
 	      */
1346
-	body_delta = lumps_len(msg, msg->body_lumps, send_sock);
1347
-	if (adjust_clen(msg, body_delta, proto) < 0) {
1346
+	body_delta = lumps_len(msg, msg->body_lumps, send_info);
1347
+	if (adjust_clen(msg, body_delta, send_info->proto) < 0) {
1348 1348
 		LOG(L_ERR, "ERROR: build_req_buf_from_sip_req: Error while adjusting"
1349 1349
 				" Content-Length\n");
1350 1350
 		goto error00;
... ...
@@ -1353,8 +1469,8 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
1353 1353
 	branch.s=msg->add_to_branch_s;
1354 1354
 	branch.len=msg->add_to_branch_len;
1355 1355
 	set_hostport(&hp, msg);
1356
-	line_buf = via_builder( &via_len, send_sock, &branch,
1357
-							extra_params.len?&extra_params:0, proto, &hp);
1356
+	line_buf = via_builder( &via_len, send_info, &branch,
1357
+							extra_params.len?&extra_params:0, &hp);
1358 1358
 	if (!line_buf){
1359 1359
 		LOG(L_ERR,"ERROR: build_req_buf_from_sip_req: no via received!\n");
1360 1360
 		goto error00;
... ...
@@ -1441,7 +1557,7 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
1441 1441
 	}
1442 1442
 
1443 1443
 	/* compute new msg len and fix overlapping zones*/
1444
-	new_len=len+body_delta+lumps_len(msg, msg->add_rm, send_sock);
1444
+	new_len=len+body_delta+lumps_len(msg, msg->add_rm, send_info);
1445 1445
 #ifdef XL_DEBUG
1446 1446
 	LOG(L_ERR, "DEBUG: new_len(%d)=len(%d)+lumps_len\n", new_len, len);
1447 1447
 #endif
... ...
@@ -1471,8 +1587,8 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
1471 1471
 	}
1472 1472
 	new_buf[new_len]=0;
1473 1473
 	/* copy msg adding/removing lumps */
1474
-	process_lumps(msg, msg->add_rm, new_buf, &offset, &s_offset, send_sock);
1475
-	process_lumps(msg, msg->body_lumps, new_buf, &offset, &s_offset,send_sock);
1474
+	process_lumps(msg, msg->add_rm, new_buf, &offset, &s_offset, send_info);
1475
+	process_lumps(msg, msg->body_lumps, new_buf, &offset, &s_offset,send_info);
1476 1476
 	/* copy the rest of the message */
1477 1477
 	memcpy(new_buf+offset, buf+s_offset, len-s_offset);
1478 1478
 	new_buf[new_len]=0;
... ...
@@ -1931,16 +2047,24 @@ int branch_builder( unsigned int hash_index,
1931 1931
 }
1932 1932
 
1933 1933
 
1934
+
1935
+/* uses only the send_info->send_socket, send_info->proto and 
1936
+ * send_info->comp (so that a send_info used for sending can be passed
1937
+ * to this function w/o changes and the correct via will be built) */
1934 1938
 char* via_builder( unsigned int *len,
1935
-	struct socket_info* send_sock,
1936
-	str* branch, str* extra_params, int proto, struct hostport* hp)
1939
+	struct dest_info* send_info /* where to send the reply */,
1940
+	str* branch, str* extra_params, struct hostport* hp)
1937 1941
 {
1938 1942
 	unsigned int  via_len, extra_len;
1939 1943
 	char               *line_buf;
1940 1944
 	int max_len;
1941 1945
 	str* address_str; /* address displayed in via */
1942 1946
 	str* port_str; /* port no displayed in via */
1947
+	struct socket_info* send_sock;
1948
+	int comp_len, comp_name_len;
1949
+	char* comp_name;
1943 1950
 
1951
+	send_sock=send_info->send_sock;
1944 1952
 	/* use pre-set address in via or the outbound socket one */
1945 1953
 	if ( hp && hp->host->len)
1946 1954
 		address_str=hp->host;
... ...
@@ -1950,12 +2074,36 @@ char* via_builder( unsigned int *len,
1950 1950
 		port_str=hp->port;
1951 1951
 	else
1952 1952
 		port_str=&(send_sock->port_no_str);
1953
-
1953
+	
1954
+	comp_len=comp_name_len=0;
1955
+	comp_name=0;
1956
+#ifdef USE_COMP
1957
+	switch(send_info->comp){
1958
+		case COMP_NONE:
1959
+			break;
1960
+		case COMP_SIGCOMP:
1961
+			comp_len=COMP_PARAM_LEN;
1962
+			comp_name_len=SIGCOMP_NAME_LEN;
1963
+			comp_name=SIGCOMP_NAME;
1964
+			break;
1965
+		case COMP_SERGZ:
1966
+			comp_len=COMP_PARAM_LEN;
1967
+			comp_name_len=SERGZ_NAME_LEN;
1968
+			comp_name=SERGZ_NAME;
1969
+			break;
1970
+		default:
1971
+			LOG(L_CRIT, "BUG: via_builder: unknown comp %d\n",
1972
+					send_info->comp);
1973
+			/* continue, we'll just ignore comp */
1974
+	}
1975
+#endif /* USE_COMP */
1976
+			
1954 1977
 	max_len=MY_VIA_LEN+address_str->len /* space in MY_VIA */
1955 1978
 		+2 /* just in case it is a v6 address ... [ ] */
1956 1979
 		+1 /*':'*/+port_str->len
1957 1980
 		+(branch?(MY_BRANCH_LEN+branch->len):0)
1958 1981
 		+(extra_params?extra_params->len:0)
1982
+		+comp_len+comp_name_len
1959 1983
 		+CRLF_LEN+1;
1960 1984
 	line_buf=pkg_malloc( max_len );
1961 1985
 	if (line_buf==0){
... ...
@@ -1969,14 +2117,14 @@ char* via_builder( unsigned int *len,
1969 1969
 	via_len=MY_VIA_LEN+address_str->len; /*space included in MY_VIA*/
1970 1970
 
1971 1971
 	memcpy(line_buf, MY_VIA, MY_VIA_LEN);
1972
-	if (proto==PROTO_UDP){
1972
+	if (send_info->proto==PROTO_UDP){
1973 1973
 		/* do nothing */
1974
-	}else if (proto==PROTO_TCP){
1974
+	}else if (send_info->proto==PROTO_TCP){
1975 1975
 		memcpy(line_buf+MY_VIA_LEN-4, "TCP ", 4);
1976
-	}else if (proto==PROTO_TLS){
1976
+	}else if (send_info->proto==PROTO_TLS){
1977 1977
 		memcpy(line_buf+MY_VIA_LEN-4, "TLS ", 4);
1978 1978
 	}else{
1979
-		LOG(L_CRIT, "BUG: via_builder: unknown proto %d\n", proto);
1979
+		LOG(L_CRIT, "BUG: via_builder: unknown proto %d\n", send_info->proto);
1980 1980
 		return 0;
1981 1981
 	}
1982 1982
 #	ifdef USE_IPV6
... ...
@@ -2009,6 +2157,15 @@ char* via_builder( unsigned int *len,
2009 2009
 		memcpy(line_buf+via_len, extra_params->s, extra_params->len);
2010 2010
 		via_len+=extra_params->len;
2011 2011
 	}
2012
+#ifdef USE_COMP
2013
+	/* comp */
2014
+	if (comp_len){
2015
+		memcpy(line_buf+via_len, COMP_PARAM, COMP_PARAM_LEN);
2016
+		via_len+=COMP_PARAM_LEN;
2017
+		memcpy(line_buf+via_len, comp_name, comp_name_len);
2018
+		via_len+=comp_name_len;
2019
+	}
2020
+#endif
2012 2021
 
2013 2022
 	memcpy(line_buf+via_len, CRLF, CRLF_LEN);
2014 2023
 	via_len+=CRLF_LEN;
... ...
@@ -76,8 +76,7 @@ struct hostport {
76 76
 	}while(0)
77 77
 
78 78
 char * build_req_buf_from_sip_req (	struct sip_msg* msg, 
79
-				unsigned int *returned_len, struct socket_info* send_sock,
80
-				int proto);
79
+				unsigned int *returned_len, struct dest_info* send_info);
81 80
 
82 81
 char * build_res_buf_from_sip_res(	struct sip_msg* msg,
83 82
 				unsigned int *returned_len);
... ...
@@ -103,8 +102,8 @@ char * build_res_buf_with_body_from_sip_req(	unsigned int code ,
103 103
 				struct bookmark *bmark);
104 104
 */
105 105
 char* via_builder( unsigned int *len,
106
-	struct socket_info* send_sock,
107
-	str *branch, str* extra_params, int proto, struct hostport *hp );
106
+	struct dest_info* send_info,
107
+	str *branch, str* extra_params, struct hostport *hp );
108 108
 
109 109
 
110 110
 int branch_builder( unsigned int hash_index, 
... ...
@@ -38,6 +38,7 @@
38 38
  *  2003-11-02  added diversion header field to sip_msg (jh)
39 39
  *  2004-11-08  added force_send_socket (andrei)
40 40
  *  2005-02-25  uri types added (sip, sips & tel)  (andrei)
41
+ *  2006-04-20  uri comp member (only if USE_COMP is defined) (andrei)
41 42
  */
42 43
 
43 44
 
... ...
@@ -140,6 +141,9 @@ struct sip_uri {
140 140
 	unsigned short port_no;
141 141
 	unsigned short proto; /* from transport */
142 142
 	uri_type type; /* uri scheme */
143
+#ifdef USE_COMP
144
+	unsigned short comp;
145
+#endif
143 146
 	/* parameters */
144 147
 	str transport;
145 148
 	str ttl;
... ...
@@ -35,6 +35,7 @@
35 35
  * 2003-07-03  sips:, r2, lr=on support added (andrei)
36 36
  * 2005-02-25  preliminary tel uri support (andrei)
37 37
  * 2005-03-03  more tel uri fixes (andrei)
38
+ * 2006-04-20  comp uri param. support (rfc3486) if defined USE_COMP  (andrei)
38 39
  */
39 40
 
40 41
 
... ...
@@ -73,6 +74,19 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
73 73
 					PLR_L, PLR_R_FIN, PLR_eq,
74 74
 					/* r2 */
75 75
 					PR2_R, PR2_2_FIN, PR2_eq,
76
+#ifdef USE_COMP
77
+					/* comp */
78
+					PCOMP_C, PCOMP_O, PCOMP_M, PCOMP_P, PCOMP_eq,
79
+					
80
+					/* comp values */
81
+					/* sigcomp */
82
+					VCOMP_S, VCOMP_SIGC_I, VCOMP_SIGC_G,
83
+					VCOMP_SIGC_C, VCOMP_SIGC_O,  VCOMP_SIGC_M,
84
+					VCOMP_SIGC_P_FIN,
85
+					/* sergz */
86
+							VCOMP_SGZ_E, VCOMP_SGZ_R, VCOMP_SGZ_G,
87
+							VCOMP_SGZ_Z_FIN,
88
+#endif
76 89
 					
77 90
 					/* transport values */
78 91
 					/* udp */
... ...
@@ -100,6 +114,10 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
100 100
 	int error_headers;
101 101
 	unsigned int scheme;
102 102
 	uri_type backup;
103
+#ifdef USE_COMP
104
+	str comp_str; /* not returned for now */
105
+	str comp_val; /* not returned for now */
106
+#endif
103 107
 	
104 108
 #define SIP_SCH		0x3a706973
105 109
 #define SIPS_SCH	0x73706973
... ...
@@ -313,7 +331,30 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
313 313
 				} \
314 314
 				break
315 315
 			
316
-	
316
+
317
+#ifdef USE_COMP
318
+#define comp_fin(c_state, comp_no) \
319
+			case c_state: \
320
+				switch(*p){ \
321
+					case '@': \
322
+						still_at_user; \
323
+						break; \
324
+					semicolon_case; \
325
+						/* param_set(b, v); */ \
326
+						uri->comp=(comp_no); \
327
+						break; \
328
+					question_case; \
329
+						/* param_set(b, v) */; \
330
+						uri->comp=(comp_no); \
331
+						break; \
332
+					colon_case;  \
333
+					default: \
334
+						state=URI_VAL_P; \
335
+						break; \
336
+				} \
337
+				break
338
+			
339
+#endif
317 340
 
318 341
 	/* init */
319 342
 	end=buf+len;
... ...
@@ -579,6 +620,13 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
579 579
 						b=p;
580 580
 						state=PR2_R;
581 581
 						break;
582
+#ifdef USE_COMP
583
+					case 'c':
584
+					case 'C':
585
+						b=p;
586
+						state=PCOMP_C;
587
+						break;
588
+#endif
582 589
 					default:
583 590
 						state=URI_PARAM_P;
584 591
 				}
... ...
@@ -784,6 +832,44 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
784 784
 						state=URI_VAL_P;
785 785
 				}
786 786
 				break;
787
+#ifdef USE_COMP
788
+			param_switch(PCOMP_C,  'o', 'O' , PCOMP_O);
789
+			param_switch(PCOMP_O,  'm', 'M' , PCOMP_M);
790
+			param_switch(PCOMP_M,  'p', 'P' , PCOMP_P);
791
+			param_switch1(PCOMP_P,  '=', PCOMP_eq);
792
+			/* value */
793
+			case PCOMP_eq:
794
+				param=&comp_str;
795
+				param_val=&comp_val;
796
+				switch (*p){
797
+					param_common_cases;
798
+					case 's':
799
+					case 'S':
800
+						v=p;
801
+						state=VCOMP_S;
802
+						break;
803
+					default:
804
+						v=p;
805
+						state=URI_VAL_P;
806
+				}
807
+				break;
808
+			/* sigcomp*/
809
+			value_switch_big(VCOMP_S, 'i', 'I', 'e', 'E',
810
+									VCOMP_SIGC_I, VCOMP_SGZ_E);
811
+			value_switch(VCOMP_SIGC_I, 'g', 'G', VCOMP_SIGC_G);
812
+			value_switch(VCOMP_SIGC_G, 'c', 'C', VCOMP_SIGC_C);
813
+			value_switch(VCOMP_SIGC_C, 'o', 'O', VCOMP_SIGC_O);
814
+			value_switch(VCOMP_SIGC_O, 'm', 'M', VCOMP_SIGC_M);
815
+			value_switch(VCOMP_SIGC_M, 'p', 'P', VCOMP_SIGC_P_FIN);
816
+			comp_fin(VCOMP_SIGC_P_FIN, COMP_SIGCOMP);
817
+			
818
+			/* sergz*/
819
+			value_switch(VCOMP_SGZ_E, 'r', 'R', VCOMP_SGZ_R);
820
+			value_switch(VCOMP_SGZ_R, 'g', 'G', VCOMP_SGZ_G);
821
+			value_switch(VCOMP_SGZ_G, 'z', 'Z', VCOMP_SGZ_Z_FIN);
822
+			comp_fin(VCOMP_SGZ_Z_FIN, COMP_SERGZ);
823
+#endif
824
+				
787 825
 				
788 826
 				
789 827
 			case URI_HEADERS:
... ...
@@ -893,6 +979,13 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
893 893
 		case PM_eq:
894 894
 		case PLR_L: /* lr */
895 895
 		case PR2_R:  /* r2 */
896
+#ifdef USE_COMP
897
+		case PCOMP_C:
898
+		case PCOMP_O:
899
+		case PCOMP_M:
900
+		case PCOMP_P:
901
+		case PCOMP_eq:
902
+#endif
896 903
 			uri->params.s=s;
897 904
 			uri->params.len=p-s;
898 905
 			break;
... ...
@@ -925,6 +1018,22 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
925 925
 			uri->params.len=p-s;
926 926
 			param_set(b, v);
927 927
 			break;
928
+#ifdef USE_COMP
929
+		case VCOMP_S:
930
+		case VCOMP_SIGC_I:
931
+		case VCOMP_SIGC_G:
932
+		case VCOMP_SIGC_C:
933
+		case VCOMP_SIGC_O:
934
+		case VCOMP_SIGC_M:
935
+		case VCOMP_SGZ_E:
936
+		case VCOMP_SGZ_R:
937
+		case VCOMP_SGZ_G:
938
+			/* unrecognized comp method, assume none */
939
+			uri->params.s=s;
940
+			uri->params.len=p-s;
941
+			/* uri->comp=COMP_NONE ; */
942
+			break;
943
+#endif
928 944
 		/* fin value states */
929 945
 		case VU_P_FIN:
930 946
 			uri->params.s=s;
... ...
@@ -950,6 +1059,20 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
950 950
 			param_set(b, v);
951 951
 			uri->proto=PROTO_SCTP;
952 952
 			break;
953
+#ifdef USE_COMP
954
+		case VCOMP_SIGC_P_FIN:
955
+			uri->params.s=s;
956
+			uri->params.len=p-s;
957
+			/* param_set(b, v); */
958
+			uri->comp=COMP_SIGCOMP;
959
+			break;
960
+		case VCOMP_SGZ_Z_FIN:
961
+			uri->params.s=s;
962
+			uri->params.len=p-s;
963
+			/* param_set(b, v); */
964
+			uri->comp=COMP_SERGZ;
965
+			break;
966
+#endif
953 967
 		/* headers */
954 968
 		case URI_HEADERS:
955 969
 			uri->headers.s=s;
... ...
@@ -1027,6 +1150,10 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
1027 1027
 			uri->maddr_val.len, ZSW(uri->maddr_val.s));
1028 1028
 	DBG("   lr=<%.*s>\n", uri->lr.len, ZSW(uri->lr.s)); 
1029 1029
 	DBG("   r2=<%.*s>\n", uri->r2.len, ZSW(uri->r2.s));
1030
+#ifdef USE_COMP
1031
+	DBG("   comp=%d\n", uri->comp);
1032
+#endif
1033
+
1030 1034
 #endif
1031 1035
 	return 0;
1032 1036
 	
... ...
@@ -49,6 +49,7 @@
49 49
  *  2004-03-31  fixed rport set instead of i bug (andrei)
50 50
  *  2005-03-02  if via has multiple bodies, and one of them is bad set
51 51
  *               also the first one as bad (andrei)
52
+ *  2006-02-24  added support for comp parameter parsing (see rfc3486) (andrei)
52 53
  */
53 54
 
54 55
 
... ...
@@ -106,9 +107,20 @@ enum {
106 106
 	RECEIVED7,
107 107
 	RPORT1, RPORT2, RPORT3,
108 108
 	ALIAS1, ALIAS2, ALIAS3, ALIAS4,
109
+#ifdef USE_COMP
110
+	COMP1, COMP2, COMP3, 
111
+	/* values */
112
+	L_COMP_VALUE, F_COMP_VALUE,
113
+	V_COMP_S, V_SIGCOMP_I, V_SIGCOMP_G, V_SIGCOMP_C, V_SIGCOMP_O, V_SIGCOMP_M,
114
+	FIN_V_SIGCOMP_P,
115
+	V_SERGZ_E, V_SERGZ_R, V_SERGZ_G, FIN_V_SERGZ_Z,
116
+#endif
109 117
 	     /* fin states (227-...)*/
110 118
 	FIN_HIDDEN = 230, FIN_TTL, FIN_BRANCH,
111 119
 	FIN_MADDR, FIN_RECEIVED, FIN_RPORT, FIN_I, FIN_ALIAS
120
+#ifdef USE_COMP
121
+	, FIN_COMP
122
+#endif
112 123
 	     /*GEN_PARAM,
113 124
 	       PARAM_ERROR*/ /* declared in msg_parser.h*/
114 125
 };
... ...
@@ -124,12 +136,94 @@ enum {
124 124
 static /*inline*/ char* parse_via_param(char* p, char* end,
125 125
 										unsigned char* pstate, 
126 126
 				    					unsigned char* psaved_state,
127
-										struct via_param* param)
127
+										struct via_param* param,
128
+										struct via_body* vb)
128 129
 {
129 130
 	char* tmp;
130 131
 	register unsigned char state;
131 132
 	unsigned char saved_state;
132 133
 
134
+#define value_case(c, C, oldstate, newstate, start_of_value) \
135
+			case (c): \
136
+			case (C): \
137
+				switch(state){ \
138
+					case (oldstate): \
139
+						state=(newstate); \
140
+						if ((start_of_value))  param->value.s=tmp; \
141
+						break; \
142
+					default_value_cases \
143
+				} \
144
+				break
145
+
146
+#define value_case_double(c, C, oldstate1, newstate1, oldstate2, newstate2) \
147
+			case (c): \
148
+			case (C): \
149
+				switch(state){ \
150
+					case (oldstate1): \
151
+						state=(newstate1); \
152
+						break; \
153
+					case (oldstate2): \
154
+						state=(newstate2); \
155
+						break; \
156
+					default_value_cases \
157
+				} \
158
+				break
159
+
160
+#define default_value_cases \
161
+					case F_VALUE: \
162
+						state=P_VALUE; \
163
+						param->value.s=tmp; \
164
+						break; \
165
+					case P_VALUE: \
166
+					case P_STRING: \
167
+						break; \
168
+					case F_LF: \
169
+					case F_CR:  \
170
+					case F_CRLF: \
171
+						state=END_OF_HEADER; \
172
+						goto end_via; \
173
+					default: \
174
+						switch(state){ \
175
+							case F_COMP_VALUE: \
176
+								comp_unexpected_char; \
177
+								state=P_VALUE; \
178
+								param->value.s=tmp; \
179
+								break; \
180
+							comp_states_cases \
181
+							comp_fin_states_cases \
182
+								comp_unexpected_char; \
183
+								state=P_VALUE; \
184
+								break; \
185
+							default: \
186
+								LOG(L_ERR, "ERROR: parse_via_param: invalid " \
187
+									"char <%c> in state %d\n", *tmp, state); \
188
+								goto error; \
189
+						}
190
+
191
+#define comp_states_cases \
192
+					case V_COMP_S: \
193
+					case V_SIGCOMP_I: \
194
+					case V_SIGCOMP_G: \
195
+					case V_SIGCOMP_C: \
196
+					case V_SIGCOMP_O: \
197
+					case V_SIGCOMP_M: \
198
+					case V_SERGZ_E: \
199
+					case V_SERGZ_R: \
200
+					case V_SERGZ_G: 
201
+
202
+#define comp_fin_states_cases \
203
+					case FIN_V_SIGCOMP_P: \
204
+					case FIN_V_SERGZ_Z:
205
+
206
+
207
+/* if unrecognized/bad comp, don't return error, just ignore comp */
208
+#define comp_unexpected_char \
209
+							LOG(L_ERR, "parse_via_param: bad/unrecognized" \
210
+									" comp method\n"); \