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 213
 					ret=E_BAD_ADDRESS;
213 214
 					goto error_fwd_uri;
214 215
 				}
216
+#ifdef USE_COMP
217
+				dst.comp=u->comp;
218
+#endif
215 219
 				ret=forward_request(msg, &dst);
216 220
 				if (ret>=0) ret=1;
217 221
 			}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 316
 		}
316 317
 	}
317 318
 
318
-	buf = build_req_buf_from_sip_req(msg, &len, send_info->send_sock,
319
-											send_info->proto);
319
+	buf = build_req_buf_from_sip_req(msg, &len, send_info);
320 320
 	if (!buf){
321 321
 		LOG(L_ERR, "ERROR: forward_request: building failed\n");
322 322
 		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 48
 #include "dprint.h"
47 49
 
48 50
 enum sip_protos { PROTO_NONE, PROTO_UDP, PROTO_TCP, PROTO_TLS, PROTO_SCTP };
49
-
51
+#ifdef USE_COMP
52
+enum comp_methods { COMP_NONE, COMP_SIGCOMP, COMP_SERGZ };
53
+#endif
50 54
 
51 55
 struct ip_addr{
52 56
 	unsigned int af; /* address family: AF_INET6 or AF_INET */
... ...
@@ -100,21 +104,27 @@ struct receive_info{
100 104
 	struct ip_addr dst_ip;
101 105
 	unsigned short src_port; /* host byte order */
102 106
 	unsigned short dst_port; /* host byte order */
103
-	int proto;
104 107
 	int proto_reserved1; /* tcp stores the connection id here */
105 108
 	int proto_reserved2;
106 109
 	union sockaddr_union src_su; /* useful for replies*/
107 110
 	struct socket_info* bind_address; /* sock_info structure on which 
108 111
 									  the msg was received*/
112
+	short proto;
113
+#ifdef USE_COMP
114
+	short comp; /* compression */
115
+#endif
109 116
 	/* no need for dst_su yet */
110 117
 };
111 118
 
112 119
 
113 120
 struct dest_info{
114
-	int proto;
115
-	int id; /* tcp stores the connection id here */ 
116
-	union sockaddr_union to;
117 121
 	struct socket_info* send_sock;
122
+	union sockaddr_union to;
123
+	int id; /* tcp stores the connection id here */ 
124
+	short proto;
125
+#ifdef USE_COMP
126
+	short comp;
127
+#endif
118 128
 };
119 129
 
120 130
 
... ...
@@ -553,10 +563,23 @@ static inline struct hostent* ip_addr2he(str* name, struct ip_addr* ip)
553 563
 /* init a dest_info structure */
554 564
 #define init_dest_info(dst) \
555 565
 	do{ \
556
-		(dst)->proto=0; \
557
-		(dst)->id=0; \
558
-		(dst)->send_sock=0; \
559
-		memset(&(dst)->to, 0, sizeof(union sockaddr_union)); \
566
+		memset((dst), 0, sizeof(struct dest_info)); \
560 567
 	} while(0) 
561 568
 
569
+
570
+
571
+/* init a dest_info structure from a recv_info structure */
572
+inline static void init_dst_from_rcv(struct dest_info* dst,
573
+									struct receive_info* rcv)
574
+{
575
+		dst->send_sock=rcv->bind_address;
576
+		dst->to=rcv->src_su;
577
+		dst->id=rcv->proto_reserved1;
578
+		dst->proto=rcv->proto;
579
+#ifdef USE_COMP
580
+		dst->comp=rcv->comp;
581
+#endif
582
+}
583
+
584
+
562 585
 #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 155
 					case PARAM_ALIAS:
155 156
 							new_via->alias = new_vp;
156 157
 							break;
158
+							
159
+#ifdef USE_COMP
160
+					case PARAM_COMP:
161
+							new_via->comp = new_vp;
162
+							break;
163
+#endif
157 164
 				}
158 165
 
159 166
 				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 99
 }
99 100
 
