Browse code

everything: shotgun attempt to put PROTO_WS and PROTO_WSS across core and in modules I use

- Bound to have missed something and lots of testing required.

Peter Dunkley authored on 29/06/2012 23:01:07
Showing 13 changed files
... ...
@@ -286,7 +286,9 @@ struct socket_info* get_send_socket2(struct socket_info* force_send_socket,
286 286
 		   except tcp_main(), see close_extra_socks() */
287 287
 		if (likely((force_send_socket->socket!=-1 ||
288 288
 						force_send_socket->proto==PROTO_TCP ||
289
-						force_send_socket->proto==PROTO_TLS) &&
289
+						force_send_socket->proto==PROTO_TLS ||
290
+						force_send_socket->proto==PROTO_WS  ||
291
+						force_send_socket->proto==PROTO_WSS) &&
290 292
 					!(force_send_socket->flags & SI_IS_MCAST)))
291 293
 				return force_send_socket;
292 294
 		else{
... ...
@@ -338,6 +340,7 @@ not_forced:
338 338
 			break;
339 339
 #endif
340 340
 #ifdef USE_TLS
341
+		case PROTO_WSS:
341 342
 		case PROTO_TLS:
342 343
 			switch(to->s.sa_family){
343 344
 				/* FIXME */
... ...
@@ -815,8 +818,10 @@ int forward_reply(struct sip_msg* msg)
815 815
 	if (
816 816
 #ifdef USE_TCP
817 817
 			dst.proto==PROTO_TCP
818
+			|| dst.proto==PROTO_WS
818 819
 #ifdef USE_TLS
819 820
 			|| dst.proto==PROTO_TLS
821
+			|| dst.proto==PROTO_WSS
820 822
 #endif
821 823
 #ifdef USE_SCTP
822 824
 			||
... ...
@@ -350,6 +350,10 @@ char* get_proto_name(unsigned int proto)
350 350
 			return "tls";
351 351
 		case PROTO_SCTP:
352 352
 			return "sctp";
353
+		case PROTO_WS:
354
+			return "ws";
355
+		case PROTO_WSS:
356
+			return "wss";
353 357
 		default:
354 358
 			return "unknown";
355 359
 	}
... ...
@@ -406,6 +406,32 @@ int check_via_protocol(struct sip_msg* _msg) {
406 406
 				return SANITY_CHECK_FAILED;
407 407
 			}
408 408
 			break;
409
+		case PROTO_WS:
410
+			if (memcmp(_msg->via1->transport.s, "WS", 2) != 0) {
411
+				if (_msg->REQ_METHOD != METHOD_ACK) {
412
+					if (sanity_reply(_msg, 400,
413
+							"Transport Missmatch in Topmost Via") < 0) {
414
+						LOG(L_WARN, "sanity_check(): check_via_protocol():"
415
+								" failed to send 505 via sl reply\n");
416
+					}
417
+				}
418
+				DBG("check_via_protocol failed\n");
419
+				return SANITY_CHECK_FAILED;
420
+			}
421
+			break;
422
+		case PROTO_WSS:
423
+			if (memcmp(_msg->via1->transport.s, "WSS", 3) != 0) {
424
+				if (_msg->REQ_METHOD != METHOD_ACK) {
425
+					if (sanity_reply(_msg, 400,
426
+							"Transport Missmatch in Topmost Via") < 0) {
427
+						LOG(L_WARN, "sanity_check(): check_via_protocol():"
428
+								" failed to send 505 via sl reply\n");
429
+					}
430
+				}
431
+				DBG("check_via_protocol failed\n");
432
+				return SANITY_CHECK_FAILED;
433
+			}
434
+			break;
409 435
 		default:
410 436
 			LOG(L_WARN, "sanity_check(): check_via_protocol():"
411 437
 					" unknown protocol in received structure\n");
... ...
@@ -1039,7 +1039,12 @@ inline static int str2proto(char *s, int len) {
1039 1039
 		return PROTO_TLS;	
1040 1040
 	else if (len == 4 && !strncasecmp(s, "sctp", 4))
1041 1041
 		return PROTO_SCTP;
1042
-	else
1042
+	else if (len == 2 && !strncasecmp(s, "ws", 2))
1043
+		return PROTO_WS;
1044
+	else if (len == 3 && !strncasecmp(s, "wss", 3)) {
1045
+		LM_WARN("\"wss\" used somewhere...\n");
1046
+		return PROTO_WS;
1047
+	} else
1043 1048
 		return PROTO_NONE;
1044 1049
 }
1045 1050
 
... ...
@@ -92,6 +92,7 @@ inline static enum sip_protos get_proto(enum sip_protos force_proto,
92 92
 				case PROTO_SCTP:
93 93
 #endif
94 94
 						return proto;
95
+				case PROTO_WSS:	/* should never see ;transport=wss */
95 96
 				default:
96 97
 						LOG(L_ERR, "ERROR: get_proto: unsupported transport:"
97 98
 								" %d\n", proto );
... ...
@@ -104,6 +105,7 @@ inline static enum sip_protos get_proto(enum sip_protos force_proto,
104 104
 #endif
105 105
 #ifdef USE_TLS
106 106
 		case PROTO_TLS:
107
+		case PROTO_WSS:
107 108
 #endif
108 109
 #ifdef USE_SCTP
109 110
 		case PROTO_SCTP:
... ...
@@ -138,8 +140,10 @@ inline static struct proxy_l *uri2proxy( str *uri, int proto )
138 138
 			LOG(L_ERR, "ERROR: uri2proxy: bad transport for sips uri: %d\n",
139 139
 					parsed_uri.proto);
140 140
 			return 0;
141
-		}else
141
+		}else if (parsed_uri.proto != PROTO_WS)
142 142
 			uri_proto=PROTO_TLS;
143
+		else
144
+			uri_proto=PROTO_WS;
143 145
 	}else
144 146
 		uri_proto=parsed_uri.proto;
145 147
 #ifdef HONOR_MADDR
... ...
@@ -196,8 +200,10 @@ inline static int get_uri_send_info(str* uri, str* host, unsigned short* port,
196 196
 			LOG(L_ERR, "ERROR: get_uri_send_info: bad transport for"
197 197
 						" sips uri: %d\n", parsed_uri.proto);
198 198
 			return -1;
199
-		}else
199
+		}else if (parsed_uri.proto != PROTO_WS)
200 200
 			uri_proto=PROTO_TLS;
