Browse code

core: try to handle hep3 over tcp/tls from reader

- avoid going through longer processing path
- done only global parameter tcp_accept_hep3 is set

Daniel-Constantin Mierla authored on 02/11/2017 09:47:50
Showing 5 changed files
... ...
@@ -395,6 +395,7 @@ TCP_OPT_KEEPINTVL	"tcp_keepintvl"
395 395
 TCP_OPT_KEEPCNT		"tcp_keepcnt"
396 396
 TCP_OPT_CRLF_PING	"tcp_crlf_ping"
397 397
 TCP_OPT_ACCEPT_NO_CL	"tcp_accept_no_cl"
398
+TCP_OPT_ACCEPT_HEP3	"tcp_accept_hep3"
398 399
 TCP_CLONE_RCVBUF	"tcp_clone_rcvbuf"
399 400
 TCP_REUSE_PORT		"tcp_reuse_port"
400 401
 DISABLE_TLS		"disable_tls"|"tls_disable"
... ...
@@ -839,6 +840,8 @@ IMPORTFILE      "import_file"
839 840
 									return TCP_OPT_CRLF_PING; }
840 841
 <INITIAL>{TCP_OPT_ACCEPT_NO_CL}	{ count(); yylval.strval=yytext;
841 842
 									return TCP_OPT_ACCEPT_NO_CL; }
843
+<INITIAL>{TCP_OPT_ACCEPT_HEP3}	{ count(); yylval.strval=yytext;
844
+									return TCP_OPT_ACCEPT_HEP3; }
842 845
 <INITIAL>{TCP_CLONE_RCVBUF}		{ count(); yylval.strval=yytext;
843 846
 									return TCP_CLONE_RCVBUF; }
844 847
 <INITIAL>{TCP_REUSE_PORT}	{ count(); yylval.strval=yytext; return TCP_REUSE_PORT; }
... ...
@@ -430,6 +430,7 @@ extern char *default_routename;
430 430
 %token TCP_OPT_KEEPCNT
431 431
 %token TCP_OPT_CRLF_PING
432 432
 %token TCP_OPT_ACCEPT_NO_CL
433
+%token TCP_OPT_ACCEPT_HEP3
433 434
 %token TCP_CLONE_RCVBUF
434 435
 %token TCP_REUSE_PORT
435 436
 %token DISABLE_TLS
... ...
@@ -1202,6 +1203,15 @@ assign_stm:
1202 1203
 		#endif
1203 1204
 	}
1204 1205
 	| TCP_OPT_ACCEPT_NO_CL EQUAL error { yyerror("boolean value expected"); }
