core: Changed WS from being a flag on a TCP/TLS connection to a protocol in its own...
authorPeter Dunkley <peter.dunkley@crocodile-rcs.com>
Fri, 29 Jun 2012 16:44:15 +0000 (17:44 +0100)
committerPeter Dunkley <peter.dunkley@crocodile-rcs.com>
Fri, 29 Jun 2012 16:44:15 +0000 (17:44 +0100)
- Also added ;transport=ws parameter parsing for URIs

12 files changed:
cfg.lex
cfg.y
forward.c
forward.h
ip_addr.h
msg_translator.c
parser/parse_uri.c
parser/parse_via.c
route.c
socket_info.c
tcp_conn.h
tcp_read.c

diff --git a/cfg.lex b/cfg.lex
index b1a0f29..76eb2f1 100644 (file)
--- a/cfg.lex
+++ b/cfg.lex
@@ -526,6 +526,7 @@ TCP                 "tcp"|"TCP"
 TLS                    "tls"|"TLS"
 SCTP           "sctp"|"SCTP"
 WS             "ws"|"WS"
+WSS            "wss"|"WSS"
 INET           "inet"|"INET"
 INET6          "inet6"|"INET6"
 SSLv23                 "sslv23"|"SSLv23"|"SSLV23"
@@ -1165,6 +1166,7 @@ IMPORTFILE      "import_file"
 <INITIAL>{TLS}                 { count(); return TLS; }
 <INITIAL>{SCTP}                        { count(); return SCTP; }
 <INITIAL>{WS}                  { count(); return WS; }