100 101
 
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 )
102
+static char *print_uac_request( struct cell *t, struct sip_msg *i_req,
103
+	int branch, str *uri, unsigned int *len, struct dest_info* dst)
104 104
 {
105 105
 	char *buf, *shbuf;
106 106
 	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 277
 
277 278
 	/* now message printing starts ... */
278 279
 	shbuf=print_uac_request( t, request, branch, uri, 
279
-		&len, t->uac[branch].request.dst.send_sock, 
280
-			t->uac[branch].request.dst.proto );
280
+							&len, &t->uac[branch].request.dst);
281 281
 	if (!shbuf) {
282 282
 		ret=ser_error=E_OUT_OF_MEM;
283 283
 		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 987
 
989 988
 	/* rb. timers are init. init_t()/new_cell() */
990 989
 	via=msg->via1;
990
+	/* rb->dst is already init (0) by new_t()/build_cell() */
991 991
 	if (!reply_to_via) {
992 992
 		update_sock_struct_from_ip( &rb->dst.to, msg );
993 993
 		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 102
 	branch_str.s=branch_buf;
101 103
 	branch_str.len=branch_len;
102 104
 	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 );
105
+	via=via_builder(&via_len, &Trans->uac[branch].request.dst,
106
+		&branch_str, 0, &hp );
105 107
 	if (!via)
106 108
 	{
107 109
 		LOG(L_ERR, "ERROR: build_local: "
... ...
@@ -355,7 +357,7 @@ static inline int get_contact_uri(struct sip_msg* msg, str* uri)
355 357
 
356 358
      /*
357 359
       * 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
360
+      * and parsed and next_hop parameter will contain the uri to which the
359 361
       * request should be send. The function is used by tm when it generates
360 362
       * local ACK to 200 OK (on behalf of applications using uac
361 363
       */
... ...
@@ -370,8 +372,7 @@ char *build_dlg_ack(struct sip_msg* rpl, struct cell *Trans, unsigned int branch
370 372
 	struct hostport hp;
371 373
 	struct rte* list;
372 374
 	str contact, ruri, *cont;
373
-	struct socket_info* send_sock;
374
-	union sockaddr_union to_su;
375
+	struct dest_info dst;
375 376
 	
376 377
 	if (get_contact_uri(rpl, &contact) < 0) {
377 378
 		return 0;
... ...
@@ -399,9 +400,8 @@ char *build_dlg_ack(struct sip_msg* rpl, struct cell *Trans, unsigned int branch
399 400
 	
400 401
 	
401 402
 	     /* 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");
403
+	if ((uri2dst(&dst, rpl, next_hop, PROTO_NONE)==0) || (dst.send_sock==0)){
404
+			LOG(L_ERR, "build_dlg_ack: no socket found\n");
405 405
 		goto error;
406 406
 	}
407 407
 	
... ...
@@ -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 552
 #endif
552 553
 
553 554
 	set_hostport(&hp, 0);
554
-	via = via_builder(&via_len, sock, &branch_str, 0, sock->proto, &hp);
555
+	via = via_builder(&via_len, dst, &branch_str, 0, &hp);
555 556
 	if (!via) {
556 557
 		LOG(L_ERR, "assemble_via: via building failed\n");
557 558
 		return -2;
... ...
@@ -674,7 +675,7 @@ static inline char* print_callid(char* w, dlg_t* dialog, struct cell* t)
674 675
  * Create a request
675 676
  */
676 677
 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)
678
+			struct cell *t, int* len, struct dest_info* dst)
678 679
 {
679 680
 	char* buf, *w;
680 681
 	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 694
 	}
694 695
 	*len = method->len + 1 + dialog->hooks.request_uri->len + 1 + SIP_VERSION_LEN + CRLF_LEN;
695 696
 
696
-	if (assemble_via(&via, t, send_sock, branch) < 0) {
697
+	if (assemble_via(&via, t, dst, branch) < 0) {
697 698
 		LOG(L_ERR, "build_uac_req(): Error while assembling Via\n");
698 699
 		return 0;
699 700
 	}
... ...
@@ -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 188
 	DBG("DEBUG:tm:t_uac: next_hop=<%.*s>\n",dialog->hooks.next_hop->len,
190 189
 			dialog->hooks.next_hop->s);
191 190
 	/* 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) {
191
+	if ((uri2dst(&dst, 0, dialog->hooks.next_hop, PROTO_NONE)==0) ||
192
+			(dst.send_sock==0)){
193
+		ser_error = E_NO_SOCKET;
194 194
 		ret=ser_error;
195 195
 		LOG(L_ERR, "t_uac: no socket found\n");
196 196
 		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 241
 	UNLOCK_HASH(hi);
246 242
 
247 243
 	buf = build_uac_req(method, headers, body, dialog, 0, new_cell,
248
-		&buf_len, send_sock);
244
+		&buf_len, &dst);
249 245
 	if (!buf) {
250 246
 		LOG(L_ERR, "t_uac: Error while building message\n");
251 247
 		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 169
 	
166 170
 	init_dest_info(dst);
167 171
 	dst->proto= get_proto(proto, uri_proto);
172
+#ifdef USE_COMP
173
+	dst->comp=parsed_uri.comp;
174
+#endif
168 175
 	sip_hostport2su(&dst->to, &parsed_uri.host, parsed_uri.port_no,
169 176
 						dst->proto);
177
+	if (msg){
178
+		dst->send_sock = get_send_socket(msg, &dst->to, dst->proto);
179
+		if (dst->send_sock==0) {
180
+			LOG(L_ERR, "ERROR: uri2sock: no corresponding socket for af %d\n", 
181
+					dst->to.s.sa_family);
182
+			/* ser_error = E_NO_SOCKET;*/
183
+			/* try to continue */
184
+		}
185
+	}
170 186
 	return dst;
171 187
 }
172 188
 
173 189
 
174 190
 
175 191
 /*
176
- * Convert a URI into socket_info
192
+ * Convert a URI into the corresponding sockaddr_union (address to send to) and
193
+ *  send socket_info (socket/address from which to send)
194
+ *  to_su is filled with the destination and the socket_info that will be 
195
+ *  used for sending is returned.
196
+ *  On error return 0.
197
+ *
198
+ *  NOTE: this function is deprecated, you should use uri2dst instead
177 199
  */
178 200
 static inline struct socket_info *uri2sock(struct sip_msg* msg, str *uri,
179 201
 									union sockaddr_union *to_su, int proto)
180 202
 {
181
-	struct socket_info* send_sock;
182 203
 	struct dest_info dst;
183 204
 
184
-	if (uri2dst(&dst, uri, proto)==0){
205
+	if (uri2dst(&dst, msg, uri, proto)==0){
185 206
 		LOG(L_ERR, "ERROR: uri2sock: Can't create a dst proxy\n");
186 207
 		ser_error=E_BAD_ADDRESS;
187 208
 		return 0;
188 209
 	}
189 210
 	*to_su=dst.to; /* copy su */
190 211
 	
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) {
212
+	/* we use dst->send_socket since uri2dst just set it correctly*/
213
+	if (dst.send_sock==0) {
194 214
 		LOG(L_ERR, "ERROR: uri2sock: no corresponding socket for af %d\n", 
195 215
 		    to_su->s.sa_family);
196 216
 		ser_error = E_NO_SOCKET;
197 217
 	}
198
-	return send_sock;
218
+	return dst.send_sock;
199 219
 }
200 220
 
201 221
 
... ...
@@ -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 439
  * returns 1 if cond is true, 0 if false */
437 440
 static inline int lump_check_opt(	enum lump_conditions cond,
438 441
 									struct sip_msg* msg,
439
-									struct socket_info* snd_s
442
+									struct dest_info* snd_i
440 443
 									)
441 444
 {
442 445
 	struct ip_addr* ip;
... ...
@@ -444,7 +447,7 @@ static inline int lump_check_opt(	enum lump_conditions cond,
444 447
 	int proto;
445 448
 
446 449
 #define get_ip_port_proto \
447
-			if (snd_s==0){ \
450
+			if ((snd_i==0) || (snd_i->send_sock==0)){ \
448 451
 				LOG(L_CRIT, "ERROR: lump_check_opt: null send socket\n"); \
449 452
 				return 1; /* we presume they are different :-) */ \
450 453
 			} \
... ...
@@ -466,30 +469,34 @@ static inline int lump_check_opt(	enum lump_conditions cond,
466 469
 		case COND_IF_DIFF_REALMS:
467 470
 			get_ip_port_proto;
468 471
 			/* faster tests first */
469
-			if ((port==snd_s->port_no)&&(proto==snd_s->proto)&&
470
-				(ip_addr_cmp(ip, &snd_s->address)))
472
+			if ((port==snd_i->send_sock->port_no) && 
473
+					(proto==snd_i->send_sock->proto) &&
474
+#ifdef USE_COMP
475
+					(msg->rcv.comp==snd_i->comp) &&
476
+#endif
477
+					(ip_addr_cmp(ip, &snd_i->send_sock->address)))
471 478
 				return 0;
472 479
 			else return 1;
473 480
 		case COND_IF_DIFF_AF:
474 481
 			get_ip_port_proto;
475
-			if (ip->af!=snd_s->address.af) return 1;
482
+			if (ip->af!=snd_i->send_sock->address.af) return 1;
476 483
 			else return 0;
477 484
 		case COND_IF_DIFF_PROTO:
478 485
 			get_ip_port_proto;
479
-			if (proto!=snd_s->proto) return 1;
486
+			if (proto!=snd_i->send_sock->proto) return 1;
480 487
 			else return 0;
481 488
 		case COND_IF_DIFF_PORT:
482 489
 			get_ip_port_proto;
483
-			if (port!=snd_s->port_no) return 1;
490
+			if (port!=snd_i->send_sock->port_no) return 1;
484 491
 			else return 0;
485 492
 		case COND_IF_DIFF_IP:
486 493
 			get_ip_port_proto;
487
-			if (ip_addr_cmp(ip, &snd_s->address)) return 0;
494
+			if (ip_addr_cmp(ip, &snd_i->send_sock->address)) return 0;
488 495
 			else return 1;
489 496
 		case COND_IF_RAND:
490 497
 			return (rand()>=RAND_MAX/2);
491 498
 		default:
492
-			LOG(L_CRIT, "BUG: lump_check_opt: unknown lump condition %d\n",
499
+			LOG(L_CRIT, "BUG: lump:w_check_opt: unknown lump condition %d\n",
493 500
 					cond);
494 501
 	}
495 502
 	return 0; /* false */
... ...
@@ -499,7 +506,8 @@ static inline int lump_check_opt(	enum lump_conditions cond,
499 506
 
500 507
 /* computes the "unpacked" len of a lump list,
501 508
    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)
509
+static inline int lumps_len(struct sip_msg* msg, struct lump* lumps, 
510
+								struct dest_info* send_info)
503 511
 {
504 512
 	int s_offset;
505 513
 	int new_len;
... ...
@@ -507,7 +515,46 @@ static inline int lumps_len(struct sip_msg* msg, struct lump* lumps, struct sock
507 515
 	struct lump* r;
508 516
 	str* send_address_str;
509 517
 	str* send_port_str;
518
+	struct socket_info* send_sock;
519
+	
520
+
521
+#ifdef USE_COMP
522
+	#define RCVCOMP_LUMP_LEN \
523
+						/* add;comp=xxx */ \
524
+					switch(msg->rcv.comp){ \
525
+						case COMP_NONE: \
526
+								break; \
527
+						case COMP_SIGCOMP: \
528
+								new_len+=COMP_PARAM_LEN+SIGCOMP_NAME_LEN; \
529
+								break; \
530
+						case COMP_SERGZ: \
531
+								new_len+=COMP_PARAM_LEN+SERGZ_NAME_LEN ; \
532
+								break; \
533
+						default: \
534
+						LOG(L_CRIT, "BUG: lumps_len: unknown comp %d\n", \
535
+								msg->rcv.comp); \
536
+					}
510 537
 
538
+	#define SENDCOMP_LUMP_LEN \
539
+					/* add;comp=xxx */ \
540
+					switch(send_info->comp){ \
541
+						case COMP_NONE: \
542
+								break; \
543
+						case COMP_SIGCOMP: \
544
+								new_len+=COMP_PARAM_LEN+SIGCOMP_NAME_LEN; \
545
+								break; \
546
+						case COMP_SERGZ: \
547
+								new_len+=COMP_PARAM_LEN+SERGZ_NAME_LEN ; \
548
+								break; \
549
+						default: \
550
+						LOG(L_CRIT, "BUG: lumps_len: unknown comp %d\n", \
551
+								send_info->comp); \
552
+					}
553
+#else
554
+	#define RCVCOMP_LUMP_LEN
555
+	#define SENDCOMP_LUMP_LEN
556
+#endif /*USE_COMP */
557
+	
511 558
 #define SUBST_LUMP_LEN(subst_l) \
512 559
 		switch((subst_l)->u.subst){ \
513 560
 			case SUBST_RCV_IP: \
... ...
@@ -574,6 +621,7 @@ static inline int lumps_len(struct sip_msg* msg, struct lump* lumps, struct sock
574 621
 						LOG(L_CRIT, "BUG: lumps_len: unknown proto %d\n", \
575 622
 								msg->rcv.bind_address->proto); \
576 623
 					}\
624
+					RCVCOMP_LUMP_LEN \
577 625
 				}else{ \
578 626
 					/* FIXME */ \
579 627
 					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 694
 						LOG(L_CRIT, "BUG: lumps_len: unknown proto %d\n", \
647 695
 								send_sock->proto); \
648 696
 					}\
697
+					SENDCOMP_LUMP_LEN \
649 698
 				}else{ \
650 699
 					/* FIXME */ \
651 700
 					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 707
 				LOG(L_CRIT, "BUG: unknown subst type %d\n", \
659 708
 						(subst_l)->u.subst); \
660 709
 		}
661
-
710
+	
711
+	if (send_info){
712
+		send_sock=send_info->send_sock;
713
+	}else{
714
+		send_sock=0;
715
+	};
662 716
 	s_offset=0;
663 717
 	new_len=0;
664 718
 	/* 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 728
 
675 729
 	for(t=lumps;t;t=t->next){
676 730
 		/* 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))
731
+		if ((t->op==LUMP_ADD_OPT)&& !lump_check_opt(t->u.cond, msg, send_info))
678 732
 			continue;
679 733
 		for(r=t->before;r;r=r->before){
680 734
 			switch(r->op){
... ...
@@ -687,7 +741,7 @@ static inline int lumps_len(struct sip_msg* msg, struct lump* lumps, struct sock
687 741
 				case LUMP_ADD_OPT:
688 742
 					/* skip if this is an OPT lump and the condition is
689 743
 					 * not satisfied */
690
-					if (!lump_check_opt(r->u.cond, msg, send_sock))
744
+					if (!lump_check_opt(r->u.cond, msg, send_info))
691 745
 						goto skip_before;
692 746
 					break;
693 747
 				default:
... ...
@@ -743,7 +797,7 @@ skip_before:
743 797
 				case LUMP_ADD_OPT:
744 798
 					/* skip if this is an OPT lump and the condition is
745 799
 					 * not satisfied */
746
-					if (!lump_check_opt(r->u.cond, msg, send_sock))
800
+					if (!lump_check_opt(r->u.cond, msg, send_info))
747 801
 						goto skip_after;
748 802
 					break;
749 803
 				default:
... ...
@@ -756,6 +810,8 @@ skip_after:
756 810
 		; /* to make gcc 3.* happy */
757 811
 	}
758 812
 	return new_len;
813
+#undef RCVCOMP_LUMP_LEN
814
+#undef SENDCOMP_LUMP_LEN
759 815
 }
760 816
 
761 817
 
... ...
@@ -768,7 +824,7 @@ static inline void process_lumps(	struct sip_msg* msg,
768 824
 									char* new_buf,
769 825
 									unsigned int* new_buf_offs,
770 826
 									unsigned int* orig_offs,
771
-									struct socket_info* send_sock)
827
+									struct dest_info* send_info)
772 828
 {
773 829
 	struct lump *t;
774 830
 	struct lump *r;
... ...
@@ -778,6 +834,58 @@ static inline void process_lumps(	struct sip_msg* msg,
778 834
 	int s_offset;
779 835
 	str* send_address_str;
780 836
 	str* send_port_str;
837
+	struct socket_info* send_sock;
838
+
839
+#ifdef USE_COMP
840
+	#define RCVCOMP_PARAM_ADD \
841
+				/* add ;comp=xxxx */ \
842
+				switch(msg->rcv.comp){ \
843
+					case COMP_NONE: \
844
+						break; \
845
+					case COMP_SIGCOMP: \
846
+						memcpy(new_buf+offset, COMP_PARAM, COMP_PARAM_LEN);\
847
+						offset+=COMP_PARAM_LEN; \
848
+						memcpy(new_buf+offset, SIGCOMP_NAME, \
849
+								SIGCOMP_NAME_LEN); \
850
+						offset+=SIGCOMP_NAME_LEN; \
851
+						break; \
852
+					case COMP_SERGZ: \
853
+						memcpy(new_buf+offset, COMP_PARAM, COMP_PARAM_LEN);\
854
+						offset+=COMP_PARAM_LEN; \
855
+						memcpy(new_buf+offset, SERGZ_NAME, SERGZ_NAME_LEN); \
856
+						offset+=SERGZ_NAME_LEN; \
857
+						break;\
858
+					default:\
859
+						LOG(L_CRIT, "BUG: process_lumps: unknown comp %d\n", \
860
+								msg->rcv.comp); \
861
+				}
862
+	
863
+	#define SENDCOMP_PARAM_ADD \
864
+				/* add ;comp=xxxx */ \
865
+				switch(send_info->comp){ \
866
+					case COMP_NONE: \
867
+						break; \
868
+					case COMP_SIGCOMP: \
869
+						memcpy(new_buf+offset, COMP_PARAM, COMP_PARAM_LEN);\
870
+						offset+=COMP_PARAM_LEN; \
871
+						memcpy(new_buf+offset, SIGCOMP_NAME, \
872
+								SIGCOMP_NAME_LEN); \
873
+						offset+=SIGCOMP_NAME_LEN; \
874
+						break; \
875
+					case COMP_SERGZ: \
876
+						memcpy(new_buf+offset, COMP_PARAM, COMP_PARAM_LEN);\
877
+						offset+=COMP_PARAM_LEN; \
878
+						memcpy(new_buf+offset, SERGZ_NAME, SERGZ_NAME_LEN); \
879
+						offset+=SERGZ_NAME_LEN; \
880
+						break;\
881
+					default:\
882
+						LOG(L_CRIT, "BUG: process_lumps: unknown comp %d\n", \
883
+								msg->rcv.comp); \
884
+				} 
885
+#else
886
+	#define RCVCOMP_PARAM_ADD
887
+	#define SENDCOMP_PARAM_ADD
888
+#endif /* USE_COMP */
781 889
 
782 890
 #define SUBST_LUMP(subst_l) \
783 891
 	switch((subst_l)->u.subst){ \
... ...
@@ -856,6 +964,7 @@ static inline void process_lumps(	struct sip_msg* msg,
856 964
 						LOG(L_CRIT, "BUG: process_lumps: unknown proto %d\n", \
857 965
 								msg->rcv.bind_address->proto); \
858 966
 				} \
967
+				RCVCOMP_PARAM_ADD \
859 968
 			}else{  \
860 969
 				/*FIXME*/ \
861 970
 				LOG(L_CRIT, "FIXME: process_lumps: null bind_address\n"); \
... ...
@@ -942,6 +1051,7 @@ static inline void process_lumps(	struct sip_msg* msg,
942 1051
 						LOG(L_CRIT, "BUG: process_lumps: unknown proto %d\n", \
943 1052
 								send_sock->proto); \
944 1053
 				} \
1054
+				SENDCOMP_PARAM_ADD \
945 1055
 			}else{  \
946 1056
 				/*FIXME*/ \
947 1057
 				LOG(L_CRIT, "FIXME: process_lumps: null bind_address\n"); \
... ...
@@ -1008,11 +1118,15 @@ static inline void process_lumps(	struct sip_msg* msg,
1008 1118
 			}; \
1009 1119
 			break; \
1010 1120
 		default: \
1011
-					LOG(L_CRIT, "BUG: process_lumps: unknown subst type %d\n", \
1121
+				LOG(L_CRIT, "BUG: process_lumps: unknown subst type %d\n", \
1012 1122
 							(subst_l)->u.subst); \
1013
-	} \
1014
- \
1123
+	}
1015 1124
 
1125
+	if (send_info){
1126
+		send_sock=send_info->send_sock;
1127
+	}else{
1128
+		send_sock=0;
1129
+	}
1016 1130
 	/* init send_address_str & send_port_str */
1017 1131
 	if (msg->set_global_address.len)
1018 1132
 		send_address_str=&(msg->set_global_address);
... ...
@@ -1036,7 +1150,7 @@ static inline void process_lumps(	struct sip_msg* msg,
1036 1150
 				/* skip if this is an OPT lump and the condition is
1037 1151
 				 * not satisfied */
1038 1152
 				if ((t->op==LUMP_ADD_OPT) &&
1039
-						(!lump_check_opt(t->u.cond, msg, send_sock)))
1153
+						(!lump_check_opt(t->u.cond, msg, send_info)))
1040 1154
 					continue;
1041 1155
 				/* just add it here! */
1042 1156
 				/* process before  */
... ...
@@ -1053,7 +1167,7 @@ static inline void process_lumps(	struct sip_msg* msg,
1053 1167
 						case LUMP_ADD_OPT:
1054 1168
 							/* skip if this is an OPT lump and the condition is
1055 1169
 					 		* not satisfied */
1056
-							if (!lump_check_opt(r->u.cond, msg, send_sock))
1170
+							if (!lump_check_opt(r->u.cond, msg, send_info))
1057 1171
 								goto skip_before;
1058 1172
 							break;
1059 1173
 						default:
... ...
@@ -1094,7 +1208,7 @@ skip_before:
1094 1208
 						case LUMP_ADD_OPT:
1095 1209
 							/* skip if this is an OPT lump and the condition is
1096 1210
 					 		* not satisfied */
1097
-							if (!lump_check_opt(r->u.cond, msg, send_sock))
1211
+							if (!lump_check_opt(r->u.cond, msg, send_info))
1098 1212
 								goto skip_after;
1099 1213
 							break;
1100 1214
 						default:
... ...
@@ -1135,7 +1249,7 @@ skip_after:
1135 1249
 						case LUMP_ADD_OPT:
1136 1250
 							/* skip if this is an OPT lump and the condition is
1137 1251
 					 		* not satisfied */
1138
-							if (!lump_check_opt(r->u.cond, msg, send_sock))
1252
+							if (!lump_check_opt(r->u.cond, msg, send_info))
1139 1253
 								goto skip_nop_before;
1140 1254
 							break;
1141 1255
 						default:
... ...
@@ -1164,7 +1278,7 @@ skip_nop_before:
1164 1278
 						case LUMP_ADD_OPT:
1165 1279
 							/* skip if this is an OPT lump and the condition is
1166 1280
 					 		* not satisfied */
1167
-							if (!lump_check_opt(r->u.cond, msg, send_sock))
1281
+							if (!lump_check_opt(r->u.cond, msg, send_info))
1168 1282
 								goto skip_nop_after;
1169 1283
 							break;
1170 1284
 						default:
... ...
@@ -1182,6 +1296,8 @@ skip_nop_after:
1182 1296
 	}
1183 1297
 	*new_buf_offs=offset;
1184 1298
 	*orig_offs=s_offset;
1299
+#undef RCVCOMP_PARAM_ADD 
1300
+#undef SENDCOMP_PARAM_ADD
1185 1301
 }
1186 1302
 
1187 1303
 
... ...
@@ -1285,7 +1401,7 @@ error:
1285 1401
 
1286 1402
 char * build_req_buf_from_sip_req( struct sip_msg* msg,
1287 1403
 								unsigned int *returned_len,
1288
-								struct socket_info* send_sock, int proto)
1404
+								struct dest_info* send_info)
1289 1405
 {
1290 1406
 	unsigned int len, new_len, received_len, rport_len, uri_len, via_len, body_delta;
1291 1407
 	char* line_buf;
... ...
@@ -1343,8 +1459,8 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
1343 1459
 	     /* Calculate message body difference and adjust
1344 1460
 	      * Content-Length
1345 1461
 	      */
1346
-	body_delta = lumps_len(msg, msg->body_lumps, send_sock);
1347
-	if (adjust_clen(msg, body_delta, proto) < 0) {
1462
+	body_delta = lumps_len(msg, msg->body_lumps, send_info);
1463
+	if (adjust_clen(msg, body_delta, send_info->proto) < 0) {
1348 1464
 		LOG(L_ERR, "ERROR: build_req_buf_from_sip_req: Error while adjusting"
1349 1465
 				" Content-Length\n");
1350 1466
 		goto error00;
... ...
@@ -1353,8 +1469,8 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
1353 1469
 	branch.s=msg->add_to_branch_s;
1354 1470
 	branch.len=msg->add_to_branch_len;
1355 1471
 	set_hostport(&hp, msg);
1356
-	line_buf = via_builder( &via_len, send_sock, &branch,
1357
-							extra_params.len?&extra_params:0, proto, &hp);
1472
+	line_buf = via_builder( &via_len, send_info, &branch,
1473
+							extra_params.len?&extra_params:0, &hp);
1358 1474
 	if (!line_buf){
1359 1475
 		LOG(L_ERR,"ERROR: build_req_buf_from_sip_req: no via received!\n");
1360 1476
 		goto error00;
... ...
@@ -1441,7 +1557,7 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
1441 1557
 	}
1442 1558
 
1443 1559
 	/* compute new msg len and fix overlapping zones*/
1444
-	new_len=len+body_delta+lumps_len(msg, msg->add_rm, send_sock);
1560
+	new_len=len+body_delta+lumps_len(msg, msg->add_rm, send_info);
1445 1561
 #ifdef XL_DEBUG
1446 1562
 	LOG(L_ERR, "DEBUG: new_len(%d)=len(%d)+lumps_len\n", new_len, len);
1447 1563
 #endif
... ...
@@ -1471,8 +1587,8 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
1471 1587
 	}
1472 1588
 	new_buf[new_len]=0;
1473 1589
 	/* 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);
1590
+	process_lumps(msg, msg->add_rm, new_buf, &offset, &s_offset, send_info);
1591
+	process_lumps(msg, msg->body_lumps, new_buf, &offset, &s_offset,send_info);
1476 1592
 	/* copy the rest of the message */
1477 1593
 	memcpy(new_buf+offset, buf+s_offset, len-s_offset);
1478 1594
 	new_buf[new_len]=0;
... ...
@@ -1931,16 +2047,24 @@ int branch_builder( unsigned int hash_index,
1931 2047
 }
1932 2048
 
1933 2049
 
2050
+
2051
+/* uses only the send_info->send_socket, send_info->proto and 
2052
+ * send_info->comp (so that a send_info used for sending can be passed
2053
+ * to this function w/o changes and the correct via will be built) */
1934 2054
 char* via_builder( unsigned int *len,
1935
-	struct socket_info* send_sock,
1936
-	str* branch, str* extra_params, int proto, struct hostport* hp)
2055
+	struct dest_info* send_info /* where to send the reply */,
2056
+	str* branch, str* extra_params, struct hostport* hp)
1937 2057
 {
1938 2058
 	unsigned int  via_len, extra_len;
1939 2059
 	char               *line_buf;
1940 2060
 	int max_len;
1941 2061
 	str* address_str; /* address displayed in via */
1942 2062
 	str* port_str; /* port no displayed in via */
2063
+	struct socket_info* send_sock;
2064
+	int comp_len, comp_name_len;
2065
+	char* comp_name;
1943 2066
 
2067
+	send_sock=send_info->send_sock;
1944 2068
 	/* use pre-set address in via or the outbound socket one */
1945 2069
 	if ( hp && hp->host->len)
1946 2070
 		address_str=hp->host;
... ...
@@ -1950,12 +2074,36 @@ char* via_builder( unsigned int *len,
1950 2074
 		port_str=hp->port;
1951 2075
 	else
1952 2076
 		port_str=&(send_sock->port_no_str);
1953
-
2077
+	
2078
+	comp_len=comp_name_len=0;
2079
+	comp_name=0;
2080
+#ifdef USE_COMP
2081
+	switch(send_info->comp){
2082
+		case COMP_NONE:
2083
+			break;
2084
+		case COMP_SIGCOMP:
2085
+			comp_len=COMP_PARAM_LEN;
2086
+			comp_name_len=SIGCOMP_NAME_LEN;
2087
+			comp_name=SIGCOMP_NAME;
2088
+			break;
2089
+		case COMP_SERGZ:
2090
+			comp_len=COMP_PARAM_LEN;
2091
+			comp_name_len=SERGZ_NAME_LEN;
2092
+			comp_name=SERGZ_NAME;
2093
+			break;
2094
+		default:
2095
+			LOG(L_CRIT, "BUG: via_builder: unknown comp %d\n",
2096
+					send_info->comp);
2097
+			/* continue, we'll just ignore comp */
2098
+	}
2099
+#endif /* USE_COMP */
2100
+			
1954 2101
 	max_len=MY_VIA_LEN+address_str->len /* space in MY_VIA */
1955 2102
 		+2 /* just in case it is a v6 address ... [ ] */
1956 2103
 		+1 /*':'*/+port_str->len
1957 2104
 		+(branch?(MY_BRANCH_LEN+branch->len):0)
1958 2105
 		+(extra_params?extra_params->len:0)
2106
+		+comp_len+comp_name_len
1959 2107
 		+CRLF_LEN+1;
1960 2108
 	line_buf=pkg_malloc( max_len );
1961 2109
 	if (line_buf==0){
... ...
@@ -1969,14 +2117,14 @@ char* via_builder( unsigned int *len,
1969 2117
 	via_len=MY_VIA_LEN+address_str->len; /*space included in MY_VIA*/
1970 2118
 
1971 2119
 	memcpy(line_buf, MY_VIA, MY_VIA_LEN);
1972
-	if (proto==PROTO_UDP){
2120
+	if (send_info->proto==PROTO_UDP){
1973 2121
 		/* do nothing */
1974
-	}else if (proto==PROTO_TCP){
2122
+	}else if (send_info->proto==PROTO_TCP){
1975 2123
 		memcpy(line_buf+MY_VIA_LEN-4, "TCP ", 4);
1976
-	}else if (proto==PROTO_TLS){
2124
+	}else if (send_info->proto==PROTO_TLS){
1977 2125
 		memcpy(line_buf+MY_VIA_LEN-4, "TLS ", 4);
1978 2126
 	}else{
1979
-		LOG(L_CRIT, "BUG: via_builder: unknown proto %d\n", proto);
2127
+		LOG(L_CRIT, "BUG: via_builder: unknown proto %d\n", send_info->proto);
1980 2128
 		return 0;
1981 2129
 	}
1982 2130
 #	ifdef USE_IPV6
... ...
@@ -2009,6 +2157,15 @@ char* via_builder( unsigned int *len,
2009 2157
 		memcpy(line_buf+via_len, extra_params->s, extra_params->len);
2010 2158
 		via_len+=extra_params->len;
2011 2159
 	}
2160
+#ifdef USE_COMP
2161
+	/* comp */
2162
+	if (comp_len){
2163
+		memcpy(line_buf+via_len, COMP_PARAM, COMP_PARAM_LEN);
2164
+		via_len+=COMP_PARAM_LEN;
2165
+		memcpy(line_buf+via_len, comp_name, comp_name_len);
2166
+		via_len+=comp_name_len;
2167
+	}
2168
+#endif
2012 2169
 
2013 2170
 	memcpy(line_buf+via_len, CRLF, CRLF_LEN);
2014 2171
 	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 102
 				struct bookmark *bmark);
104 103
 */
105 104
 char* via_builder( unsigned int *len,
106
-	struct socket_info* send_sock,
107
-	str *branch, str* extra_params, int proto, struct hostport *hp );
105
+	struct dest_info* send_info,
106
+	str *branch, str* extra_params, struct hostport *hp );
108 107
 
109 108
 
110 109
 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 141
 	unsigned short port_no;
141 142
 	unsigned short proto; /* from transport */
142 143
 	uri_type type; /* uri scheme */
144
+#ifdef USE_COMP
145
+	unsigned short comp;
146
+#endif
143 147
 	/* parameters */
144 148
 	str transport;
145 149
 	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 74
 					PLR_L, PLR_R_FIN, PLR_eq,
74 75
 					/* r2 */
75 76
 					PR2_R, PR2_2_FIN, PR2_eq,
77
+#ifdef USE_COMP
78
+					/* comp */
79
+					PCOMP_C, PCOMP_O, PCOMP_M, PCOMP_P, PCOMP_eq,
80
+					
81
+					/* comp values */
82
+					/* sigcomp */
83
+					VCOMP_S, VCOMP_SIGC_I, VCOMP_SIGC_G,
84
+					VCOMP_SIGC_C, VCOMP_SIGC_O,  VCOMP_SIGC_M,
85
+					VCOMP_SIGC_P_FIN,
86
+					/* sergz */
87
+							VCOMP_SGZ_E, VCOMP_SGZ_R, VCOMP_SGZ_G,
88
+							VCOMP_SGZ_Z_FIN,
89
+#endif
76 90
 					
77 91
 					/* transport values */
78 92
 					/* udp */
... ...
@@ -100,6 +114,10 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
100 114
 	int error_headers;
101 115
 	unsigned int scheme;
102 116
 	uri_type backup;
117
+#ifdef USE_COMP
118
+	str comp_str; /* not returned for now */
119
+	str comp_val; /* not returned for now */
120
+#endif
103 121
 	
104 122
 #define SIP_SCH		0x3a706973
105 123
 #define SIPS_SCH	0x73706973
... ...
@@ -313,7 +331,30 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
313 331
 				} \
314 332
 				break
315 333
 			
316
-	
334
+
335
+#ifdef USE_COMP
336
+#define comp_fin(c_state, comp_no) \
337
+			case c_state: \
338
+				switch(*p){ \
339
+					case '@': \
340
+						still_at_user; \
341
+						break; \
342
+					semicolon_case; \
343
+						/* param_set(b, v); */ \
344
+						uri->comp=(comp_no); \
345
+						break; \
346
+					question_case; \
347
+						/* param_set(b, v) */; \
348
+						uri->comp=(comp_no); \
349
+						break; \
350
+					colon_case;  \
351
+					default: \
352
+						state=URI_VAL_P; \
353
+						break; \
354
+				} \
355
+				break
356
+			
357
+#endif
317 358
 
318 359
 	/* init */
319 360
 	end=buf+len;
... ...
@@ -579,6 +620,13 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
579 620
 						b=p;
580 621
 						state=PR2_R;
581 622
 						break;
623
+#ifdef USE_COMP
624
+					case 'c':
625
+					case 'C':
626
+						b=p;
627
+						state=PCOMP_C;
628
+						break;
629
+#endif
582 630
 					default:
583 631
 						state=URI_PARAM_P;
584 632
 				}
... ...
@@ -784,6 +832,44 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
784 832
 						state=URI_VAL_P;
785 833
 				}
786 834
 				break;
835
+#ifdef USE_COMP
836
+			param_switch(PCOMP_C,  'o', 'O' , PCOMP_O);
837
+			param_switch(PCOMP_O,  'm', 'M' , PCOMP_M);
838
+			param_switch(PCOMP_M,  'p', 'P' , PCOMP_P);
839
+			param_switch1(PCOMP_P,  '=', PCOMP_eq);
840
+			/* value */
841
+			case PCOMP_eq:
842
+				param=&comp_str;
843
+				param_val=&comp_val;
844
+				switch (*p){
845
+					param_common_cases;
846
+					case 's':
847
+					case 'S':
848
+						v=p;
849
+						state=VCOMP_S;
850
+						break;
851
+					default:
852
+						v=p;
853
+						state=URI_VAL_P;
854
+				}
855
+				break;
856
+			/* sigcomp*/
857
+			value_switch_big(VCOMP_S, 'i', 'I', 'e', 'E',
858
+									VCOMP_SIGC_I, VCOMP_SGZ_E);
859
+			value_switch(VCOMP_SIGC_I, 'g', 'G', VCOMP_SIGC_G);
860
+			value_switch(VCOMP_SIGC_G, 'c', 'C', VCOMP_SIGC_C);
861
+			value_switch(VCOMP_SIGC_C, 'o', 'O', VCOMP_SIGC_O);
862
+			value_switch(VCOMP_SIGC_O, 'm', 'M', VCOMP_SIGC_M);
863
+			value_switch(VCOMP_SIGC_M, 'p', 'P', VCOMP_SIGC_P_FIN);
864
+			comp_fin(VCOMP_SIGC_P_FIN, COMP_SIGCOMP);
865
+			
866
+			/* sergz*/
867
+			value_switch(VCOMP_SGZ_E, 'r', 'R', VCOMP_SGZ_R);
868
+			value_switch(VCOMP_SGZ_R, 'g', 'G', VCOMP_SGZ_G);
869
+			value_switch(VCOMP_SGZ_G, 'z', 'Z', VCOMP_SGZ_Z_FIN);
870
+			comp_fin(VCOMP_SGZ_Z_FIN, COMP_SERGZ);
871
+#endif
872
+				
787 873
 				
788 874
 				
789 875
 			case URI_HEADERS:
... ...
@@ -893,6 +979,13 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
893 979
 		case PM_eq:
894 980
 		case PLR_L: /* lr */
895 981
 		case PR2_R:  /* r2 */
982
+#ifdef USE_COMP
983
+		case PCOMP_C:
984
+		case PCOMP_O:
985
+		case PCOMP_M:
986
+		case PCOMP_P:
987
+		case PCOMP_eq:
988
+#endif
896 989
 			uri->params.s=s;
897 990
 			uri->params.len=p-s;
898 991
 			break;
... ...
@@ -925,6 +1018,22 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
925 1018
 			uri->params.len=p-s;
926 1019
 			param_set(b, v);
927 1020
 			break;
1021
+#ifdef USE_COMP
1022
+		case VCOMP_S:
1023
+		case VCOMP_SIGC_I:
1024
+		case VCOMP_SIGC_G:
1025
+		case VCOMP_SIGC_C:
1026
+		case VCOMP_SIGC_O:
1027
+		case VCOMP_SIGC_M:
1028
+		case VCOMP_SGZ_E:
1029
+		case VCOMP_SGZ_R:
1030
+		case VCOMP_SGZ_G:
1031
+			/* unrecognized comp method, assume none */
1032
+			uri->params.s=s;
1033
+			uri->params.len=p-s;
1034
+			/* uri->comp=COMP_NONE ; */
1035
+			break;
1036
+#endif
928 1037
 		/* fin value states */
929 1038
 		case VU_P_FIN:
930 1039
 			uri->params.s=s;
... ...
@@ -950,6 +1059,20 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
950 1059
 			param_set(b, v);
951 1060
 			uri->proto=PROTO_SCTP;
952 1061
 			break;
1062
+#ifdef USE_COMP
1063
+		case VCOMP_SIGC_P_FIN:
1064
+			uri->params.s=s;
1065
+			uri->params.len=p-s;
1066
+			/* param_set(b, v); */
1067
+			uri->comp=COMP_SIGCOMP;
1068
+			break;
1069
+		case VCOMP_SGZ_Z_FIN:
1070
+			uri->params.s=s;
1071
+			uri->params.len=p-s;
1072
+			/* param_set(b, v); */
1073
+			uri->comp=COMP_SERGZ;
1074
+			break;
1075
+#endif
953 1076
 		/* headers */
954 1077
 		case URI_HEADERS:
955 1078
 			uri->headers.s=s;
... ...
@@ -1027,6 +1150,10 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
1027 1150
 			uri->maddr_val.len, ZSW(uri->maddr_val.s));
1028 1151
 	DBG("   lr=<%.*s>\n", uri->lr.len, ZSW(uri->lr.s)); 
1029 1152
 	DBG("   r2=<%.*s>\n", uri->r2.len, ZSW(uri->r2.s));
1153
+#ifdef USE_COMP
1154
+	DBG("   comp=%d\n", uri->comp);
1155
+#endif
1156
+
1030 1157
 #endif
1031 1158
 	return 0;
1032 1159
 	
... ...
@@ -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 107
 	RECEIVED7,
107 108
 	RPORT1, RPORT2, RPORT3,
108 109
 	ALIAS1, ALIAS2, ALIAS3, ALIAS4,
110
+#ifdef USE_COMP
111
+	COMP1, COMP2, COMP3, 
112
+	/* values */
113
+	L_COMP_VALUE, F_COMP_VALUE,
114
+	V_COMP_S, V_SIGCOMP_I, V_SIGCOMP_G, V_SIGCOMP_C, V_SIGCOMP_O, V_SIGCOMP_M,
115
+	FIN_V_SIGCOMP_P,
116
+	V_SERGZ_E, V_SERGZ_R, V_SERGZ_G, FIN_V_SERGZ_Z,
117
+#endif
109 118
 	     /* fin states (227-...)*/
110 119
 	FIN_HIDDEN = 230, FIN_TTL, FIN_BRANCH,
111 120
 	FIN_MADDR, FIN_RECEIVED, FIN_RPORT, FIN_I, FIN_ALIAS
121
+#ifdef USE_COMP
122
+	, FIN_COMP
123
+#endif
112 124
 	     /*GEN_PARAM,
113 125
 	       PARAM_ERROR*/ /* declared in msg_parser.h*/
114 126
 };
... ...
@@ -124,12 +136,94 @@ enum {
124 136
 static /*inline*/ char* parse_via_param(char* p, char* end,
125 137
 										unsigned char* pstate, 
126 138
 				    					unsigned char* psaved_state,
127
-										struct via_param* param)
139
+										struct via_param* param,
140
+										struct via_body* vb)
128 141
 {
129 142
 	char* tmp;
130 143
 	register unsigned char state;
131 144
 	unsigned char saved_state;
132 145
 
146
+#define value_case(c, C, oldstate, newstate, start_of_value) \
147
+			case (c): \
148
+			case (C): \
149
+				switch(state){ \
150
+					case (oldstate): \
151
+						state=(newstate); \
152
+						if ((start_of_value))  param->value.s=tmp; \
153
+						break; \
154
+					default_value_cases \
155
+				} \
156
+				break
157
+
158
+#define value_case_double(c, C, oldstate1, newstate1, oldstate2, newstate2) \
159
+			case (c): \
160
+			case (C): \
161
+				switch(state){ \
162
+					case (oldstate1): \
163
+						state=(newstate1); \
164
+						break; \
165
+					case (oldstate2): \
166
+						state=(newstate2); \
167
+						break; \
168
+					default_value_cases \
169
+				} \
170
+				break
171
+
172
+#define default_value_cases \
173
+					case F_VALUE: \
174
+						state=P_VALUE; \
175
+						param->value.s=tmp; \
176
+						break; \
177
+					case P_VALUE: \
178
+					case P_STRING: \
179
+						break; \
180
+					case F_LF: \
181
+					case F_CR:  \
182
+					case F_CRLF: \
183
+						state=END_OF_HEADER; \
184
+						goto end_via; \
185
+					default: \
186
+						switch(state){ \
187
+							case F_COMP_VALUE: \
188
+								comp_unexpected_char; \
189
+								state=P_VALUE; \
190
+								param->value.s=tmp; \
191
+								break; \
192
+							comp_states_cases \
193
+							comp_fin_states_cases \
194
+								comp_unexpected_char; \
195
+								state=P_VALUE; \
196
+								break; \
197
+							default: \
198
+								LOG(L_ERR, "ERROR: parse_via_param: invalid " \
199
+									"char <%c> in state %d\n", *tmp, state); \
200
+								goto error; \
201
+						}
202
+
203
+#define comp_states_cases \
204
+					case V_COMP_S: \
205
+					case V_SIGCOMP_I: \
206
+					case V_SIGCOMP_G: \
207
+					case V_SIGCOMP_C: \
208
+					case V_SIGCOMP_O: \
209
+					case V_SIGCOMP_M: \
210
+					case V_SERGZ_E: \
211
+					case V_SERGZ_R: \
212
+					case V_SERGZ_G: 
213
+
214
+#define comp_fin_states_cases \
215
+					case FIN_V_SIGCOMP_P: \
216
+					case FIN_V_SERGZ_Z:
217
+
218
+
219
+/* if unrecognized/bad comp, don't return error, just ignore comp */
220
+#define comp_unexpected_char \
221
+							LOG(L_ERR, "parse_via_param: bad/unrecognized" \
222