Browse code

core: udp server - add sockaddr_storage to ensure enough size for sockaddr_union

- safety check that from addr len is matching expected size for listen
socket
- rename local variables to suggest better their purpose

Daniel-Constantin Mierla authored on 09/05/2020 09:00:20
Showing 2 changed files
... ...
@@ -71,6 +71,7 @@ union sockaddr_union{
71 71
 	struct sockaddr     s;
72 72
 	struct sockaddr_in  sin;
73 73
 	struct sockaddr_in6 sin6;
74
+	struct sockaddr_storage sas;
74 75
 };
75 76
 
76 77
 
... ...
@@ -428,9 +428,9 @@ int udp_rcv_loop()
428 428
 	static char buf [BUF_SIZE+1];
429 429
 #endif
430 430
 	char *tmp;
431
-	union sockaddr_union* from;
432
-	unsigned int fromlen;
433
-	struct receive_info ri;
431
+	union sockaddr_union* fromaddr;
432
+	unsigned int fromaddrlen;
433
+	receive_info_t rcvi;
434 434
 	sr_event_param_t evp = {0};
435 435
 #define UDP_RCV_PRINTBUF_SIZE 512
436 436
 #define UDP_RCV_PRINT_LEN 100
... ...
@@ -440,17 +440,18 @@ int udp_rcv_loop()
440 440
 	int l;
441 441
 
442 442
 
443
-	from=(union sockaddr_union*) pkg_malloc(sizeof(union sockaddr_union));
444
-	if (from==0){
443
+	fromaddr=(union sockaddr_union*) pkg_malloc(sizeof(union sockaddr_union));
444
+	if (fromaddr==0){
445 445
 		PKG_MEM_ERROR;
446 446
 		goto error;
447 447
 	}
448
-	memset(from, 0 , sizeof(union sockaddr_union));
449
-	ri.bind_address=bind_address; /* this will not change, we do it only once*/
450
-	ri.dst_port=bind_address->port_no;
451
-	ri.dst_ip=bind_address->address;
452
-	ri.proto=PROTO_UDP;
453
-	ri.proto_reserved1=ri.proto_reserved2=0;
448
+	memset(fromaddr, 0,sizeof(union sockaddr_union));
449
+	memset(&rcvi, 0, sizeof(receive_info_t));
450
+	/* these do not change, set only once*/
451
+	rcvi.bind_address=bind_address;
452
+	rcvi.dst_port=bind_address->port_no;
453
+	rcvi.dst_ip=bind_address->address;
454
+	rcvi.proto=PROTO_UDP;
454 455
 
455 456
 	/* initialize the config framework */
456 457
 	if (cfg_child_init()) goto error;
... ...
@@ -463,9 +464,9 @@ int udp_rcv_loop()
463 464
 			goto error;
464 465
 		}
465 466
 #endif
466
-		fromlen=sockaddru_len(bind_address->su);
467
-		len=recvfrom(bind_address->socket, buf, BUF_SIZE, 0, &from->s,
468
-											&fromlen);
467
+		fromaddrlen=sizeof(union sockaddr_union);
468
+		len=recvfrom(bind_address->socket, buf, BUF_SIZE, 0,
469
+				(struct sockaddr*)fromaddr, &fromaddrlen);
469 470
 		if (len==-1){
470 471
 			if (errno==EAGAIN){
471 472
 				LM_DBG("packet with bad checksum received\n");
... ...
@@ -476,6 +477,11 @@ int udp_rcv_loop()
476 477
 				continue; /* goto skip;*/
477 478
 			else goto error;
478 479
 		}
480
+		if(fromaddrlen != (unsigned int)sockaddru_len(bind_address->su)) {
481
+			LM_ERR("ignoring data - unexpected from addr len: %u != %u\n",
482
+					fromaddrlen, (unsigned int)sockaddru_len(bind_address->su));
483
+			continue;
484
+		}
479 485
 		/* we must 0-term the messages, receive_msg expects it */
480 486
 		buf[len]=0; /* no need to save the previous char */
481 487
 
... ...
@@ -498,16 +504,16 @@ int udp_rcv_loop()
498 504
 			LM_DBG("received on udp socket: (%d/%d/%d) [[%.*s]]\n",
499 505
 					j, i, len, j, printbuf);
500 506
 		}
501
-		ri.src_su=*from;
502
-		su2ip_addr(&ri.src_ip, from);
503
-		ri.src_port=su_getport(from);
507
+		rcvi.src_su=*fromaddr;
508
+		su2ip_addr(&rcvi.src_ip, fromaddr);
509
+		rcvi.src_port=su_getport(fromaddr);
504 510
 
505 511
 		if(unlikely(sr_event_enabled(SREV_NET_DGRAM_IN)))
506 512
 		{
507 513
 			void *sredp[3];
508 514
 			sredp[0] = (void*)buf;
509 515
 			sredp[1] = (void*)(&len);
510
-			sredp[2] = (void*)(&ri);
516
+			sredp[2] = (void*)(&rcvi);
511 517
 			evp.data = (void*)sredp;
512 518
 			if(sr_event_exec(SREV_NET_DGRAM_IN, &evp)<0) {
513 519
 				/* data handled by callback - continue to next packet */
... ...
@@ -517,8 +523,8 @@ int udp_rcv_loop()
517 523
 #ifndef NO_ZERO_CHECKS
518 524
 		if (!unlikely(sr_event_enabled(SREV_STUN_IN)) || (unsigned char)*buf != 0x00) {
519 525
 			if (len<MIN_UDP_PACKET) {
520
-				tmp=ip_addr2a(&ri.src_ip);
521
-				LM_DBG("probing packet received from %s %d\n", tmp, htons(ri.src_port));
526
+				tmp=ip_addr2a(&rcvi.src_ip);
527
+				LM_DBG("probing packet received from %s %d\n", tmp, htons(rcvi.src_port));
522 528
 				continue;
523 529
 			}
524 530
 		}
... ...
@@ -530,8 +536,8 @@ int udp_rcv_loop()
530 536
 			continue;
531 537
 		}
532 538
 #endif
533
-		if (ri.src_port==0){
534
-			tmp=ip_addr2a(&ri.src_ip);
539
+		if (rcvi.src_port==0){
540
+			tmp=ip_addr2a(&rcvi.src_ip);
535 541
 			LM_INFO("dropping 0 port packet from %s\n", tmp);
536 542
 			continue;
537 543
 		}
... ...
@@ -540,24 +546,24 @@ int udp_rcv_loop()
540 546
 		cfg_update();
541 547
 		if (unlikely(sr_event_enabled(SREV_STUN_IN)) && (unsigned char)*buf == 0x00) {
542 548
 			/* stun_process_msg releases buf memory if necessary */
543
-			if ((stun_process_msg(buf, len, &ri)) != 0) {
549
+			if ((stun_process_msg(buf, len, &rcvi)) != 0) {
544 550
 				continue; /* some error occurred */
545 551
 			}
546 552
 		} else {
547 553
 			/* receive_msg must free buf too!*/
548
-			receive_msg(buf, len, &ri);
554
+			receive_msg(buf, len, &rcvi);
549 555
 		}
550 556
 
551 557
 	/* skip: do other stuff */
552 558
 
553 559
 	}
554 560
 	/*
555
-	if (from) pkg_free(from);
561
+	if (fromaddr) pkg_free(fromaddr);
556 562
 	return 0;
557 563
 	*/
558 564
 
559 565
 error:
560
-	if (from) pkg_free(from);
566
+	if (fromaddr) pkg_free(fromaddr);
561 567
 	return -1;
562 568
 }
563 569