201
+		else
202
+			uri_proto=PROTO_WS;
201 203
 	}else
202 204
 		uri_proto=parsed_uri.proto;
203 205
 	
... ...
@@ -272,8 +278,10 @@ inline static struct dest_info *uri2dst2(struct dest_info* dst,
272 272
 			LOG(L_ERR, "ERROR: uri2dst: bad transport for sips uri: %d\n",
273 273
 					parsed_uri.proto);
274 274
 			return 0;
275
-		}else
275
+		}else if (parsed_uri.proto!=PROTO_WS)
276 276
 			uri_proto=PROTO_TLS;
277
+		else
278
+			uri_proto=PROTO_WS;
277 279
 	}else
278 280
 		uri_proto=parsed_uri.proto;
279 281
 	
... ...
@@ -141,6 +141,10 @@ int hash_table_insert(struct trusted_list** table, char* src_ip,
141 141
 		np->proto = PROTO_TLS;
142 142
 	} else if (strcasecmp(proto, "sctp") == 0) {
143 143
 		np->proto = PROTO_SCTP;
144
+	} else if (strcasecmp(proto, "ws") == 0) {
145
+		np->proto = PROTO_WS;
146
+	} else if (strcasecmp(proto, "wss") == 0) {
147
+		np->proto = PROTO_WSS;
144 148
 	} else if (strcasecmp(proto, "none") == 0) {
145 149
 		shm_free(np);
146 150
 		return 1;
... ...
@@ -324,6 +324,22 @@ static inline int match_proto(const char *proto_string, int proto_int)
324 324
 		}
325 325
 	}
326 326
 
327
+	if (proto_int == PROTO_WS) {
328
+		if (strcasecmp(proto_string, "ws") == 0) {
329
+			return 1;
330
+		} else {
331
+			return 0;
332
+		}
333
+	}
334
+	
335
+	if (proto_int == PROTO_WSS) {
336
+		if (strcasecmp(proto_string, "wss") == 0) {
337
+			return 1;
338
+		} else {
339
+			return 0;
340
+		}
341
+	}
342
+
327 343
 	LM_ERR("unknown request protocol\n");
328 344
 
329 345
 	return 0;
... ...
@@ -512,6 +528,13 @@ int allow_trusted_2(struct sip_msg* _msg, char* _src_ip_sp, char* _proto_sp)
512 512
 	    proto_int = PROTO_SCTP;
513 513
 	} else goto error;
514 514
 	break;
515
+    case 'w': case 'W':
516
+	if (proto.len==2 && strncasecmp(proto.s, "ws", 2) == 0) {
517
+	    proto_int = PROTO_WS;
518
+	} else if (proto.len==3 && strncasecmp(proto.s, "wss", 3) == 0) {
519
+	    proto_int = PROTO_WSS;
520
+	} else goto error;
521
+        break;
515 522
     default:
516 523
 	goto error;
517 524
     }
... ...
@@ -103,6 +103,12 @@ int send_2XX_reply(struct sip_msg * msg, int reply_code, int lexpire,
103 103
 				strncpy(tmp.s, ";transport=sctp", 15);
104 104
 				tmp.s += 15;
105 105
 			break;
106
+			case PROTO_WS:
107
+			case PROTO_WSS:
108
+				strncpy(tmp.s, ";transport=ws", 13);
109
+				tmp.s += 13;
110
+				hdr_append.len -= 2;
111
+			break;
106 112
 			default:
107 113
 				hdr_append.len -= 15;
108 114
 		}
... ...
@@ -117,6 +117,11 @@ static inline int ps_fill_local_contact(struct sip_msg* msg, str *contact)
117 117
 		proto= "sctp";
118 118
 		plen = 4;
119 119
 	}
