- more struct dest_info conversions (via_builder, tm: build_uac_req,
authorAndrei Pelinescu-Onciul <andrei@iptel.org>
Fri, 21 Apr 2006 14:28:36 +0000 (14:28 +0000)
committerAndrei Pelinescu-Onciul <andrei@iptel.org>
Fri, 21 Apr 2006 14:28:36 +0000 (14:28 +0000)
  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

22 files changed:
Makefile.defs
action.c
config.h
forward.c
ip_addr.h
modules/tm/sip_msg.c
modules/tm/t_funcs.c
modules/tm/t_fwd.c
modules/tm/t_fwd.h
modules/tm/t_lookup.c
modules/tm/t_msgbuilder.c
modules/tm/t_msgbuilder.h
modules/tm/t_reply.c
modules/tm/uac.c
modules/tm/ut.h
msg_translator.c
msg_translator.h
parser/msg_parser.h
parser/parse_uri.c
parser/parse_via.c
parser/parse_via.h
version.h

index 3e45495..4e85a74 100644 (file)
@@ -66,7 +66,7 @@ MAIN_NAME=ser
 VERSION = 0
 PATCHLEVEL = 10
 SUBLEVEL =   99
-EXTRAVERSION = -dev39
+EXTRAVERSION = -dev40
 
 SER_VER = $(shell expr $(VERSION) \* 1000000 + $(PATCHLEVEL) \* 1000 + \
                        $(SUBLEVEL) )
@@ -335,6 +335,10 @@ endif
 # -DHAVE_RESOLV_RES
 #              support for changing some of the resolver parameters present
 #               (_res structure in <resolv.h>)
+# -DUSE_COMP
+#              compiles in comp=[sergz|sigcomp] support (parsing uri & via, 
+#              adding it to via, lumps a.s.o). WARNING: right now this option
+#              is useless since the compression code doesn't exist yet.
 
 
 DEFS+= $(extra_defs) \
index 5eea979..96cb315 100644 (file)
--- a/action.c
+++ b/action.c
@@ -146,7 +146,8 @@ int do_action(struct action* a, struct sip_msg* msg)
                                /*parse uri*/
 
                                if (msg->dst_uri.len) {
-                                       ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len, &next_hop);
+                                       ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len,
+                                                                       &next_hop);
                                        u = &next_hop;
                                } else {
                                        ret = parse_sip_msg_uri(msg);
@@ -212,6 +213,9 @@ int do_action(struct action* a, struct sip_msg* msg)
                                        ret=E_BAD_ADDRESS;
                                        goto error_fwd_uri;
                                }
+#ifdef USE_COMP
+                               dst.comp=u->comp;
+#endif
                                ret=forward_request(msg, &dst);
                                if (ret>=0) ret=1;
                        }else if ((a->val[0].type==PROXY_ST) && (a->val[1].type==NUMBER_ST)){
index cd15b10..7e400ba 100644 (file)
--- a/config.h
+++ b/config.h
 #define TRANSPORT_PARAM ";transport="
 #define TRANSPORT_PARAM_LEN (sizeof(TRANSPORT_PARAM) - 1)
 
+#define COMP_PARAM ";comp="
+#define COMP_PARAM_LEN (sizeof(COMP_PARAM)-1)
+
+#define SIGCOMP_NAME "sigcomp"
+#define SIGCOMP_NAME_LEN (sizeof(SIGCOMP_NAME)-1)
+
+#define SERGZ_NAME "sergz"
+#define SERGZ_NAME_LEN (sizeof(SERGZ_NAME)-1)
+
 #define TOTAG_TOKEN ";tag="
 #define TOTAG_TOKEN_LEN (sizeof(TOTAG_TOKEN)-1)
 
index 9850076..3d47741 100644 (file)
--- a/forward.c
+++ b/forward.c
@@ -49,6 +49,7 @@
  *  2005-12-11  onsend_router support; forward_request to no longer
  *              pkg_malloc'ed (andrei)
  *  2006-04-12  forward_{request,reply} use now struct dest_info (andrei)
+ *  2006-04-21  basic comp via param support (andrei)
  */
 
 
@@ -315,8 +316,7 @@ int forward_request(struct sip_msg* msg, struct dest_info* send_info)
                }
        }
 
