Просмотр исходного кода

core: Changed WS from being a flag on a TCP/TLS connection to a protocol in its own right

- Also added ;transport=ws parameter parsing for URIs
Peter Dunkley 13 лет назад
Родитель
Сommit
8393efff31
12 измененных файлов с 88 добавлено и 58 удалено
  1. 2 0
      cfg.lex
  2. 15 9
      cfg.y
  3. 1 0
      forward.c
  4. 32 25
      forward.h
  5. 1 1
      ip_addr.h
  6. 2 0
      msg_translator.c
  7. 22 1
      parser/parse_uri.c
  8. 6 6
      parser/parse_via.c
  9. 0 9
      route.c
  10. 1 0
      socket_info.c
  11. 0 1
      tcp_conn.h
  12. 6 6
      tcp_read.c

+ 2 - 0
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();

+ 15 - 9
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;

+ 1 - 0
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

+ 32 - 25
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");

+ 1 - 1
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

+ 2 - 0
msg_translator.c

@@ -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;

+ 22 - 1
parser/parse_uri.c

@@ -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;
 	}

+ 6 - 6
parser/parse_via.c

@@ -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;

+ 0 - 9
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;

+ 1 - 0
socket_info.c

@@ -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

+ 0 - 1
tcp_conn.h

@@ -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

+ 6 - 6
tcp_read.c

@@ -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