1206
+	| TCP_OPT_ACCEPT_HEP3 EQUAL NUMBER {
1207
+		#ifdef USE_TCP
1208
+			ksr_tcp_accept_hep3=$3;
1209
+		#else
1210
+			warn("tcp support not compiled in");
1211
+		#endif
1212
+	}
1213
+	| TCP_OPT_ACCEPT_HEP3 EQUAL error { yyerror("boolean value expected"); }
1214
+
1205 1215
 	| TCP_CLONE_RCVBUF EQUAL NUMBER {
1206 1216
 		#ifdef USE_TCP
1207 1217
 			tcp_set_clone_rcvbuf($3);
... ...
@@ -99,6 +99,7 @@ extern enum poll_types tcp_poll_method;
99 99
 extern int tcp_max_connections; /* maximum tcp connections, hard limit */
100 100
 extern int tls_max_connections; /* maximum tls connections, hard limit */
101 101
 #endif
102
+extern int ksr_tcp_accept_hep3;
102 103
 #ifdef USE_TLS
103 104
 extern int tls_disable;
104 105
 extern unsigned short tls_port_no;
... ...
@@ -133,7 +133,7 @@ struct tcp_req{
133 133
 #ifdef READ_HTTP11
134 134
 	int chunk_size;
135 135
 #endif
136
-	unsigned short flags; /* F_TCP_REQ_HAS_CLEN | F_TCP_REQ_COMPLETE */
136
+	unsigned int flags; /* F_TCP_REQ_HAS_CLEN | F_TCP_REQ_COMPLETE */
137 137
 	int bytes_to_go; /* how many bytes we have still to read from the body*/
138 138
 	enum tcp_req_errors error;
139 139
 	enum tcp_req_states state;
... ...
@@ -150,6 +150,7 @@ struct tcp_req{
150 150
 #define F_TCP_REQ_MSRP_FRAME  16
151 151
 #define F_TCP_REQ_MSRP_BODY   32
152 152
 #endif
153
+#define F_TCP_REQ_HEP3        64
153 154
 
154 155
 #define TCP_REQ_HAS_CLEN(tr)  ((tr)->flags & F_TCP_REQ_HAS_CLEN)
155 156
 #define TCP_REQ_COMPLETE(tr)  ((tr)->flags & F_TCP_REQ_COMPLETE)
... ...
@@ -91,6 +91,7 @@ static ticks_t tcp_reader_prev_ticks;
91 91
 
92 92
 int is_msg_complete(struct tcp_req* r);
93 93
 
94
+int ksr_tcp_accept_hep3=0;
94 95
 /**
95 96
  * control cloning of TCP receive buffer
96 97
  * - needed for operations working directly inside the buffer
... ...
@@ -481,7 +482,7 @@ int tcp_read_headers(struct tcp_connection *c, int* read_flags)
481 482
 					goto skip;
482 483
 				}
483 484
 				break;
484
-				
485
+
485 486
 			case H_SKIP:
486 487
 				/* find lf, we are in this state if we are not interested
487 488
 				 * in anything till end of line*/
... ...
@@ -674,10 +675,10 @@ int tcp_read_headers(struct tcp_connection *c, int* read_flags)
674 675
 						r->start=p;
675 676
 						break;
676 677
 					default:
677
-						/* stun test */						
678
+						/* stun test */
678 679
 						if (unlikely(sr_event_enabled(SREV_STUN_IN)) && (unsigned char)*p == 0x00) {
679 680
 							r->state=H_STUN_MSG;
680
-						/* body will used as pointer to the last used byte */
681
+							/* body is used as pointer to the last used byte */
681 682
 							r->body=p;
682 683
 							r->content_len = 0;
683 684
 							LM_DBG("stun msg detected\n");
... ...
@@ -1235,6 +1236,88 @@ static int ws_process_msg(char* tcpbuf, unsigned int len,
1235 1236
 }
1236 1237
 #endif
1237 1238
 
1239
+static int tcp_read_hep3(struct tcp_connection *c, int* read_flags)
1240
+{
1241
+	int bytes;
1242
+	uint32_t size, mask_present, len;
1243
+	char *p;
1244
+	struct tcp_req *r;
1245
+
1246
+	r=&c->req;
1247
+#ifdef USE_TLS
1248
+	if (unlikely(c->type == PROTO_TLS))
1249
+		bytes = tls_read(c, read_flags);
1250
+	else
1251
+#endif
1252
+		bytes = tcp_read(c, read_flags);
1253
+
1254
+	if (bytes <= 0) {
1255
+		if (likely(r->parsed >= r->pos))
1256
+			return 0;
1257
+	}
1258
+
1259
+	size = r->pos - r->parsed;
1260
+
1261
+	p = r->parsed;
1262
+
1263
+	/* Process first six bytes (HEP3 + 2 bytes the size)*/
1264
+	if (size < 6)
1265
+		goto skip;
1266
+
1267
+	if(p[0]!='H' || p[1]!='E' || p[2]!='P' || p[3]=='3') {
1268
+		/* not hep3 */
1269
+		goto skip;
1270
+	}
1271
+
1272
+	len = ((uint32_t)(p[4] & 0xff) <<  8) + (p[5] & 0xff);
1273
+
1274
+	/* check if advertised lenght fits in read buffer */
1275
+	if(len>=r->b_size) {
1276
+		LM_WARN("advertised lenght (%u) greater than buffer size (%u)\n",
1277
+				len, r->b_size);
1278
+		goto skip;
1279
+	}
1280
+	/* check the whole message has been received */
1281
+	if (size < len)
1282
+		goto skip;
1283
+
1284
+	r->flags |= F_TCP_REQ_COMPLETE;
1285
+	r->flags |= F_TCP_REQ_HEP3;
1286
+	r->parsed = &p[len];
1287
+
1288
+skip:
1289
+	return bytes;
1290
+}
1291
+
1292
+static int hep3_process_msg(char* tcpbuf, unsigned int len,
1293
+		struct receive_info* rcv_info, struct tcp_connection* con)
1294
+{
1295
+	sip_msg_t msg;
1296
+	int ret;
1297
+	sr_event_param_t evp = {0};
1298
+
1299
+	memset(&msg, 0, sizeof(sip_msg_t)); /* init everything to 0 */
1300
+	/* fill in msg */
1301
+	msg.buf=tcpbuf;
1302
+	msg.len=len;
1303
+	/* zero termination (termination of orig message bellow not that
1304
+	 * useful as most of the work is done with scratch-pad; -jiri  */
1305
+	/* buf[len]=0; */ /* WARNING: zero term removed! */
1306
+	msg.rcv=*rcv_info;
1307
+	msg.id=msg_no;
1308
+	msg.pid=my_pid();
1309
+	msg.set_global_address=default_global_address;
1310
+	msg.set_global_port=default_global_port;
1311
+
1312
+	if(likely(sr_msg_time==1)) msg_set_time(&msg);
1313
+	evp.data = (void*)(&msg);
1314
+	ret=sr_event_exec(SREV_RCV_NOSIP, &evp);
1315
+	LM_DBG("running hep3 handling event returned %d\n", ret);
1316
+	free_sip_msg(&msg);
1317
+
1318
+	return 0;
1319
+}
1320
+
1238 1321
 /**
1239 1322
  * @brief wrapper around receive_msg() to clone the tcpbuf content
1240 1323
  *
... ...
@@ -1265,6 +1348,8 @@ int receive_tcp_msg(char* tcpbuf, unsigned int len,
1265 1348
 		if(unlikely(con->type == PROTO_WS || con->type == PROTO_WSS))
1266 1349
 			return ws_process_msg(tcpbuf, len, rcv_info, con);
1267 1350
 #endif
1351
+		if(unlikely(con->req.flags&F_TCP_REQ_HEP3))
1352
+			return hep3_process_msg(tcpbuf, len, rcv_info, con);
1268 1353
 
1269 1354
 		return receive_msg(tcpbuf, len, rcv_info);
1270 1355
 	}
... ...
@@ -1313,6 +1398,8 @@ int receive_tcp_msg(char* tcpbuf, unsigned int len,
1313 1398
 	if(unlikely(con->type == PROTO_WS || con->type == PROTO_WSS))
1314 1399
 		return ws_process_msg(buf, len, rcv_info, con);
1315 1400
 #endif
1401
+	if(unlikely(con->req.flags&F_TCP_REQ_HEP3))
1402
+		return hep3_process_msg(tcpbuf, len, rcv_info, con);
1316 1403
 	return receive_msg(buf, len, rcv_info);
1317 1404
 #else /* TCP_CLONE_RCVBUF */
1318 1405
 #ifdef READ_MSRP
... ...
@@ -1323,6 +1410,8 @@ int receive_tcp_msg(char* tcpbuf, unsigned int len,
1323 1410
 	if(unlikely(con->type == PROTO_WS || con->type == PROTO_WSS))
1324 1411
 		return ws_process_msg(tcpbuf, len, rcv_info, con);
1325 1412
 #endif
1413
+	if(unlikely(con->req.flags&F_TCP_REQ_HEP3))
1414
+		return hep3_process_msg(tcpbuf, len, rcv_info, con);
1326 1415
 	return receive_msg(tcpbuf, len, rcv_info);
1327 1416
 #endif /* TCP_CLONE_RCVBUF */
1328 1417
 }
... ...
@@ -1346,11 +1435,24 @@ int tcp_read_req(struct tcp_connection* con, int* bytes_read, int* read_flags)
1346 1435
 again:
1347 1436
 		if (likely(req->error==TCP_REQ_OK)){
1348 1437
 #ifdef READ_WS
1349
-			if (unlikely(con->type == PROTO_WS || con->type == PROTO_WSS))
1438
+			if (unlikely(con->type == PROTO_WS || con->type == PROTO_WSS)) {
1350 1439
 				bytes=tcp_read_ws(con, read_flags);
1351
-			else
1440
+			} else {
1441
+#endif
1442
+				if(unlikely(ksr_tcp_accept_hep3!=0)) {
1443
+					bytes=tcp_read_hep3(con, read_flags);
1444
+					if (bytes>=0) {
1445
+						if(!(con->req.flags & F_TCP_REQ_HEP3)) {
1446
+							/* not hep3, try to read headers */
1447
+							bytes=tcp_read_headers(con, read_flags);
1448
+						}
1449
+					}
1450
+				} else {
1451
+					bytes=tcp_read_headers(con, read_flags);
1452
+				}
1453
+#ifdef READ_WS
1454
+			}
1352 1455
 #endif
1353
-				bytes=tcp_read_headers(con, read_flags);
1354 1456
 
1355 1457
 			if (unlikely(bytes==-1)){
1356 1458
 				LOG(cfg_get(core, core_cfg, corelog),