120
+	else	
121
+	if(msg->rcv.proto== PROTO_WS || msg->rcv.proto== PROTO_WSS) {
122
+		proto= "ws";
123
+		plen = 2;
124
+	}
120 125
 	else
121 126
 	{
122 127
 		LM_ERR("unsupported proto\n");
... ...
@@ -868,6 +868,12 @@ int pv_get_proto(struct sip_msg *msg, pv_param_t *param,
868 868
 			s.s = "sctp";
869 869
 			s.len = 4;
870 870
 		break;
871
+		case PROTO_WS:
872
+			s.s = "ws";
873
+			s.len = 2;
874
+		case PROTO_WSS:
875
+			s.s = "wss";
876
+			s.len = 3;
871 877
 		default:
872 878
 			s.s = "NONE";
873 879
 			s.len = 4;
... ...
@@ -440,7 +440,7 @@ static inline int insert_contacts(struct sip_msg* _m, udomain_t* _d, str* _a)
440 440
 	flags = mem_only;
441 441
 #ifdef USE_TCP
442 442
 	if ( (_m->flags&tcp_persistent_flag) &&
443
-	(_m->rcv.proto==PROTO_TCP||_m->rcv.proto==PROTO_TLS)) {
443
+	(_m->rcv.proto==PROTO_TCP||_m->rcv.proto==PROTO_TLS||_m->rcv.proto==PROTO_WS||_m->rcv.proto==PROTO_WSS)) {
444 444
 		e_max = 0;
445 445
 		tcp_check = 1;
446 446
 	} else {
... ...
@@ -505,7 +505,7 @@ static inline int insert_contacts(struct sip_msg* _m, udomain_t* _d, str* _a)
505 505
 			if (parse_uri( _c->uri.s, _c->uri.len, &uri)<0) {
506 506
 				LM_ERR("failed to parse contact <%.*s>\n", 
507 507
 						_c->uri.len, _c->uri.s);
508
-			} else if (uri.proto==PROTO_TCP || uri.proto==PROTO_TLS) {
508
+			} else if (uri.proto==PROTO_TCP || uri.proto==PROTO_TLS || uri.proto==PROTO_WS || uri.proto==PROTO_WSS) {
509 509
 				if (e_max) {
510 510
 					LM_WARN("multiple TCP contacts on single REGISTER\n");
511 511
 					if (expires>e_max) e_max = expires;
... ...
@@ -637,7 +637,7 @@ static inline int update_contacts(struct sip_msg* _m, urecord_t* _r,
637 637
 
638 638
 #ifdef USE_TCP
639 639
 	if ( (_m->flags&tcp_persistent_flag) &&
640
-	(_m->rcv.proto==PROTO_TCP||_m->rcv.proto==PROTO_TLS)) {
640
+	(_m->rcv.proto==PROTO_TCP||_m->rcv.proto==PROTO_TLS||_m->rcv.proto==PROTO_WS||_m->rcv.proto==PROTO_WSS)) {
641 641
 		e_max = -1;
642 642
 		tcp_check = 1;
643 643
 	} else {
... ...
@@ -742,7 +742,7 @@ static inline int update_contacts(struct sip_msg* _m, urecord_t* _r,
742 742
 			if (parse_uri( _c->uri.s, _c->uri.len, &uri)<0) {
743 743
 				LM_ERR("failed to parse contact <%.*s>\n", 
744 744
 						_c->uri.len, _c->uri.s);
745
-			} else if (uri.proto==PROTO_TCP || uri.proto==PROTO_TLS) {
745
+			} else if (uri.proto==PROTO_TCP || uri.proto==PROTO_TLS || uri.proto==PROTO_WS || uri.proto==PROTO_WSS) {
746 746
 				if (e_max>0) {
747 747
 					LM_WARN("multiple TCP contacts on single REGISTER\n");
748 748
 				}
... ...
@@ -478,6 +478,10 @@ static inline int siptrace_copy_proto(int proto, char *buf)
478 478
 		strcpy(buf, "tls:");
479 479
 	} else if(proto==PROTO_SCTP) {
480 480
 		strcpy(buf, "sctp:");
481
+	} else if(proto==PROTO_WS) {
482
+		strcpy(buf, "ws:");
483
+	} else if(proto==PROTO_WSS) {
484
+		strcpy(buf, "wss:");
481 485
 	} else {
482 486
 		strcpy(buf, "udp:");
483 487
 	}
... ...
@@ -482,6 +482,7 @@ struct socket_info** get_sock_info_list(unsigned short proto)
482 482
 #endif
483 483
 			break;
484 484
 		case PROTO_TLS:
485
+		case PROTO_WSS:
485 486
 #ifdef USE_TLS
486 487
 			return &tls_listen;
487 488
 #endif
... ...
@@ -2052,6 +2053,9 @@ void init_proto_order()
2052 2052
 			if (nxt_proto[r]==PROTO_SCTP)
2053 2053
 				nxt_proto[r]=nxt_proto[PROTO_SCTP];
2054 2054
 		}
2055
+
2056
+	/* Deliberately skipping PROTO_WS and PROTO_WSS here as these
2057
+	   are just upgraded TCP and TLS connections */
2055 2058
 }
2056 2059
 
2057 2060