+<INITIAL>{WSS}                 { count(); return WSS; }
 <INITIAL>{INET}                        { count(); yylval.intval=AF_INET;
                                                        yy_number_str=yytext; return NUMBER; }
 <INITIAL>{INET6}               { count();
diff --git a/cfg.y b/cfg.y
index 8fdccdc..e094223 100644 (file)
--- a/cfg.y
+++ b/cfg.y
@@ -392,6 +392,7 @@ extern char *finame;
 %token TLS
 %token SCTP
 %token WS
+%token WSS
 
 /* config vars. */
 %token DEBUG_V
@@ -657,7 +658,7 @@ extern char *finame;
 %type <sockid>  id_lst
 %type <sockid>  phostport
 %type <sockid>  listen_phostport
-%type <intval> proto port
+%type <intval> proto eqproto port
 %type <intval> equalop strop cmpop rve_cmpop rve_equalop
 %type <intval> uri_type
 %type <attr> attr_id
@@ -772,6 +773,15 @@ proto:
        | SCTP  { $$=PROTO_SCTP; }
        | STAR  { $$=0; }
        ;
+eqproto:
+       UDP     { $$=PROTO_UDP; }
+       | TCP   { $$=PROTO_TCP; }
+       | TLS   { $$=PROTO_TLS; }
+       | SCTP  { $$=PROTO_SCTP; }
+       | WS    { $$=PROTO_WS; }
+       | WSS   { $$=PROTO_WSS; }
+       | STAR  { $$=0; }
+       ;
 port:
        NUMBER  { $$=$1; }
        | STAR  { $$=0; }
@@ -2202,22 +2212,18 @@ exp_elem:
        | eint_op cmpop error   { $$=0; yyerror("number expected"); }
        | eint_op equalop error { $$=0; yyerror("number expected"); }
        | eint_op error { $$=0; yyerror("==, !=, <,>, >= or <=  expected"); }
-       | PROTO equalop proto %prec EQUAL_T
+       | PROTO equalop eqproto %prec EQUAL_T
                { $$=mk_elem($2, PROTO_O, 0, NUMBER_ST, (void*)$3 ); }
-       | PROTO equalop WS %prec EQUAL_T
-               { $$=mk_elem($2, PROTO_O, 0, WEBSOCKET_ST, (void *)PROTO_WS ); }
        | PROTO equalop rval_expr %prec EQUAL_T
                { $$=mk_elem($2, PROTO_O, 0, RVE_ST, $3 ); }
        | PROTO equalop error
-               { $$=0; yyerror("protocol expected (udp, tcp, tls, sctp, or ws)"); }
-       | SNDPROTO equalop proto %prec EQUAL_T
+               { $$=0; yyerror("protocol expected (udp, tcp, tls, sctp, ws, or wss)"); }
+       | SNDPROTO equalop eqproto %prec EQUAL_T
                { $$=mk_elem($2, SNDPROTO_O, 0, NUMBER_ST, (void*)$3 ); }
-       | SNDPROTO equalop WS %prec EQUAL_T
-               { $$=mk_elem($2, SNDPROTO_O, 0, WEBSOCKET_ST, (void *)PROTO_WS ); }
        | SNDPROTO equalop rval_expr %prec EQUAL_T
                { $$=mk_elem($2, SNDPROTO_O, 0, RVE_ST, $3 ); }
        | SNDPROTO equalop error
-               { $$=0; yyerror("protocol expected (udp, tcp, tls, sctp, ws)"); }
+               { $$=0; yyerror("protocol expected (udp, tcp, tls, sctp, ws, or wss)"); }
        | eip_op strop ipnet %prec EQUAL_T { $$=mk_elem($2, $1, 0, NET_ST, $3); }
        | eip_op strop rval_expr %prec EQUAL_T {
                        s_tmp.s=0;
index d3ecb00..89fe18f 100644 (file)
--- a/forward.c
+++ b/forward.c
@@ -319,6 +319,7 @@ not_forced:
         * eg: ipv4 -> ipv6 or ipv6 -> ipv4) */
        switch(proto){
 #ifdef USE_TCP
+               case PROTO_WS:
                case PROTO_TCP:
                /* on tcp just use the "main address", we don't really now the
                 * sending address (we can find it out, but we'll need also to see
index 8b91c15..02cfd12 100644 (file)
--- a/forward.h
+++ b/forward.h
@@ -140,11 +140,11 @@ static inline int msg_send(struct dest_info* dst, char* buf, int len)
        sr_event_exec(SREV_NET_DATA_OUT, (void*)&outb);
 
 #ifdef USE_TCP
-       if (dst->proto == PROTO_TCP
+       if (unlikely((dst->proto == PROTO_WS
 #ifdef USE_TLS
-               || dst->proto == PROTO_TLS
+               || dst->proto == PROTO_WSS
 #endif
-       ) {
+       ) && sr_event_enabled(SREV_TCP_WS_FRAME_OUT))) {
                if (unlikely(dst->send_flags.f & SND_F_FORCE_SOCKET
                                && dst->send_sock)) {
                        local_addr = dst->send_sock->su;
@@ -152,29 +152,24 @@ static inline int msg_send(struct dest_info* dst, char* buf, int len)
                        from = &local_addr;
                }
 
-               if (unlikely(sr_event_enabled(SREV_TCP_WS_FRAME_OUT))) {
-                       port = su_getport(&dst->to);
-                       if (likely(port)) {
-                               su2ip_addr(&ip, &dst->to);
-                               con = tcpconn_get(dst->id, &ip, port, from, 0);
-                       }
-                       else if (likely(dst->id))
-                               con = tcpconn_get(dst->id, 0, 0, 0, 0);
-                       else {
-                               LM_CRIT("BUG: msg_send called with null_id & to\n");
-                               return -1;
-                       }
-
-                       if (con && con->flags & F_CONN_WS)
-                       {
-                               memset(&wsev, 0, sizeof(ws_event_info_t));
-                               wsev.type = SREV_TCP_WS_FRAME_OUT;
-                               wsev.buf = outb.s;
-                               wsev.len = outb.len;
-                               wsev.id = con->id;
-                               return sr_event_exec(SREV_TCP_WS_FRAME_OUT, (void *) &wsev);
-                       }
+               port = su_getport(&dst->to);
+               if (likely(port)) {
+                       su2ip_addr(&ip, &dst->to);
+                       con = tcpconn_get(dst->id, &ip, port, from, 0);
                }
+               else if (likely(dst->id))
+                       con = tcpconn_get(dst->id, 0, 0, 0, 0);
+               else {
+                       LM_CRIT("BUG: msg_send called with null_id & to\n");
+                       return -1;
+               }
+
+               memset(&wsev, 0, sizeof(ws_event_info_t));
+               wsev.type = SREV_TCP_WS_FRAME_OUT;
+               wsev.buf = outb.s;
+               wsev.len = outb.len;
+               wsev.id = con->id;
+               return sr_event_exec(SREV_TCP_WS_FRAME_OUT, (void *) &wsev);
        }
 #endif
 
@@ -203,6 +198,12 @@ static inline int msg_send(struct dest_info* dst, char* buf, int len)
                                        " support is disabled\n");
                        goto error;
                }else{
+                       if (unlikely((dst->send_flags.f & SND_F_FORCE_SOCKET) &&
+                                               dst->send_sock)) {
+                               local_addr=dst->send_sock->su;
+                               su_setport(&local_addr, 0); /* any local port will do */
+                               from=&local_addr;
+                       }
                        if (unlikely(tcp_send(dst, from, outb.s, outb.len)<0)){
                                STATS_TX_DROPS;
                                LOG(L_ERR, "msg_send: ERROR: tcp_send failed\n");
@@ -218,6 +219,12 @@ static inline int msg_send(struct dest_info* dst, char* buf, int len)
                                        " support is disabled\n");
                        goto error;
                }else{
+                       if (unlikely((dst->send_flags.f & SND_F_FORCE_SOCKET) &&
+                                               dst->send_sock)) {
+                               local_addr=dst->send_sock->su;
+                               su_setport(&local_addr, 0); /* any local port will do */
+                               from=&local_addr;
+                       }
                        if (unlikely(tcp_send(dst, from, outb.s, outb.len)<0)){
                                STATS_TX_DROPS;
                                LOG(L_ERR, "msg_send: ERROR: tcp_send failed\n");
index 3e23633..115e4b4 100644 (file)
--- a/ip_addr.h
+++ b/ip_addr.h
@@ -52,7 +52,7 @@
 
 #include "dprint.h"
 
-enum sip_protos { PROTO_NONE, PROTO_UDP, PROTO_TCP, PROTO_TLS, PROTO_SCTP, PROTO_OTHER, PROTO_WS /* Deliberately after PROTO_(OTHER|LAST) */ };
+enum sip_protos { PROTO_NONE, PROTO_UDP, PROTO_TCP, PROTO_TLS, PROTO_SCTP, PROTO_WS, PROTO_WSS, PROTO_OTHER };
 #define PROTO_LAST PROTO_OTHER
 
 #ifdef USE_COMP
index f45cb66..e4f0d74 100644 (file)
@@ -2394,6 +2394,8 @@ char* via_builder( unsigned int *len,
                memcpy(line_buf+MY_VIA_LEN-4, "TLS ", 4);
        }else if (send_info->proto==PROTO_SCTP){
                memcpy(line_buf+MY_VIA_LEN-4, "SCTP ", 5);
+       }else if (send_info->proto==PROTO_WS){
+               memcpy(line_buf+MY_VIA_LEN-4, "WS ", 2);
        }else{
                LOG(L_CRIT, "BUG: via_builder: unknown proto %d\n", send_info->proto);
                return 0;
index a244cf2..bb31872 100644 (file)
@@ -106,7 +106,9 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
                                        /* tls */
                                              VTLS_L, VTLS_S_FIN,
                                        /* sctp */
-                                       VS_S, VS_C, VS_T, VS_P_FIN
+                                       VS_S, VS_C, VS_T, VS_P_FIN,
+                                       /* ws */
+                                       VW_W, VW_S_FIN
        };
        register enum states state;
        char* s;
@@ -701,6 +703,11 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
                                                v=p;
                                                state=VS_S;
                                                break;
+                                       case 'w':
+                                       case 'W':
+                                               v=p;
+                                               state=VW_W;
+                                               break;
                                        default:
                                                v=p;
                                                state=URI_VAL_P;
@@ -728,6 +735,9 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
                        value_switch(VS_C, 't', 'T', VS_T);
                        value_switch(VS_T, 'p', 'P', VS_P_FIN);
                        transport_fin(VS_P_FIN, PROTO_SCTP);
+                       /* ws */
+                       value_switch(VW_W, 's', 'S', VW_S_FIN);
+                       transport_fin(VW_S_FIN, PROTO_WS);
                        
                        /* ttl */
                        param_switch(PTTL_T2,  'l', 'L', PTTL_L);
@@ -1094,6 +1104,7 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
                case VS_S:
                case VS_C:
                case VS_T:
+               case VW_W:
                        uri->params.s=s;
                        uri->params.len=p-s;
                        param_set(b, v);
@@ -1139,6 +1150,12 @@ int parse_uri(char* buf, int len, struct sip_uri* uri)
                        param_set(b, v);
                        uri->proto=PROTO_SCTP;
                        break;
+               case VW_S_FIN:
+                       uri->params.s=s;
+                       uri->params.len=p-s;
+                       param_set(b, v);
+                       uri->proto=PROTO_WS;
+                       break;
 #ifdef USE_COMP
                case VCOMP_SIGC_P_FIN:
                        uri->params.s=s;
@@ -1393,6 +1410,7 @@ static str        s_udp  = STR_STATIC_INIT("udp");
 static str     s_tcp  = STR_STATIC_INIT("tcp");
 static str     s_tls  = STR_STATIC_INIT("tls");
 static str     s_sctp = STR_STATIC_INIT("sctp");
+static str     s_ws   = STR_STATIC_INIT("ws");
 
 inline void proto_type_to_str(unsigned short type, str *s) {
        switch (type) {
@@ -1408,6 +1426,9 @@ inline void proto_type_to_str(unsigned short type, str *s) {
        case PROTO_SCTP:
                *s = s_sctp;
                break;
+       case PROTO_WS:
+               *s = s_ws;
+               break;
        default:
                *s = s_null;
        }
index 69756bc..0f6c930 100644 (file)
@@ -1374,13 +1374,13 @@ parse_again:
                                        case WS_WSS2:
                                                /* finished proto parsing */
                                                vb->transport.len=tmp-vb->transport.s;
-                                               vb->proto=PROTO_TCP;
+                                               vb->proto=PROTO_WS;
                                                state=F_HOST; /* start looking for host*/
                                                goto main_via;
                                        case FIN_WSS:
                                                /* finished proto parsing */
                                                vb->transport.len=tmp-vb->transport.s;
-                                               vb->proto=PROTO_TLS;
+                                               vb->proto=PROTO_WSS;
                                                state=F_HOST; /* start looking for host*/
                                                goto main_via;
                                        case OTHER_PROTO:
@@ -1460,14 +1460,14 @@ parse_again:
                                        case WS_WSS2:
                                                /* finished proto parsing */
                                                vb->transport.len=tmp-vb->transport.s;
-                                               vb->proto=PROTO_TCP;
+                                               vb->proto=PROTO_WS;
                                                state=F_LF;
                                                saved_state=F_HOST; /* start looking for host*/
                                                goto main_via;
                                        case FIN_WSS:
                                                /* finished proto parsing */
                                                vb->transport.len=tmp-vb->transport.s;
-                                               vb->proto=PROTO_TLS;
+                                               vb->proto=PROTO_WSS;
                                                state=F_LF;
                                                saved_state=F_HOST; /* start looking for host*/
                                                goto main_via;
@@ -1552,13 +1552,13 @@ parse_again:
                                                goto main_via;
                                        case WS_WSS2:
                                                vb->transport.len=tmp-vb->transport.s;
-                                               vb->proto=PROTO_TCP;
+                                               vb->proto=PROTO_WS;
                                                state=F_CR;
                                                saved_state=F_HOST;
                                                goto main_via;
                                        case FIN_WSS:
                                                vb->transport.len=tmp-vb->transport.s;
-                                               vb->proto=PROTO_TLS;
+                                               vb->proto=PROTO_WSS;
                                                state=F_CR;
                                                saved_state=F_HOST;
                                                goto main_via;
diff --git a/route.c b/route.c
index ca357d3..7990cfd 100644 (file)
--- a/route.c
+++ b/route.c
@@ -1231,7 +1231,6 @@ inline static int comp_num(int op, long left, int rtype, union exp_op* r,
        pv_value_t pval;
        avp_t* avp;
        int right;
-       struct tcp_connection *con;
 
        if (unlikely(op==NO_OP)) return !(!left);
        switch(rtype){
@@ -1261,14 +1260,6 @@ inline static int comp_num(int op, long left, int rtype, union exp_op* r,
                                return (op == DIFF_OP); /* not found or invalid type */
                        }
                        break;
-               case WEBSOCKET_ST:
-                       if ((con = tcpconn_get(msg->rcv.proto_reserved1, 0, 0, 0, 0)) != NULL) {
-                               if (con->flags & F_CONN_WS)
-                                       left = PROTO_WS;
-                       }
-                       right = r->numval;
-                       break;
-
                default:
                        LOG(L_CRIT, "BUG: comp_num: Invalid right operand (%d)\n", rtype);
                        return E_BUG;
index 1ccddfd..ad6fe9b 100644 (file)
@@ -476,6 +476,7 @@ struct socket_info** get_sock_info_list(unsigned short proto)
                        return &udp_listen;
                        break;
                case PROTO_TCP:
+               case PROTO_WS:
 #ifdef USE_TCP
                        return &tcp_listen;
 #endif
index ec7c44f..3fb4d7c 100644 (file)
@@ -75,7 +75,6 @@
 #define F_CONN_WANTS_RD  4096  /* conn. should be watched for READ */
 #define F_CONN_WANTS_WR  8192  /* conn. should be watched for WRITE */
 #define F_CONN_PASSIVE  16384 /* conn. created via accept() and not connect()*/
-#define F_CONN_WS      32768 /* conn. is a websocket */
 
 #ifndef NO_READ_HTTP11
 #define READ_HTTP11
index b524727..1c80c19 100644 (file)
@@ -1025,7 +1025,7 @@ static int tcp_read_ws(struct tcp_connection *c, int* read_flags)
 
        r=&c->req;
 #ifdef USE_TLS
-       if (unlikely(c->type == PROTO_TLS))
+       if (unlikely(c->type == PROTO_WSS))
                bytes = tls_read(c, read_flags);
        else
 #endif
@@ -1168,7 +1168,7 @@ int receive_tcp_msg(char* tcpbuf, unsigned int len,
                        return msrp_process_msg(tcpbuf, len, rcv_info, con);
 #endif
 #ifdef READ_WS
-               if(unlikely(con->flags & F_CONN_WS))
+               if(unlikely(con->type == PROTO_WS || con->type == PROTO_WSS))
                        return ws_process_msg(tcpbuf, len, rcv_info, con);
 #endif
 
@@ -1216,7 +1216,7 @@ int receive_tcp_msg(char* tcpbuf, unsigned int len,
                return msrp_process_msg(buf, len, rcv_info, con);
 #endif
 #ifdef READ_WS
-       if(unlikely(con->flags & F_CONN_WS))
+       if(unlikely(con->type == PROTO_WS || con->type == PROTO_WSS))
                return ws_process_msg(buf, len, rcv_info, con);
 #endif
        return receive_msg(buf, len, rcv_info);
@@ -1226,7 +1226,7 @@ int receive_tcp_msg(char* tcpbuf, unsigned int len,
                return msrp_process_msg(tcpbuf, len, rcv_info, con);
 #endif
 #ifdef READ_WS
-       if(unlikely(con->flags & F_CONN_WS))
+       if(unlikely(con->type == PROTO_WS || con->type == PROTO_WSS))
                return ws_process_msg(tcpbuf, len, rcv_info, con);
 #endif
        return receive_msg(tcpbuf, len, rcv_info);
@@ -1252,7 +1252,7 @@ int tcp_read_req(struct tcp_connection* con, int* bytes_read, int* read_flags)
 again:
                if (likely(req->error==TCP_REQ_OK)){
 #ifdef READ_WS
-                       if (unlikely(con->flags&F_CONN_WS))
+                       if (unlikely(con->type == PROTO_WS || con->type == PROTO_WSS))
                                bytes=tcp_read_ws(con, read_flags);
                        else
 #endif
@@ -1372,7 +1372,7 @@ again:
                        }else
 #endif
 #ifdef READ_WS
-                       if (unlikely(con->flags&F_CONN_WS)){
+                       if (unlikely(con->type == PROTO_WS || con->type == PROTO_WSS)){
                                ret = receive_tcp_msg(req->start, req->parsed-req->start,
                                                                        &con->rcv, con);
                        }else