-       buf = build_req_buf_from_sip_req(msg, &len, send_info->send_sock,
-                                                                                       send_info->proto);
+       buf = build_req_buf_from_sip_req(msg, &len, send_info);
        if (!buf){
                LOG(L_ERR, "ERROR: forward_request: building failed\n");
                goto error;
@@ -468,7 +468,9 @@ int forward_reply(struct sip_msg* msg)
 
        dst.proto=msg->via2->proto;
        if (update_sock_struct_from_via( &dst.to, msg, msg->via2 )==-1) goto error;
-
+#ifdef USE_COMP
+       dst.comp=msg->via2->comp_no;
+#endif
 
 #ifdef USE_TCP
        if (dst.proto==PROTO_TCP
index cae7883..d743b4d 100644 (file)
--- a/ip_addr.h
+++ b/ip_addr.h
@@ -30,6 +30,8 @@
  * --------
  *  2003-02-13  added struct dest_info (andrei)
  *  2003-04-06  all ports are stored/passed in host byte order now (andrei)
+ *  2006-04-20  comp support in recv_info and dest_info (andrei)
+ *  2006-04-21  added init_dst_from_rcv (andrei)
  */
 
 #ifndef ip_addr_h
@@ -46,7 +48,9 @@
 #include "dprint.h"
 
 enum sip_protos { PROTO_NONE, PROTO_UDP, PROTO_TCP, PROTO_TLS, PROTO_SCTP };
-
+#ifdef USE_COMP
+enum comp_methods { COMP_NONE, COMP_SIGCOMP, COMP_SERGZ };
+#endif
 
 struct ip_addr{
        unsigned int af; /* address family: AF_INET6 or AF_INET */
@@ -100,21 +104,27 @@ struct receive_info{
        struct ip_addr dst_ip;
        unsigned short src_port; /* host byte order */
        unsigned short dst_port; /* host byte order */
-       int proto;
        int proto_reserved1; /* tcp stores the connection id here */
        int proto_reserved2;
        union sockaddr_union src_su; /* useful for replies*/
        struct socket_info* bind_address; /* sock_info structure on which 
                                                                          the msg was received*/
+       short proto;
+#ifdef USE_COMP
+       short comp; /* compression */
+#endif
        /* no need for dst_su yet */
 };
 
 
 struct dest_info{
-       int proto;
-       int id; /* tcp stores the connection id here */ 
-       union sockaddr_union to;
        struct socket_info* send_sock;
+       union sockaddr_union to;
+       int id; /* tcp stores the connection id here */ 
+       short proto;
+#ifdef USE_COMP
+       short comp;
+#endif
 };
 
 
@@ -553,10 +563,23 @@ static inline struct hostent* ip_addr2he(str* name, struct ip_addr* ip)
 /* init a dest_info structure */
 #define init_dest_info(dst) \
        do{ \
-               (dst)->proto=0; \
-               (dst)->id=0; \
-               (dst)->send_sock=0; \
-               memset(&(dst)->to, 0, sizeof(union sockaddr_union)); \
+               memset((dst), 0, sizeof(struct dest_info)); \
        } while(0) 
 
+
+
+/* init a dest_info structure from a recv_info structure */
+inline static void init_dst_from_rcv(struct dest_info* dst,
+                                                                       struct receive_info* rcv)
+{
+               dst->send_sock=rcv->bind_address;
+               dst->to=rcv->src_su;
+               dst->id=rcv->proto_reserved1;
+               dst->proto=rcv->proto;
+#ifdef USE_COMP
+               dst->comp=rcv->comp;
+#endif
+}
+
+
 #endif
index cfe7c9f..03b2503 100644 (file)
@@ -46,6 +46,7 @@
  *  2003-05-07  received, rport & i via shortcuts are also translated (andrei)
  *  2003-11-11  updated cloning of lump_rpl (bogdan)
  *  2004-03-31  alias shortcuts are also translated (andrei)
+ *  2006-04-20  via->comp is also translated (andrei)
  */
 
 #include "defs.h"
@@ -154,6 +155,12 @@ inline struct via_body* via_body_cloner( char* new_buf,
                                        case PARAM_ALIAS:
                                                        new_via->alias = new_vp;
                                                        break;
+                                                       
+#ifdef USE_COMP
+                                       case PARAM_COMP:
+                                                       new_via->comp = new_vp;
+                                                       break;
+#endif
                                }
 
                                if (last_new_vp)
index 6aef325..0c1354b 100644 (file)
@@ -230,7 +230,7 @@ int t_relay_to( struct sip_msg  *p_msg , struct proxy_l *proxy, int proto,
                DBG( "SER: forwarding ACK  statelessly \n");
                if (proxy==0) {
                        uri = GET_RURI(p_msg);
-                       if (uri2dst(&dst, GET_NEXT_HOP(p_msg), proto)==0){
+                       if (uri2dst(&dst, p_msg, GET_NEXT_HOP(p_msg), proto)==0){
                                ret=E_BAD_ADDRESS;
                                goto done;
                        }
@@ -239,6 +239,8 @@ int t_relay_to( struct sip_msg  *p_msg , struct proxy_l *proxy, int proto,
                        init_dest_info(&dst);
                        dst.proto=get_proto(proto, proxy->proto);
                        proxy2su(&dst.to, proxy);
+                       /* dst->send_sock not set, but forward_request will take care
+                        * of it */
                        ret=forward_request( p_msg , &dst) ;
                }
                goto done;
index d2356db..3125744 100644 (file)
@@ -49,6 +49,7 @@
  *              already canceled transaction is attempted (andrei)
  *  2006-02-07  named routes support (andrei)
  *  2006-04-18  add_uac simplified + switched to struct dest_info (andrei)
+ *  2006-04-20  pint_uac_request uses now struct dest_info (andrei)
  */
 
 #include "defs.h"
@@ -98,9 +99,8 @@ unsigned int get_on_branch(void)
 }
 
 
-char *print_uac_request( struct cell *t, struct sip_msg *i_req,
-       int branch, str *uri, unsigned int *len, struct socket_info *send_sock,
-       enum sip_protos proto )
+static char *print_uac_request( struct cell *t, struct sip_msg *i_req,
+       int branch, str *uri, unsigned int *len, struct dest_info* dst)
 {
        char *buf, *shbuf;
        str* msg_uri;
@@ -139,7 +139,7 @@ char *print_uac_request( struct cell *t, struct sip_msg *i_req,
        run_trans_callbacks( TMCB_REQUEST_FWDED , t, i_req, 0, -i_req->REQ_METHOD);
 
        /* ... and build it now */
-       buf=build_req_buf_from_sip_req( i_req, len, send_sock, proto );
+       buf=build_req_buf_from_sip_req( i_req, len, dst);
 #ifdef DBG_MSG_QA
        if (buf[*len-1]==0) {
                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,
                goto error;
        }
 
-       init_dest_info(&t->uac[branch].request.dst);
        /* check DNS resolution */
        if (proxy){
                /* dst filled from the proxy */
+               init_dest_info(&t->uac[branch].request.dst);
                t->uac[branch].request.dst.proto=get_proto(proto, proxy->proto);
                proxy2su(&t->uac[branch].request.dst.to, proxy);
+               /* fill dst send_sock */
+               t->uac[branch].request.dst.send_sock =
+               get_send_socket( request, &t->uac[branch].request.dst.to,
+                                                               t->uac[branch].request.dst.proto);
        }else {
-               /* dst filled from the uri */
-               if (uri2dst(&t->uac[branch].request.dst,
+               /* dst filled from the uri & request (send_socket) */
+               if (uri2dst(&t->uac[branch].request.dst, request,
                                                next_hop ? next_hop: uri, proto)==0){
                        ret=E_BAD_ADDRESS;
                        goto error;
                }
        }
-
-       /* fill dst send_sock */
-       t->uac[branch].request.dst.send_sock =
-                       get_send_socket( request, &t->uac[branch].request.dst.to,
-                                                               t->uac[branch].request.dst. proto);
+       
+       /* check if send_sock is ok */
        if (t->uac[branch].request.dst.send_sock==0) {
                LOG(L_ERR, "ERROR: add_uac: can't fwd to af %d, proto %d "
                        " (no corresponding listening socket)\n",
@@ -276,8 +277,7 @@ int add_uac( struct cell *t, struct sip_msg *request, str *uri, str* next_hop,
 
        /* now message printing starts ... */
        shbuf=print_uac_request( t, request, branch, uri, 
-               &len, t->uac[branch].request.dst.send_sock, 
-                       t->uac[branch].request.dst.proto );
+                                                       &len, &t->uac[branch].request.dst);
        if (!shbuf) {
                ret=ser_error=E_OUT_OF_MEM;
                goto error01;
@@ -322,9 +322,8 @@ int e2e_cancel_branch( struct sip_msg *cancel_msg, struct cell *t_cancel,
 
        /* print */
        shbuf=print_uac_request( t_cancel, cancel_msg, branch, 
-               &t_invite->uac[branch].uri, &len, 
-               t_invite->uac[branch].request.dst.send_sock,
-               t_invite->uac[branch].request.dst.proto);
+                                                       &t_invite->uac[branch].uri, &len, 
+                                                       &t_invite->uac[branch].request.dst);
        if (!shbuf) {
                LOG(L_ERR, "ERROR: e2e_cancel_branch: printing e2e cancel failed\n");
                ret=ser_error=E_OUT_OF_MEM;
index a981393..facef27 100644 (file)
@@ -45,9 +45,10 @@ typedef int (*taddblind_f)( /*struct cell *t */ );
 void t_on_branch(unsigned int go_to);
 unsigned int get_on_branch();
 int t_replicate(struct sip_msg *p_msg, struct proxy_l * proxy, int proto);
+/*  -- not use outside t_fwd.c for noe
 char *print_uac_request( struct cell *t, struct sip_msg *i_req,
-    int branch, str *uri, unsigned int *len, struct socket_info *send_sock,
-    enum sip_protos proto);
+    int branch, str *uri, unsigned int *len, struct dest_info *dst);
+*/
 void e2e_cancel( struct sip_msg *cancel_msg, struct cell *t_cancel, struct cell *t_invite );
 int e2e_cancel_branch( struct sip_msg *cancel_msg, struct cell *t_cancel, struct cell *t_invite, int branch );
 int add_uac(   struct cell *t, struct sip_msg *request, str *uri, str* next_hop,
index 8fe2f31..f030ef9 100644 (file)
@@ -82,7 +82,6 @@
  * 2005-12-09  added t_set_fr()  (andrei)
  * 2006-01-27  transaction lookup function will set up a cancel flag
  *             if the searched transaction was pre-canceled (andrei)
- * 
  */
 
 #include "defs.h"
@@ -988,6 +987,7 @@ int init_rb( struct retr_buf *rb, struct sip_msg *msg)
 
        /* rb. timers are init. init_t()/new_cell() */
        via=msg->via1;
+       /* rb->dst is already init (0) by new_t()/build_cell() */
        if (!reply_to_via) {
                update_sock_struct_from_ip( &rb->dst.to, msg );
                proto=msg->rcv.proto;
@@ -1003,6 +1003,9 @@ int init_rb( struct retr_buf *rb, struct sip_msg *msg)
        }
        rb->dst.proto=proto;
        rb->dst.id=msg->rcv.proto_reserved1;
+#ifdef USE_COMP
+       rb->dst.comp=via->comp_no;
+#endif
        /* turn off mhomed for generating replies -- they are ideally sent to where
           request came from to make life with NATs and other beasts easier
        */
index 3b5a4e6..4af72c6 100644 (file)
@@ -38,6 +38,8 @@
  * 2003-10-02  added via_builder set host/port support (andrei)
  * 2004-02-11  FIFO/CANCEL + alignments (hash=f(callid,cseq)) (uli+jiri)
  * 2004-02-13: t->is_invite and t->local replaced with flags (bogdan)
+ * 2006-04-21  build_uac_req, assemble_via use struct dest_info now;
+ *              uri2sock replaced with uri2dst (andrei)
  */
 
 #include "defs.h"
@@ -100,8 +102,8 @@ char *build_local(struct cell *Trans,unsigned int branch,
        branch_str.s=branch_buf;
        branch_str.len=branch_len;
        set_hostport(&hp, (is_local(Trans))?0:(Trans->uas.request));
-       via=via_builder(&via_len, Trans->uac[branch].request.dst.send_sock,
-               &branch_str, 0, Trans->uac[branch].request.dst.proto, &hp );
+       via=via_builder(&via_len, &Trans->uac[branch].request.dst,
+               &branch_str, 0, &hp );
        if (!via)
        {
                LOG(L_ERR, "ERROR: build_local: "
@@ -355,7 +357,7 @@ static inline int get_contact_uri(struct sip_msg* msg, str* uri)
 
      /*
       * The function creates an ACK to 200 OK. Route set will be created
-      * and parsed and next_hop parameter will contain uri the which the
+      * and parsed and next_hop parameter will contain the uri to which the
       * request should be send. The function is used by tm when it generates
       * local ACK to 200 OK (on behalf of applications using uac
       */
@@ -370,8 +372,7 @@ char *build_dlg_ack(struct sip_msg* rpl, struct cell *Trans, unsigned int branch
        struct hostport hp;
        struct rte* list;
        str contact, ruri, *cont;
-       struct socket_info* send_sock;
-       union sockaddr_union to_su;
+       struct dest_info dst;
        
        if (get_contact_uri(rpl, &contact) < 0) {
                return 0;
@@ -399,9 +400,8 @@ char *build_dlg_ack(struct sip_msg* rpl, struct cell *Trans, unsigned int branch
        
        
             /* via */
-       send_sock = uri2sock(rpl, next_hop, &to_su, PROTO_NONE);
-       if (!send_sock) {
-               LOG(L_ERR, "build_dlg_ack: no socket found\n");
+       if ((uri2dst(&dst, rpl, next_hop, PROTO_NONE)==0) || (dst.send_sock==0)){
+                       LOG(L_ERR, "build_dlg_ack: no socket found\n");
                goto error;
        }
        
@@ -409,7 +409,7 @@ char *build_dlg_ack(struct sip_msg* rpl, struct cell *Trans, unsigned int branch
        branch_str.s = branch_buf;
        branch_str.len = branch_len;
        set_hostport(&hp, 0);
-       via = via_builder(&via_len, send_sock, &branch_str, 0, send_sock->proto, &hp);
+       via = via_builder(&via_len, &dst, &branch_str, 0, &hp);
        if (!via) {
                LOG(L_ERR, "build_dlg_ack: No via header got from builder\n");
                goto error;
@@ -529,7 +529,8 @@ static inline int print_cseq_num(str* _s, dlg_t* _d)
 /*
  * Create Via header
  */
-static inline int assemble_via(str* dest, struct cell* t, struct socket_info* sock, int branch)
+static inline int assemble_via(str* dest, struct cell* t, 
+                                                               struct dest_info* dst, int branch)
 {
        static char branch_buf[MAX_BRANCH_PARAM_LEN];
        char* via;
@@ -551,7 +552,7 @@ static inline int assemble_via(str* dest, struct cell* t, struct socket_info* so
 #endif
 
        set_hostport(&hp, 0);
-       via = via_builder(&via_len, sock, &branch_str, 0, sock->proto, &hp);
+       via = via_builder(&via_len, dst, &branch_str, 0, &hp);
        if (!via) {
                LOG(L_ERR, "assemble_via: via building failed\n");
                return -2;
@@ -674,7 +675,7 @@ static inline char* print_callid(char* w, dlg_t* dialog, struct cell* t)
  * Create a request
  */
 char* build_uac_req(str* method, str* headers, str* body, dlg_t* dialog, int branch, 
-                       struct cell *t, int* len, struct socket_info* send_sock)
+                       struct cell *t, int* len, struct dest_info* dst)
 {
        char* buf, *w;
        str content_length, cseq, via;
@@ -693,7 +694,7 @@ char* build_uac_req(str* method, str* headers, str* body, dlg_t* dialog, int bra
        }
        *len = method->len + 1 + dialog->hooks.request_uri->len + 1 + SIP_VERSION_LEN + CRLF_LEN;
 
-       if (assemble_via(&via, t, send_sock, branch) < 0) {
+       if (assemble_via(&via, t, dst, branch) < 0) {
                LOG(L_ERR, "build_uac_req(): Error while assembling Via\n");
                return 0;
        }
index 687abad..32ccf2d 100644 (file)
@@ -89,7 +89,7 @@ char *build_dlg_ack(struct sip_msg* rpl, struct cell *Trans, unsigned int branch
  * Create a request
  */
 char* build_uac_req(str* method, str* headers, str* body, dlg_t* dialog, int branch, 
-                   struct cell *t, int* len, struct socket_info* send_sock);
+                   struct cell *t, int* len, struct dest_info* dst);
 
 
 int t_calc_branch(struct cell *t,
index 4502ce7..b7d05a8 100644 (file)
@@ -322,13 +322,10 @@ static int send_local_ack(struct sip_msg* msg, str* next_hop,
                LOG(L_ERR, "send_local_ack: Invalid parameter value\n");
                return -1;
        }
-       init_dest_info(&dst);
-       dst.send_sock = uri2sock(msg, next_hop, &dst.to, PROTO_NONE);
-       if (!dst.send_sock) {
+       if ((uri2dst(&dst, msg,  next_hop, PROTO_NONE)==0) || (dst.send_sock==0)){
                LOG(L_ERR, "send_local_ack: no socket found\n");
                return -1;
        }
-       dst.id=0;
        return msg_send(&dst, ack, ack_len);
 }
 
index 4e44570..7b54267 100644 (file)
@@ -170,8 +170,7 @@ static inline unsigned int dlg2hash( dlg_t* dlg )
 int t_uac(str* method, str* headers, str* body, dlg_t* dialog,
          transaction_cb cb, void* cbp)
 {
-       struct socket_info* send_sock;
-       union sockaddr_union to_su;
+       struct dest_info dst;
        struct cell *new_cell;
        struct retr_buf *request;
        char* buf;
@@ -189,8 +188,9 @@ int t_uac(str* method, str* headers, str* body, dlg_t* dialog,
        DBG("DEBUG:tm:t_uac: next_hop=<%.*s>\n",dialog->hooks.next_hop->len,
                        dialog->hooks.next_hop->s);
        /* it's a new message, so we will take the default socket */
-       send_sock = uri2sock(0, dialog->hooks.next_hop, &to_su, PROTO_NONE);
-       if (!send_sock) {
+       if ((uri2dst(&dst, 0, dialog->hooks.next_hop, PROTO_NONE)==0) ||
+                       (dst.send_sock==0)){
+               ser_error = E_NO_SOCKET;
                ret=ser_error;
                LOG(L_ERR, "t_uac: no socket found\n");
                goto error2;
@@ -233,11 +233,7 @@ int t_uac(str* method, str* headers, str* body, dlg_t* dialog,
 
        request = &new_cell->uac[0].request;
        
-       init_dest_info(&request->dst);
-       request->dst.to = to_su;
-       request->dst.send_sock = send_sock;
-       request->dst.proto = send_sock->proto;
-       request->dst.id = 0;
+       request->dst = dst;
 
        hi=dlg2hash(dialog);
        LOCK_HASH(hi);
@@ -245,7 +241,7 @@ int t_uac(str* method, str* headers, str* body, dlg_t* dialog,
        UNLOCK_HASH(hi);
 
        buf = build_uac_req(method, headers, body, dialog, 0, new_cell,
-               &buf_len, send_sock);
+               &buf_len, &dst);
        if (!buf) {
                LOG(L_ERR, "t_uac: Error while building message\n");
                ret=E_OUT_OF_MEM;
index 710edb8..7b0e8b2 100644 (file)
@@ -135,13 +135,17 @@ inline static struct proxy_l *uri2proxy( str *uri, int proto )
 
 /*
  * Convert a URI into a dest_info structure
- * params: dst - will be filled
+ * params: msg - sip message used to set dst->send_sock, if 0 dst->send_sock
+ *               will be set to the default w/o using msg->force_send_socket 
+ *               (see get_send_socket()) 
+ *         dst - will be filled
  *         uri - uri in str form
  *         proto - if != PROTO_NONE, this protocol will be forced over the
  *                 uri_proto, otherwise the uri proto will be used
  * returns 0 on error, dst on success
  */
-inline static struct dest_info *uri2dst(struct dest_info* dst, str *uri, 
+inline static struct dest_info *uri2dst(struct dest_info* dst,
+                                                                               struct sip_msg *msg, str *uri, 
                                                                                        int proto )
 {
        struct sip_uri parsed_uri;
@@ -165,37 +169,53 @@ inline static struct dest_info *uri2dst(struct dest_info* dst, str *uri,
        
        init_dest_info(dst);
        dst->proto= get_proto(proto, uri_proto);
+#ifdef USE_COMP
+       dst->comp=parsed_uri.comp;
+#endif
        sip_hostport2su(&dst->to, &parsed_uri.host, parsed_uri.port_no,
                                                dst->proto);
+       if (msg){
+               dst->send_sock = get_send_socket(msg, &dst->to, dst->proto);
+               if (dst->send_sock==0) {
+                       LOG(L_ERR, "ERROR: uri2sock: no corresponding socket for af %d\n", 
+                                       dst->to.s.sa_family);
+                       /* ser_error = E_NO_SOCKET;*/
+                       /* try to continue */
+               }
+       }
        return dst;
 }
 
 
 
 /*
- * Convert a URI into socket_info
+ * Convert a URI into the corresponding sockaddr_union (address to send to) and
+ *  send socket_info (socket/address from which to send)
+ *  to_su is filled with the destination and the socket_info that will be 
+ *  used for sending is returned.
+ *  On error return 0.
+ *
+ *  NOTE: this function is deprecated, you should use uri2dst instead
  */
 static inline struct socket_info *uri2sock(struct sip_msg* msg, str *uri,
                                                                        union sockaddr_union *to_su, int proto)
 {
-       struct socket_info* send_sock;
        struct dest_info dst;
 
-       if (uri2dst(&dst, uri, proto)==0){
+       if (uri2dst(&dst, msg, uri, proto)==0){
                LOG(L_ERR, "ERROR: uri2sock: Can't create a dst proxy\n");
                ser_error=E_BAD_ADDRESS;
                return 0;
        }
        *to_su=dst.to; /* copy su */
        
-       /* we use dst->proto since uri2dst just set it correctly*/
-       send_sock = get_send_socket(msg, to_su, dst.proto);
-       if (!send_sock) {
+       /* we use dst->send_socket since uri2dst just set it correctly*/
+       if (dst.send_sock==0) {
                LOG(L_ERR, "ERROR: uri2sock: no corresponding socket for af %d\n", 
                    to_su->s.sa_family);
                ser_error = E_NO_SOCKET;
        }
-       return send_sock;
+       return dst.send_sock;
 }
 
 
index 26e3a50..bc95c68 100644 (file)
@@ -56,6 +56,9 @@
  * 2003-10-08  receive_test function-alized (jiri)
  * 2003-10-20  added body_lump list (sip_msg), adjust_clen (andrei & jan)
  * 2003-11-11  type of rpl_lumps replaced by flags (bogdan)
+ * 2006-04-20  build_req_from_sip_req, via_builder and lump_* functions
+ *              use now struct dest_info; lumps & via comp param support
+ *              (rfc3486) (andrei)
  *
  */
 /* Via special params:
@@ -436,7 +439,7 @@ char* clen_builder(struct sip_msg* msg, int *clen_len, int diff)
  * returns 1 if cond is true, 0 if false */
 static inline int lump_check_opt(      enum lump_conditions cond,
                                                                        struct sip_msg* msg,
-                                                                       struct socket_info* snd_s
+                                                                       struct dest_info* snd_i
                                                                        )
 {
        struct ip_addr* ip;
@@ -444,7 +447,7 @@ static inline int lump_check_opt(   enum lump_conditions cond,
        int proto;
 
 #define get_ip_port_proto \
-                       if (snd_s==0){ \
+                       if ((snd_i==0) || (snd_i->send_sock==0)){ \
                                LOG(L_CRIT, "ERROR: lump_check_opt: null send socket\n"); \
                                return 1; /* we presume they are different :-) */ \
                        } \
@@ -466,30 +469,34 @@ static inline int lump_check_opt( enum lump_conditions cond,
                case COND_IF_DIFF_REALMS:
                        get_ip_port_proto;
                        /* faster tests first */
-                       if ((port==snd_s->port_no)&&(proto==snd_s->proto)&&
-                               (ip_addr_cmp(ip, &snd_s->address)))
+                       if ((port==snd_i->send_sock->port_no) && 
+                                       (proto==snd_i->send_sock->proto) &&
+#ifdef USE_COMP
+                                       (msg->rcv.comp==snd_i->comp) &&
+#endif
+                                       (ip_addr_cmp(ip, &snd_i->send_sock->address)))
                                return 0;
                        else return 1;
                case COND_IF_DIFF_AF:
                        get_ip_port_proto;
-                       if (ip->af!=snd_s->address.af) return 1;
+                       if (ip->af!=snd_i->send_sock->address.af) return 1;
                        else return 0;
                case COND_IF_DIFF_PROTO:
                        get_ip_port_proto;
-                       if (proto!=snd_s->proto) return 1;
+                       if (proto!=snd_i->send_sock->proto) return 1;
                        else return 0;
                case COND_IF_DIFF_PORT:
                        get_ip_port_proto;
-                       if (port!=snd_s->port_no) return 1;
+                       if (port!=snd_i->send_sock->port_no) return 1;
                        else return 0;
                case COND_IF_DIFF_IP:
                        get_ip_port_proto;
-                       if (ip_addr_cmp(ip, &snd_s->address)) return 0;
+                       if (ip_addr_cmp(ip, &snd_i->send_sock->address)) return 0;
                        else return 1;
                case COND_IF_RAND:
                        return (rand()>=RAND_MAX/2);
                default:
-                       LOG(L_CRIT, "BUG: lump_check_opt: unknown lump condition %d\n",
+                       LOG(L_CRIT, "BUG: lump:w_check_opt: unknown lump condition %d\n",
                                        cond);
        }
        return 0; /* false */
@@ -499,7 +506,8 @@ static inline int lump_check_opt(   enum lump_conditions cond,
 
 /* computes the "unpacked" len of a lump list,
    code moved from build_req_from_req */
-static inline int lumps_len(struct sip_msg* msg, struct lump* lumps, struct socket_info* send_sock)
+static inline int lumps_len(struct sip_msg* msg, struct lump* lumps, 
+                                                               struct dest_info* send_info)
 {
        int s_offset;
        int new_len;
@@ -507,7 +515,46 @@ static inline int lumps_len(struct sip_msg* msg, struct lump* lumps, struct sock
        struct lump* r;
        str* send_address_str;
        str* send_port_str;
+       struct socket_info* send_sock;
+       
+
+#ifdef USE_COMP
+       #define RCVCOMP_LUMP_LEN \
+                                               /* add;comp=xxx */ \
+                                       switch(msg->rcv.comp){ \
+                                               case COMP_NONE: \
+                                                               break; \
+                                               case COMP_SIGCOMP: \
+                                                               new_len+=COMP_PARAM_LEN+SIGCOMP_NAME_LEN; \
+                                                               break; \
+                                               case COMP_SERGZ: \
+                                                               new_len+=COMP_PARAM_LEN+SERGZ_NAME_LEN ; \
+                                                               break; \
+                                               default: \
+                                               LOG(L_CRIT, "BUG: lumps_len: unknown comp %d\n", \
+                                                               msg->rcv.comp); \
+                                       }
 
+       #define SENDCOMP_LUMP_LEN \
+                                       /* add;comp=xxx */ \
+                                       switch(send_info->comp){ \
+                                               case COMP_NONE: \
+                                                               break; \
+                                               case COMP_SIGCOMP: \
+                                                               new_len+=COMP_PARAM_LEN+SIGCOMP_NAME_LEN; \
+                                                               break; \
+                                               case COMP_SERGZ: \
+                                                               new_len+=COMP_PARAM_LEN+SERGZ_NAME_LEN ; \
+                                                               break; \
+                                               default: \
+                                               LOG(L_CRIT, "BUG: lumps_len: unknown comp %d\n", \
+                                                               send_info->comp); \
+                                       }
+#else
+       #define RCVCOMP_LUMP_LEN
+       #define SENDCOMP_LUMP_LEN
+#endif /*USE_COMP */
+       
 #define SUBST_LUMP_LEN(subst_l) \
                switch((subst_l)->u.subst){ \
                        case SUBST_RCV_IP: \
@@ -574,6 +621,7 @@ static inline int lumps_len(struct sip_msg* msg, struct lump* lumps, struct sock
                                                LOG(L_CRIT, "BUG: lumps_len: unknown proto %d\n", \
                                                                msg->rcv.bind_address->proto); \
                                        }\
+                                       RCVCOMP_LUMP_LEN \
                                }else{ \
                                        /* FIXME */ \
                                        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
                                                LOG(L_CRIT, "BUG: lumps_len: unknown proto %d\n", \
                                                                send_sock->proto); \
                                        }\
+                                       SENDCOMP_LUMP_LEN \
                                }else{ \
                                        /* FIXME */ \
                                        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
                                LOG(L_CRIT, "BUG: unknown subst type %d\n", \
                                                (subst_l)->u.subst); \
                }
-
+       
+       if (send_info){
+               send_sock=send_info->send_sock;
+       }else{
+               send_sock=0;
+       };
        s_offset=0;
        new_len=0;
        /* 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
 
        for(t=lumps;t;t=t->next){
                /* skip if this is an OPT lump and the condition is not satisfied */
-               if ((t->op==LUMP_ADD_OPT) && !lump_check_opt(t->u.cond, msg, send_sock))
+               if ((t->op==LUMP_ADD_OPT)&& !lump_check_opt(t->u.cond, msg, send_info))
                        continue;
                for(r=t->before;r;r=r->before){
                        switch(r->op){
@@ -687,7 +741,7 @@ static inline int lumps_len(struct sip_msg* msg, struct lump* lumps, struct sock
                                case LUMP_ADD_OPT:
                                        /* skip if this is an OPT lump and the condition is
                                         * not satisfied */
-                                       if (!lump_check_opt(r->u.cond, msg, send_sock))
+                                       if (!lump_check_opt(r->u.cond, msg, send_info))
                                                goto skip_before;
                                        break;
                                default:
@@ -743,7 +797,7 @@ skip_before:
                                case LUMP_ADD_OPT:
                                        /* skip if this is an OPT lump and the condition is
                                         * not satisfied */
-                                       if (!lump_check_opt(r->u.cond, msg, send_sock))
+                                       if (!lump_check_opt(r->u.cond, msg, send_info))
                                                goto skip_after;
                                        break;
                                default:
@@ -756,6 +810,8 @@ skip_after:
                ; /* to make gcc 3.* happy */
        }
        return new_len;
+#undef RCVCOMP_LUMP_LEN
+#undef SENDCOMP_LUMP_LEN
 }
 
 
@@ -768,7 +824,7 @@ static inline void process_lumps(   struct sip_msg* msg,
                                                                        char* new_buf,
                                                                        unsigned int* new_buf_offs,
                                                                        unsigned int* orig_offs,
-                                                                       struct socket_info* send_sock)
+                                                                       struct dest_info* send_info)
 {
        struct lump *t;
        struct lump *r;
@@ -778,6 +834,58 @@ static inline void process_lumps(  struct sip_msg* msg,
        int s_offset;
        str* send_address_str;
        str* send_port_str;
+       struct socket_info* send_sock;
+
+#ifdef USE_COMP
+       #define RCVCOMP_PARAM_ADD \
+                               /* add ;comp=xxxx */ \
+                               switch(msg->rcv.comp){ \
+                                       case COMP_NONE: \
+                                               break; \
+                                       case COMP_SIGCOMP: \
+                                               memcpy(new_buf+offset, COMP_PARAM, COMP_PARAM_LEN);\
+                                               offset+=COMP_PARAM_LEN; \
+                                               memcpy(new_buf+offset, SIGCOMP_NAME, \
+                                                               SIGCOMP_NAME_LEN); \
+                                               offset+=SIGCOMP_NAME_LEN; \
+                                               break; \
+                                       case COMP_SERGZ: \
+                                               memcpy(new_buf+offset, COMP_PARAM, COMP_PARAM_LEN);\
+                                               offset+=COMP_PARAM_LEN; \
+                                               memcpy(new_buf+offset, SERGZ_NAME, SERGZ_NAME_LEN); \
+                                               offset+=SERGZ_NAME_LEN; \
+                                               break;\
+                                       default:\
+                                               LOG(L_CRIT, "BUG: process_lumps: unknown comp %d\n", \
+                                                               msg->rcv.comp); \
+                               }
+       
+       #define SENDCOMP_PARAM_ADD \
+                               /* add ;comp=xxxx */ \
+                               switch(send_info->comp){ \
+                                       case COMP_NONE: \
+                                               break; \
+                                       case COMP_SIGCOMP: \
+                                               memcpy(new_buf+offset, COMP_PARAM, COMP_PARAM_LEN);\
+                                               offset+=COMP_PARAM_LEN; \
+                                               memcpy(new_buf+offset, SIGCOMP_NAME, \
+                                                               SIGCOMP_NAME_LEN); \
+                                               offset+=SIGCOMP_NAME_LEN; \
+                                               break; \
+                                       case COMP_SERGZ: \
+                                               memcpy(new_buf+offset, COMP_PARAM, COMP_PARAM_LEN);\
+                                               offset+=COMP_PARAM_LEN; \
+                                               memcpy(new_buf+offset, SERGZ_NAME, SERGZ_NAME_LEN); \
+                                               offset+=SERGZ_NAME_LEN; \
+                                               break;\
+                                       default:\
+                                               LOG(L_CRIT, "BUG: process_lumps: unknown comp %d\n", \
+                                                               msg->rcv.comp); \
+                               } 
+#else
+       #define RCVCOMP_PARAM_ADD
+       #define SENDCOMP_PARAM_ADD
+#endif /* USE_COMP */
 
 #define SUBST_LUMP(subst_l) \
        switch((subst_l)->u.subst){ \
@@ -856,6 +964,7 @@ static inline void process_lumps(   struct sip_msg* msg,
                                                LOG(L_CRIT, "BUG: process_lumps: unknown proto %d\n", \
                                                                msg->rcv.bind_address->proto); \
                                } \
+                               RCVCOMP_PARAM_ADD \
                        }else{  \
                                /*FIXME*/ \
                                LOG(L_CRIT, "FIXME: process_lumps: null bind_address\n"); \
@@ -942,6 +1051,7 @@ static inline void process_lumps(  struct sip_msg* msg,
                                                LOG(L_CRIT, "BUG: process_lumps: unknown proto %d\n", \
                                                                send_sock->proto); \
                                } \
+                               SENDCOMP_PARAM_ADD \
                        }else{  \
                                /*FIXME*/ \
                                LOG(L_CRIT, "FIXME: process_lumps: null bind_address\n"); \
@@ -1008,11 +1118,15 @@ static inline void process_lumps(       struct sip_msg* msg,
                        }; \
                        break; \
                default: \
-                                       LOG(L_CRIT, "BUG: process_lumps: unknown subst type %d\n", \
+                               LOG(L_CRIT, "BUG: process_lumps: unknown subst type %d\n", \
                                                        (subst_l)->u.subst); \
-       } \
- \
+       }
 
+       if (send_info){
+               send_sock=send_info->send_sock;
+       }else{
+               send_sock=0;
+       }
        /* init send_address_str & send_port_str */
        if (msg->set_global_address.len)
                send_address_str=&(msg->set_global_address);
@@ -1036,7 +1150,7 @@ static inline void process_lumps( struct sip_msg* msg,
                                /* skip if this is an OPT lump and the condition is
                                 * not satisfied */
                                if ((t->op==LUMP_ADD_OPT) &&
-                                               (!lump_check_opt(t->u.cond, msg, send_sock)))
+                                               (!lump_check_opt(t->u.cond, msg, send_info)))
                                        continue;
                                /* just add it here! */
                                /* process before  */
@@ -1053,7 +1167,7 @@ static inline void process_lumps( struct sip_msg* msg,
                                                case LUMP_ADD_OPT:
                                                        /* skip if this is an OPT lump and the condition is
                                                        * not satisfied */
-                                                       if (!lump_check_opt(r->u.cond, msg, send_sock))
+                                                       if (!lump_check_opt(r->u.cond, msg, send_info))
                                                                goto skip_before;
                                                        break;
                                                default:
@@ -1094,7 +1208,7 @@ skip_before:
                                                case LUMP_ADD_OPT:
                                                        /* skip if this is an OPT lump and the condition is
                                                        * not satisfied */
-                                                       if (!lump_check_opt(r->u.cond, msg, send_sock))
+                                                       if (!lump_check_opt(r->u.cond, msg, send_info))
                                                                goto skip_after;
                                                        break;
                                                default:
@@ -1135,7 +1249,7 @@ skip_after:
                                                case LUMP_ADD_OPT:
                                                        /* skip if this is an OPT lump and the condition is
                                                        * not satisfied */
-                                                       if (!lump_check_opt(r->u.cond, msg, send_sock))
+                                                       if (!lump_check_opt(r->u.cond, msg, send_info))
                                                                goto skip_nop_before;
                                                        break;
                                                default:
@@ -1164,7 +1278,7 @@ skip_nop_before:
                                                case LUMP_ADD_OPT:
                                                        /* skip if this is an OPT lump and the condition is
                                                        * not satisfied */
-                                                       if (!lump_check_opt(r->u.cond, msg, send_sock))
+                                                       if (!lump_check_opt(r->u.cond, msg, send_info))
                                                                goto skip_nop_after;
                                                        break;
                                                default:
@@ -1182,6 +1296,8 @@ skip_nop_after:
        }
        *new_buf_offs=offset;
        *orig_offs=s_offset;
+#undef RCVCOMP_PARAM_ADD 
+#undef SENDCOMP_PARAM_ADD
 }
 
 
@@ -1285,7 +1401,7 @@ error:
 
 char * build_req_buf_from_sip_req( struct sip_msg* msg,
                                                                unsigned int *returned_len,
-                                                               struct socket_info* send_sock, int proto)
+                                                               struct dest_info* send_info)
 {
        unsigned int len, new_len, received_len, rport_len, uri_len, via_len, body_delta;
        char* line_buf;
@@ -1343,8 +1459,8 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
             /* Calculate message body difference and adjust
              * Content-Length
              */
-       body_delta = lumps_len(msg, msg->body_lumps, send_sock);
-       if (adjust_clen(msg, body_delta, proto) < 0) {
+       body_delta = lumps_len(msg, msg->body_lumps, send_info);
+       if (adjust_clen(msg, body_delta, send_info->proto) < 0) {
                LOG(L_ERR, "ERROR: build_req_buf_from_sip_req: Error while adjusting"
                                " Content-Length\n");
                goto error00;
@@ -1353,8 +1469,8 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
        branch.s=msg->add_to_branch_s;
        branch.len=msg->add_to_branch_len;
        set_hostport(&hp, msg);
-       line_buf = via_builder( &via_len, send_sock, &branch,
-                                                       extra_params.len?&extra_params:0, proto, &hp);
+       line_buf = via_builder( &via_len, send_info, &branch,
+                                                       extra_params.len?&extra_params:0, &hp);
        if (!line_buf){
                LOG(L_ERR,"ERROR: build_req_buf_from_sip_req: no via received!\n");
                goto error00;
@@ -1441,7 +1557,7 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
        }
 
        /* compute new msg len and fix overlapping zones*/
-       new_len=len+body_delta+lumps_len(msg, msg->add_rm, send_sock);
+       new_len=len+body_delta+lumps_len(msg, msg->add_rm, send_info);
 #ifdef XL_DEBUG
        LOG(L_ERR, "DEBUG: new_len(%d)=len(%d)+lumps_len\n", new_len, len);
 #endif
@@ -1471,8 +1587,8 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
        }
        new_buf[new_len]=0;
        /* copy msg adding/removing lumps */
-       process_lumps(msg, msg->add_rm, new_buf, &offset, &s_offset, send_sock);
-       process_lumps(msg, msg->body_lumps, new_buf, &offset, &s_offset,send_sock);
+       process_lumps(msg, msg->add_rm, new_buf, &offset, &s_offset, send_info);
+       process_lumps(msg, msg->body_lumps, new_buf, &offset, &s_offset,send_info);
        /* copy the rest of the message */
        memcpy(new_buf+offset, buf+s_offset, len-s_offset);
        new_buf[new_len]=0;
@@ -1931,16 +2047,24 @@ int branch_builder( unsigned int hash_index,
 }
 
 
+
+/* uses only the send_info->send_socket, send_info->proto and 
+ * send_info->comp (so that a send_info used for sending can be passed
+ * to this function w/o changes and the correct via will be built) */
 char* via_builder( unsigned int *len,
-       struct socket_info* send_sock,
-       str* branch, str* extra_params, int proto, struct hostport* hp)
+       struct dest_info* send_info /* where to send the reply */,
+       str* branch, str* extra_params, struct hostport* hp)
 {
        unsigned int  via_len, extra_len;
        char               *line_buf;
        int max_len;
        str* address_str; /* address displayed in via */
        str* port_str; /* port no displayed in via */
+       struct socket_info* send_sock;
+       int comp_len, comp_name_len;
+       char* comp_name;
 
+       send_sock=send_info->send_sock;
        /* use pre-set address in via or the outbound socket one */
        if ( hp && hp->host->len)
                address_str=hp->host;
@@ -1950,12 +2074,36 @@ char* via_builder( unsigned int *len,
                port_str=hp->port;
        else
                port_str=&(send_sock->port_no_str);
-
+       
+       comp_len=comp_name_len=0;
+       comp_name=0;
+#ifdef USE_COMP
+       switch(send_info->comp){
+               case COMP_NONE:
+                       break;
+               case COMP_SIGCOMP:
+                       comp_len=COMP_PARAM_LEN;
+                       comp_name_len=SIGCOMP_NAME_LEN;
+                       comp_name=SIGCOMP_NAME;
+                       break;
+               case COMP_SERGZ:
+                       comp_len=COMP_PARAM_LEN;
+                       comp_name_len=SERGZ_NAME_LEN;
+                       comp_name=SERGZ_NAME;
+                       break;
+               default:
+                       LOG(L_CRIT, "BUG: via_builder: unknown comp %d\n",
+                                       send_info->comp);
+                       /* continue, we'll just ignore comp */
+       }
+#endif /* USE_COMP */
+                       
        max_len=MY_VIA_LEN+address_str->len /* space in MY_VIA */
                +2 /* just in case it is a v6 address ... [ ] */
                +1 /*':'*/+port_str->len
                +(branch?(MY_BRANCH_LEN+branch->len):0)
                +(extra_params?extra_params->len:0)
+               +comp_len+comp_name_len
                +CRLF_LEN+1;
        line_buf=pkg_malloc( max_len );
        if (line_buf==0){
@@ -1969,14 +2117,14 @@ char* via_builder( unsigned int *len,
        via_len=MY_VIA_LEN+address_str->len; /*space included in MY_VIA*/
 
        memcpy(line_buf, MY_VIA, MY_VIA_LEN);
-       if (proto==PROTO_UDP){
+       if (send_info->proto==PROTO_UDP){
                /* do nothing */
-       }else if (proto==PROTO_TCP){
+       }else if (send_info->proto==PROTO_TCP){
                memcpy(line_buf+MY_VIA_LEN-4, "TCP ", 4);
-       }else if (proto==PROTO_TLS){
+       }else if (send_info->proto==PROTO_TLS){
                memcpy(line_buf+MY_VIA_LEN-4, "TLS ", 4);
        }else{
-               LOG(L_CRIT, "BUG: via_builder: unknown proto %d\n", proto);
+               LOG(L_CRIT, "BUG: via_builder: unknown proto %d\n", send_info->proto);
                return 0;
        }
 #      ifdef USE_IPV6
@@ -2009,6 +2157,15 @@ char* via_builder( unsigned int *len,
                memcpy(line_buf+via_len, extra_params->s, extra_params->len);
                via_len+=extra_params->len;
        }
+#ifdef USE_COMP
+       /* comp */
+       if (comp_len){
+               memcpy(line_buf+via_len, COMP_PARAM, COMP_PARAM_LEN);
+               via_len+=COMP_PARAM_LEN;
+               memcpy(line_buf+via_len, comp_name, comp_name_len);
+               via_len+=comp_name_len;
+       }
+#endif
 
        memcpy(line_buf+via_len, CRLF, CRLF_LEN);
        via_len+=CRLF_LEN;
index c9add94..4a6e446 100644 (file)
@@ -76,8 +76,7 @@ struct hostport {
        }while(0)
 
 char * build_req_buf_from_sip_req (    struct sip_msg* msg, 
-                               unsigned int *returned_len, struct socket_info* send_sock,
-                               int proto);
+                               unsigned int *returned_len, struct dest_info* send_info);
 
 char * build_res_buf_from_sip_res(     struct sip_msg* msg,
                                unsigned int *returned_len);
@@ -103,8 +102,8 @@ char * build_res_buf_with_body_from_sip_req(        unsigned int code ,
                                struct bookmark *bmark);
 */
 char* via_builder( unsigned int *len,
-       struct socket_info* send_sock,
-       str *branch, str* extra_params, int proto, struct hostport *hp );
+       struct dest_info* send_info,
+       str *branch, str* extra_params, struct hostport *hp );
 
 
 int branch_builder( unsigned int hash_index, 
index fad017f..52c6aec 100644 (file)
@@ -38,6 +38,7 @@
  *  2003-11-02  added diversion header field to sip_msg (jh)
  *  2004-11-08  added force_send_socket (andrei)
  *  2005-02-25  uri types added (sip, sips & tel)  (andrei)
+ *  2006-04-20  uri comp member (only if USE_COMP is defined) (andrei)
  */
 
 
@@ -140,6 +141,9 @@ struct sip_uri {
        unsigned short port_no;
        unsigned short proto; /* from transport */
        uri_type type; /* uri scheme */
+#ifdef USE_COMP
+       unsigned short comp;
+#endif
        /* parameters */
        str transport;
        str ttl;
index 200e1ad..afa18bf 100644 (file)
@@ -35,6 +35,7 @@
  * 2003-07-03  sips:, r2, lr=on support added (andrei)
  * 2005-02-25  preliminary tel uri support (andrei)
  * 2005-03-03  more tel uri fixes (andrei)
+ * 2006-04-20  comp uri param. support (rfc3486) if defined USE_COMP  (andrei)
  */
 
 
@@ -73,6 +74,19 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
                                        PLR_L, PLR_R_FIN, PLR_eq,
                                        /* r2 */
                                        PR2_R, PR2_2_FIN, PR2_eq,
+#ifdef USE_COMP
+                                       /* comp */
+                                       PCOMP_C, PCOMP_O, PCOMP_M, PCOMP_P, PCOMP_eq,
+                                       
+                                       /* comp values */
+                                       /* sigcomp */
+                                       VCOMP_S, VCOMP_SIGC_I, VCOMP_SIGC_G,
+                                       VCOMP_SIGC_C, VCOMP_SIGC_O,  VCOMP_SIGC_M,
+                                       VCOMP_SIGC_P_FIN,
+                                       /* sergz */
+                                                       VCOMP_SGZ_E, VCOMP_SGZ_R, VCOMP_SGZ_G,
+                                                       VCOMP_SGZ_Z_FIN,
+#endif
                                        
                                        /* transport values */
                                        /* udp */
@@ -100,6 +114,10 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
        int error_headers;
        unsigned int scheme;
        uri_type backup;
+#ifdef USE_COMP
+       str comp_str; /* not returned for now */
+       str comp_val; /* not returned for now */
+#endif
        
 #define SIP_SCH                0x3a706973
 #define SIPS_SCH       0x73706973
@@ -313,7 +331,30 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
                                } \
                                break
                        
-       
+
+#ifdef USE_COMP
+#define comp_fin(c_state, comp_no) \
+                       case c_state: \
+                               switch(*p){ \
+                                       case '@': \
+                                               still_at_user; \
+                                               break; \
+                                       semicolon_case; \
+                                               /* param_set(b, v); */ \
+                                               uri->comp=(comp_no); \
+                                               break; \
+                                       question_case; \
+                                               /* param_set(b, v) */; \
+                                               uri->comp=(comp_no); \
+                                               break; \
+                                       colon_case;  \
+                                       default: \
+                                               state=URI_VAL_P; \
+                                               break; \
+                               } \
+                               break
+                       
+#endif
 
        /* init */
        end=buf+len;
@@ -579,6 +620,13 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
                                                b=p;
                                                state=PR2_R;
                                                break;
+#ifdef USE_COMP
+                                       case 'c':
+                                       case 'C':
+                                               b=p;
+                                               state=PCOMP_C;
+                                               break;
+#endif
                                        default:
                                                state=URI_PARAM_P;
                                }
@@ -784,6 +832,44 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
                                                state=URI_VAL_P;
                                }
                                break;
+#ifdef USE_COMP
+                       param_switch(PCOMP_C,  'o', 'O' , PCOMP_O);
+                       param_switch(PCOMP_O,  'm', 'M' , PCOMP_M);
+                       param_switch(PCOMP_M,  'p', 'P' , PCOMP_P);
+                       param_switch1(PCOMP_P,  '=', PCOMP_eq);
+                       /* value */
+                       case PCOMP_eq:
+                               param=&comp_str;
+                               param_val=&comp_val;
+                               switch (*p){
+                                       param_common_cases;
+                                       case 's':
+                                       case 'S':
+                                               v=p;
+                                               state=VCOMP_S;
+                                               break;
+                                       default:
+                                               v=p;
+                                               state=URI_VAL_P;
+                               }
+                               break;
+                       /* sigcomp*/
+                       value_switch_big(VCOMP_S, 'i', 'I', 'e', 'E',
+                                                                       VCOMP_SIGC_I, VCOMP_SGZ_E);
+                       value_switch(VCOMP_SIGC_I, 'g', 'G', VCOMP_SIGC_G);
+                       value_switch(VCOMP_SIGC_G, 'c', 'C', VCOMP_SIGC_C);
+                       value_switch(VCOMP_SIGC_C, 'o', 'O', VCOMP_SIGC_O);
+                       value_switch(VCOMP_SIGC_O, 'm', 'M', VCOMP_SIGC_M);
+                       value_switch(VCOMP_SIGC_M, 'p', 'P', VCOMP_SIGC_P_FIN);
+                       comp_fin(VCOMP_SIGC_P_FIN, COMP_SIGCOMP);
+                       
+                       /* sergz*/
+                       value_switch(VCOMP_SGZ_E, 'r', 'R', VCOMP_SGZ_R);
+                       value_switch(VCOMP_SGZ_R, 'g', 'G', VCOMP_SGZ_G);
+                       value_switch(VCOMP_SGZ_G, 'z', 'Z', VCOMP_SGZ_Z_FIN);
+                       comp_fin(VCOMP_SGZ_Z_FIN, COMP_SERGZ);
+#endif
+                               
                                
                                
                        case URI_HEADERS:
@@ -893,6 +979,13 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
                case PM_eq:
                case PLR_L: /* lr */
                case PR2_R:  /* r2 */
+#ifdef USE_COMP
+               case PCOMP_C:
+               case PCOMP_O:
+               case PCOMP_M:
+               case PCOMP_P:
+               case PCOMP_eq:
+#endif
                        uri->params.s=s;
                        uri->params.len=p-s;
                        break;
@@ -925,6 +1018,22 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
                        uri->params.len=p-s;
                        param_set(b, v);
                        break;
+#ifdef USE_COMP
+               case VCOMP_S:
+               case VCOMP_SIGC_I:
+               case VCOMP_SIGC_G:
+               case VCOMP_SIGC_C:
+               case VCOMP_SIGC_O:
+               case VCOMP_SIGC_M:
+               case VCOMP_SGZ_E:
+               case VCOMP_SGZ_R:
+               case VCOMP_SGZ_G:
+                       /* unrecognized comp method, assume none */
+                       uri->params.s=s;
+                       uri->params.len=p-s;
+                       /* uri->comp=COMP_NONE ; */
+                       break;
+#endif
                /* fin value states */
                case VU_P_FIN:
                        uri->params.s=s;
@@ -950,6 +1059,20 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
                        param_set(b, v);
                        uri->proto=PROTO_SCTP;
                        break;
+#ifdef USE_COMP
+               case VCOMP_SIGC_P_FIN:
+                       uri->params.s=s;
+                       uri->params.len=p-s;
+                       /* param_set(b, v); */
+                       uri->comp=COMP_SIGCOMP;
+                       break;
+               case VCOMP_SGZ_Z_FIN:
+                       uri->params.s=s;
+                       uri->params.len=p-s;
+                       /* param_set(b, v); */
+                       uri->comp=COMP_SERGZ;
+                       break;
+#endif
                /* headers */
                case URI_HEADERS:
                        uri->headers.s=s;
@@ -1027,6 +1150,10 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
                        uri->maddr_val.len, ZSW(uri->maddr_val.s));
        DBG("   lr=<%.*s>\n", uri->lr.len, ZSW(uri->lr.s)); 
        DBG("   r2=<%.*s>\n", uri->r2.len, ZSW(uri->r2.s));
+#ifdef USE_COMP
+       DBG("   comp=%d\n", uri->comp);
+#endif
+
 #endif
        return 0;
        
index 25b6200..ec31de3 100644 (file)
@@ -49,6 +49,7 @@
  *  2004-03-31  fixed rport set instead of i bug (andrei)
  *  2005-03-02  if via has multiple bodies, and one of them is bad set
  *               also the first one as bad (andrei)
+ *  2006-02-24  added support for comp parameter parsing (see rfc3486) (andrei)
  */
 
 
@@ -106,9 +107,20 @@ enum {
        RECEIVED7,
        RPORT1, RPORT2, RPORT3,
        ALIAS1, ALIAS2, ALIAS3, ALIAS4,
+#ifdef USE_COMP
+       COMP1, COMP2, COMP3, 
+       /* values */
+       L_COMP_VALUE, F_COMP_VALUE,
+       V_COMP_S, V_SIGCOMP_I, V_SIGCOMP_G, V_SIGCOMP_C, V_SIGCOMP_O, V_SIGCOMP_M,
+       FIN_V_SIGCOMP_P,
+       V_SERGZ_E, V_SERGZ_R, V_SERGZ_G, FIN_V_SERGZ_Z,
+#endif
             /* fin states (227-...)*/
        FIN_HIDDEN = 230, FIN_TTL, FIN_BRANCH,
        FIN_MADDR, FIN_RECEIVED, FIN_RPORT, FIN_I, FIN_ALIAS
+#ifdef USE_COMP
+       , FIN_COMP
+#endif
             /*GEN_PARAM,
               PARAM_ERROR*/ /* declared in msg_parser.h*/
 };
@@ -124,12 +136,94 @@ enum {
 static /*inline*/ char* parse_via_param(char* p, char* end,
                                                                                unsigned char* pstate, 
                                                                        unsigned char* psaved_state,
-                                                                               struct via_param* param)
+                                                                               struct via_param* param,
+                                                                               struct via_body* vb)
 {
        char* tmp;
        register unsigned char state;
        unsigned char saved_state;
 
+#define value_case(c, C, oldstate, newstate, start_of_value) \
+                       case (c): \
+                       case (C): \
+                               switch(state){ \
+                                       case (oldstate): \
+                                               state=(newstate); \
+                                               if ((start_of_value))  param->value.s=tmp; \
+                                               break; \
+                                       default_value_cases \
+                               } \
+                               break
+
+#define value_case_double(c, C, oldstate1, newstate1, oldstate2, newstate2) \
+                       case (c): \
+                       case (C): \
+                               switch(state){ \
+                                       case (oldstate1): \
+                                               state=(newstate1); \
+                                               break; \
+                                       case (oldstate2): \
+                                               state=(newstate2); \
+                                               break; \
+                                       default_value_cases \
+                               } \
+                               break
+
+#define default_value_cases \
+                                       case F_VALUE: \
+                                               state=P_VALUE; \
+                                               param->value.s=tmp; \
+                                               break; \
+                                       case P_VALUE: \
+                                       case P_STRING: \
+                                               break; \
+                                       case F_LF: \
+                                       case F_CR:  \
+                                       case F_CRLF: \
+                                               state=END_OF_HEADER; \
+                                               goto end_via; \
+                                       default: \
+                                               switch(state){ \
+                                                       case F_COMP_VALUE: \
+                                                               comp_unexpected_char; \
+                                                               state=P_VALUE; \
+                                                               param->value.s=tmp; \
+                                                               break; \
+                                                       comp_states_cases \
+                                                       comp_fin_states_cases \
+                                                               comp_unexpected_char; \
+                                                               state=P_VALUE; \
+                                                               break; \
+                                                       default: \
+                                                               LOG(L_ERR, "ERROR: parse_via_param: invalid " \
+                                                                       "char <%c> in state %d\n", *tmp, state); \
+                                                               goto error; \
+                                               }
+
+#define comp_states_cases \
+                                       case V_COMP_S: \
+                                       case V_SIGCOMP_I: \
+                                       case V_SIGCOMP_G: \
+                                       case V_SIGCOMP_C: \
+                                       case V_SIGCOMP_O: \
+                                       case V_SIGCOMP_M: \
+                                       case V_SERGZ_E: \
+                                       case V_SERGZ_R: \
+                                       case V_SERGZ_G: 
+
+#define comp_fin_states_cases \
+                                       case FIN_V_SIGCOMP_P: \
+                                       case FIN_V_SERGZ_Z:
+
+
+/* if unrecognized/bad comp, don't return error, just ignore comp */
+#define comp_unexpected_char \
+                                                       LOG(L_ERR, "parse_via_param: bad/unrecognized" \
+                                                                       " comp method\n"); \
+                                                       vb->comp_no=0
+                                                               
+
+
        state=*pstate;
        saved_state=*psaved_state;
        param->type=PARAM_ERROR;
@@ -155,6 +249,13 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
                                                param->name.len=tmp-param->name.s;
                                                state=L_VALUE;
                                                goto find_value;
+#ifdef USE_COMP
+                                       case FIN_COMP:
+                                               param->type=state;
+                                               param->name.len=tmp-param->name.s;
+                                               state=L_COMP_VALUE;
+                                               goto find_value;
+#endif
                                        case F_PARAM:
                                                break;
                                        case F_LF:
@@ -193,6 +294,15 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
                                                saved_state=L_VALUE;
                                                state=F_LF;
                                                goto find_value;
+#ifdef USE_COMP
+                                       case FIN_COMP:
+                                               param->type=state;
+                                               param->name.len=tmp-param->name.s;
+                                               param->size=tmp-param->start; 
+                                               saved_state=L_COMP_VALUE;
+                                               state=F_LF;
+                                               goto find_value;
+#endif
                                        case F_PARAM:
                                                saved_state=state;
                                                state=F_LF;
@@ -236,6 +346,15 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
                                                saved_state=L_VALUE;
                                                state=F_CR;
                                                goto find_value;
+#ifdef USE_COMP
+                                       case FIN_COMP:
+                                               param->type=state;
+                                               param->name.len=tmp-param->name.s;
+                                               param->size=tmp-param->start; 
+                                               saved_state=L_COMP_VALUE;
+                                               state=F_LF;
+                                               goto find_value;
+#endif
                                        case F_PARAM:
                                                saved_state=state;
                                                state=F_CR;
@@ -267,6 +386,13 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
                                                param->name.len=tmp-param->name.s;
                                                state=F_VALUE;
                                                goto find_value;
+#ifdef USE_COMP
+                                       case FIN_COMP:
+                                               param->type=state;
+                                               param->name.len=tmp-param->name.s;
+                                               state=F_COMP_VALUE;
+                                               goto find_value;
+#endif
                                        case F_PARAM:
                                        case FIN_HIDDEN:
                                        case FIN_ALIAS:
@@ -300,6 +426,9 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
                                        case FIN_TTL:
                                        case FIN_RECEIVED:
                                        case FIN_I:
+#ifdef USE_COMP
+                                       case FIN_COMP:
+#endif
                                                LOG(L_ERR, "ERROR: parse_via: invalid char <%c> in"
                                                                " state %d\n", *tmp, state);
                                                goto error;
@@ -330,6 +459,9 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
                                        case FIN_TTL:
                                        case FIN_RECEIVED:
                                        case FIN_I:
+#ifdef USE_COMP
+                                       case FIN_COMP:
+#endif
                                                LOG(L_ERR, "ERROR: parse_via_param: new via found" 
                                                                "(',') when '=' expected (state %d=)\n",
                                                                state);
@@ -539,6 +671,11 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
                                                state=MADDR1;
                                                param->name.s=tmp;
                                                break;
+#ifdef USE_COMP
+                                       case COMP2:
+                                               state=COMP3;
+                                               break;
+#endif
                                        case GEN_PARAM:
                                                break;
                                        case F_CR:
@@ -608,7 +745,11 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
                        case 'C':
                                switch(state){
                                        case F_PARAM:
+#ifdef USE_COMP
+                                               state=COMP1;
+#else
                                                state=GEN_PARAM;
+#endif
                                                param->name.s=tmp;
                                                break;
                                        case RECEIVED2:
@@ -677,6 +818,11 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
                                        case RECEIVED1:
                                                state=RPORT1;
                                                break;
+#ifdef USE_COMP
+                                       case COMP3:
+                                               state=FIN_COMP;
+                                               break;
+#endif
                                        case F_CR:
                                        case F_LF:
                                        case F_CRLF:
@@ -696,6 +842,11 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
                                        case RPORT1:
                                                state=RPORT2;
                                                break;
+#ifdef USE_COMP
+                                       case COMP1:
+                                               state=COMP2;
+                                               break;
+#endif
                                        case F_CR:
                                        case F_LF:
                                        case F_CRLF:
@@ -762,6 +913,26 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
                                                state=L_PARAM;
                                                param->value.len=tmp-param->value.s;
                                                goto endofvalue;
+#ifdef USE_COMP
+                                       case L_COMP_VALUE:
+                                       case F_COMP_VALUE:
+                                               break; /* eat space */
+                                       case FIN_V_SIGCOMP_P:
+                                               state=L_PARAM;
+                                               param->value.len=tmp-param->value.s;
+                                               vb->comp_no=COMP_SIGCOMP;
+                                               goto endofvalue;
+                                       case FIN_V_SERGZ_Z:
+                                               state=L_PARAM;
+                                               param->value.len=tmp-param->value.s;
+                                               vb->comp_no=COMP_SIGCOMP;
+                                               goto endofvalue;
+                                       comp_states_cases
+                                               state=L_PARAM;
+                                               param->value.len=tmp-param->value.s;
+                                               comp_unexpected_char;
+                                               goto endofvalue;
+#endif
                                        case P_STRING:
                                                break;
                                        case F_CR:
@@ -779,6 +950,10 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
                                switch(state){
                                        case L_VALUE:
                                        case F_VALUE: /*eat space*/
+#ifdef USE_COMP
+                                       case L_COMP_VALUE:
+                                       case F_COMP_VALUE:
+#endif
                                        case P_STRING:
                                                saved_state=state;
                                                param->size=tmp-param->start;
@@ -789,6 +964,26 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
                                                state=F_LF;
                                                param->value.len=tmp-param->value.s;
                                                goto endofvalue;
+#ifdef USE_COMP
+                                       case FIN_V_SIGCOMP_P:
+                                               saved_state=L_PARAM;
+                                               state=F_LF;
+                                               param->value.len=tmp-param->value.s;
+                                               vb->comp_no=COMP_SIGCOMP;
+                                               goto endofvalue;
+                                       case FIN_V_SERGZ_Z:
+                                               saved_state=L_PARAM;
+                                               state=F_LF;
+                                               param->value.len=tmp-param->value.s;
+                                               vb->comp_no=COMP_SIGCOMP;
+                                               goto endofvalue;
+                                       comp_states_cases
+                                               saved_state=L_PARAM;
+                                               state=F_LF;
+                                               param->value.len=tmp-param->value.s;
+                                               comp_unexpected_char;
+                                               goto endofvalue;
+#endif
                                        case F_LF:
                                        case F_CRLF:
                                                state=END_OF_HEADER;
@@ -806,6 +1001,10 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
                                switch(state){
                                        case L_VALUE:
                                        case F_VALUE: /*eat space*/
+#ifdef USE_COMP
+                                       case L_COMP_VALUE:
+                                       case F_COMP_VALUE:
+#endif
                                        case P_STRING:
                                                saved_state=state;
                                                param->size=tmp-param->start;
@@ -816,6 +1015,26 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
                                                saved_state=L_PARAM;
                                                state=F_CR;
                                                goto endofvalue;
+#ifdef USE_COMP
+                                       case FIN_V_SIGCOMP_P:
+                                               saved_state=L_PARAM;
+                                               state=F_CR;
+                                               param->value.len=tmp-param->value.s;
+                                               vb->comp_no=COMP_SIGCOMP;
+                                               goto endofvalue;
+                                       case FIN_V_SERGZ_Z:
+                                               saved_state=L_PARAM;
+                                               state=F_CR;
+                                               param->value.len=tmp-param->value.s;
+                                               vb->comp_no=COMP_SIGCOMP;
+                                               goto endofvalue;
+                                       comp_states_cases
+                                               saved_state=L_PARAM;
+                                               state=F_CR;
+                                               param->value.len=tmp-param->value.s;
+                                               comp_unexpected_char;
+                                               goto endofvalue;
+#endif
                                        case F_LF:
                                        case F_CR:
                                        case F_CRLF:
@@ -833,6 +1052,13 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
                                        case L_VALUE:
                                                state=F_VALUE;
                                                break;
+#ifdef USE_COMP
+                                       case L_COMP_VALUE:
+                                               state=F_COMP_VALUE;
+                                               break;
+                                       /* '=' in any other COMP value state is an error,
+                                        * and it will be catched by the default branch */
+#endif
                                        case P_STRING:
                                                break;
                                        case F_LF:
@@ -863,6 +1089,35 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
                                        case F_CRLF:
                                                state=END_OF_HEADER;
                                                goto end_via;
+#ifdef USE_COMP
+                                       case L_COMP_VALUE:
+                                               comp_unexpected_char;
+                                               /* we want to contine with no comp */
+                                               state=F_PARAM;
+                                               param->value.len=0;
+                                               param->value.s=0;
+                                               goto endofvalue;
+                                       case F_COMP_VALUE:
+                                               comp_unexpected_char;
+                                               param->value.len=0;
+                                               state=F_PARAM;
+                                               goto endofvalue;
+                                       comp_states_cases
+                                               comp_unexpected_char;
+                                               param->value.len=tmp-param->value.s;
+                                               state=F_PARAM;
+                                               goto endofvalue;
+                                       case FIN_V_SIGCOMP_P:
+                                               vb->comp_no=COMP_SIGCOMP;
+                                               param->value.len=tmp-param->value.s;
+                                               state=F_PARAM;
+                                               goto endofvalue;
+                                       case FIN_V_SERGZ_Z:
+                                               vb->comp_no=COMP_SIGCOMP;
+                                               param->value.len=tmp-param->value.s;
+                                               state=F_PARAM;
+                                               goto endofvalue;
+#endif
                                        case L_VALUE:
                                                if (param->type==FIN_RPORT){
                                                        param->value.len=0;
@@ -889,6 +1144,35 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
                                        case F_CRLF:
                                                state=END_OF_HEADER;
                                                goto end_via;
+#ifdef USE_COMP
+                                       case L_COMP_VALUE:
+                                               comp_unexpected_char;
+                                               /* we want to contine with no comp */
+                                               state=F_VIA;
+                                               param->value.len=0;
+                                               param->value.s=0;
+                                               goto endofvalue;
+                                       case F_COMP_VALUE:
+                                               comp_unexpected_char;
+                                               param->value.len=0;
+                                               state=F_VIA;
+                                               goto endofvalue;
+                                       comp_states_cases
+                                               comp_unexpected_char;
+                                               param->value.len=tmp-param->value.s;
+                                               state=F_VIA;
+                                               goto endofvalue;
+                                       case FIN_V_SIGCOMP_P:
+                                               vb->comp_no=COMP_SIGCOMP;
+                                               param->value.len=tmp-param->value.s;
+                                               state=F_VIA;
+                                               goto endofvalue;
+                                       case FIN_V_SERGZ_Z:
+                                               vb->comp_no=COMP_SIGCOMP;
+                                               param->value.len=tmp-param->value.s;
+                                               state=F_VIA;
+                                               goto endofvalue;
+#endif
                                        case L_VALUE:
                                                if (param->type==FIN_RPORT){
                                                        param->value.len=0;
@@ -924,6 +1208,21 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
                                                goto error;
                                }
                                break;
+#ifdef USE_COMP
+                       value_case('s', 'S', F_COMP_VALUE, V_COMP_S, 1);
+                       value_case('i', 'I', V_COMP_S, V_SIGCOMP_I, 0);
+                       value_case_double('g', 'G', V_SIGCOMP_I, V_SIGCOMP_G,
+                                                           V_SERGZ_R,   V_SERGZ_G);
+                       value_case('c', 'C', V_SIGCOMP_G, V_SIGCOMP_C, 0);
+                       value_case('o', 'O', V_SIGCOMP_C, V_SIGCOMP_O, 0);
+                       value_case('m', 'M', V_SIGCOMP_O, V_SIGCOMP_M, 0);
+                       value_case('p', 'P', V_SIGCOMP_M, FIN_V_SIGCOMP_P, 0);
+                       
+                       value_case('e', 'E', V_COMP_S, V_SERGZ_E, 0);
+                       value_case('r', 'R', V_SERGZ_E, V_SERGZ_R, 0);
+                       value_case('z', 'Z', V_SERGZ_G, FIN_V_SERGZ_Z, 0);
+#endif /* USE_COMP */
+                               
                        default:
                                switch(state){
                                        case F_VALUE:
@@ -939,9 +1238,28 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
                                                state=END_OF_HEADER;
                                                goto end_via;
                                        default:
+#ifdef USE_COMP
+                                               switch(state){
+                                                       case F_COMP_VALUE:
+                                                               comp_unexpected_char;
+                                                               state=P_VALUE;
+                                                               param->value.s=tmp;
+                                                               break;
+                                                       comp_states_cases
+                                                       comp_fin_states_cases
+                                                               comp_unexpected_char;
+                                                               state=P_VALUE;
+                                                               break;
+                                                       default:
+                                                               LOG(L_ERR, "ERROR: parse_via_param: invalid "
+                                                                       "char <%c> in state %d\n", *tmp, state);
+                                                               goto error;
+                                               }
+#else
                                                LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
                                                                " in state %d\n", *tmp, state);
                                                goto error;
+#endif /* USE_COMP */
                                }
                }
        } /* for2 tmp*/
@@ -1830,7 +2148,7 @@ parse_again:
                                                memset(param,0, sizeof(struct via_param));
                                                param->start=param_start;
                                                tmp=parse_via_param(tmp, end, &state, &saved_state,
-                                                                                       param);
+                                                                                       param, vb);
 
                                                switch(state){
                                                        case F_PARAM:
@@ -1879,6 +2197,28 @@ parse_again:
                                                        case PARAM_ALIAS:
                                                                vb->alias=param;
                                                                break;
+#ifdef USE_COMP
+                                                       case PARAM_COMP:
+                                                               vb->comp=param;
+                                                               /*  moved comp value parsing in via_param */
+                                                               /*
+                                                               if  ((param->value.len==SIGCOMP_NAME_LEN) &&
+                                                                       (strncasecmp(param->value.s, SIGCOMP_NAME,
+                                                                                               SIGCOMP_NAME_LEN)==0)){
+                                                                       vb->comp_no=COMP_SIGCOMP;
+                                                               }else if ((param->value.len==SERGZ_NAME_LEN) &&
+                                                                               (strncasecmp(param->value.s,
+                                                                                                       SERGZ_NAME,
+                                                                                                       SERGZ_NAME_LEN)==0)){
+                                                                       vb->comp_no=COMP_SERGZ;
+                                                               }else{
+                                                                       LOG(L_ERR, "ERROR: parse_via: unrecognized"
+                                                                               " compression method in comp=%.*s\n",
+                                                                               param->value.len, param->value.s);
+                                                               }
+                                                               */
+                                                               break;
+#endif
                                                }
                                                
                                                if (state==END_OF_HEADER){
index a6ddecd..e0164e7 100644 (file)
@@ -32,6 +32,7 @@
  *               by tcp to identify the sending socket, by andrei
  *  2003-01-27  added a new member (start) to via_param, by andrei
  *  2003-10-27  added alias to via && PARAM_ALIAS (andrei)
+ *  2006-02-24  added comp/PARAM_COMP support (andrei)
  */
 
 
 enum {
        PARAM_HIDDEN=230, PARAM_TTL, PARAM_BRANCH, 
        PARAM_MADDR, PARAM_RECEIVED, PARAM_RPORT, PARAM_I, PARAM_ALIAS,
-       GEN_PARAM,
+#ifdef USE_COMP
+       PARAM_COMP,
+#endif
+       GEN_PARAM=253,
        PARAM_ERROR
 };
 
@@ -74,9 +78,12 @@ struct via_body {
        str name;
        str version;   
        str transport;
-       int proto; /* transport */
        str host;
-       int port;
+       short proto; /* transport */
+       unsigned short port;
+#ifdef USE_COMP
+       short comp_no;
+#endif
        str port_str;
        str params;
        str comment;
@@ -91,6 +98,9 @@ struct via_body {
        struct via_param* rport;
        struct via_param* i;
        struct via_param* alias; /* alias see draft-ietf-sip-connect-reuse-00 */
+#ifdef USE_COMP
+       struct via_param* comp; /* see rfc3486 */
+#endif
        struct via_body* next; /* pointer to next via body string if
                                  compact via or null */
 };
index c27fb7f..f8ea816 100644 (file)
--- a/version.h
+++ b/version.h
 #endif
 
 
+#ifdef USE_COMP
+#define USE_COMP_STR ", USE_COMP"
+#else
+#define USE_COMP_STR ""
+#endif
+
+
 #define SER_COMPILE_FLAGS \
        STATS_STR EXTRA_DEBUG_STR USE_IPV6_STR USE_TCP_STR USE_TLS_STR \
        DISABLE_NAGLE_STR USE_MCAST_STR NO_DEBUG_STR NO_LOG_STR DNS_IP_HACK_STR \
        USE_SHM_MEM_STR DBG_QM_MALLOC_STR DBG_F_MALLOC_STR DEBUG_DMALLOC_STR \
        TIMER_DEBUG_STR \
        FAST_LOCK_STR NOSMP_STR USE_PTHREAD_MUTEX_STR USE_POSIX_SEM_STR \
-       USE_SYSV_SEM_STR
+       USE_SYSV_SEM_STR USE_COMP_STR
 
 
 #endif