Browse code

Merge 98dd53abc4212d8bc333c4c79e54f7cdc0bd1f20 into 6ce9c3c897055ff9942634c493caf79780ccf71b

rhys-hanrahan authored on 04/01/2022 09:50:59 • GitHub committed on 04/01/2022 09:50:59
Showing 7 changed files
... ...
@@ -305,6 +305,7 @@ XAVPVIAPARAMS	xavp_via_params
305 305
 XAVPVIAFIELDS	xavp_via_fields
306 306
 LISTEN		listen
307 307
 ADVERTISE	advertise|ADVERTISE
308
+VIRTUAL		virtual
308 309
 STRNAME		name|NAME
309 310
 ALIAS		alias
310 311
 SR_AUTO_ALIASES	auto_aliases
... ...
@@ -741,6 +742,7 @@ IMPORTFILE      "import_file"
741 742
 <INITIAL>{XAVPVIAFIELDS}	{ yylval.strval=yytext; return XAVPVIAFIELDS; }
742 743
 <INITIAL>{LISTEN}	{ count(); yylval.strval=yytext; return LISTEN; }
743 744
 <INITIAL>{ADVERTISE}	{ count(); yylval.strval=yytext; return ADVERTISE; }
745
+<INITIAL>{VIRTUAL}	{ count(); yylval.strval=yytext; return VIRTUAL; }
744 746
 <INITIAL>{STRNAME}	{ count(); yylval.strval=yytext; return STRNAME; }
745 747
 <INITIAL>{ALIAS}	{ count(); yylval.strval=yytext; return ALIAS; }
746 748
 <INITIAL>{SR_AUTO_ALIASES}	{ count(); yylval.strval=yytext;
... ...
@@ -328,6 +328,7 @@ extern char *default_routename;
328 328
 %token XAVPVIAFIELDS
329 329
 %token LISTEN
330 330
 %token ADVERTISE
331
+%token VIRTUAL
331 332
 %token STRNAME
332 333
 %token ALIAS
333 334
 %token SR_AUTO_ALIASES
... ...
@@ -1503,6 +1504,19 @@ assign_stm:
1503 1504
 		}
1504 1505
 		free_socket_id_lst($3);
1505 1506
 	}
1507
+        | LISTEN EQUAL id_lst VIRTUAL {
1508
+                for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next) {
1509
+			lst_tmp->flags |= SI_IS_VIRTUAL;
1510
+                        if (add_listen_iface(   lst_tmp->addr_lst->name,
1511
+                                                                        lst_tmp->addr_lst->next,
1512
+                                                                        lst_tmp->port, lst_tmp->proto,
1513
+                                                                        lst_tmp->flags)!=0) {
1514
+                                LM_CRIT("cfg. parser: failed to add listen address\n");
1515
+                                break;
1516
+                        }
1517
+                }
1518
+                free_socket_id_lst($3);
1519
+        }
1506 1520
 	| LISTEN EQUAL id_lst STRNAME STRING {
1507 1521
 		for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next) {
1508 1522
 			if (add_listen_iface_name(lst_tmp->addr_lst->name,
... ...
@@ -1515,6 +1529,19 @@ assign_stm:
1515 1529
 		}
1516 1530
 		free_socket_id_lst($3);
1517 1531
 	}
1532
+        | LISTEN EQUAL id_lst STRNAME STRING VIRTUAL {
1533
+                for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next) {
1534
+                        lst_tmp->flags |= SI_IS_VIRTUAL;
1535
+                        if (add_listen_iface_name(lst_tmp->addr_lst->name,
1536
+                                                                        lst_tmp->addr_lst->next,
1537
+                                                                        lst_tmp->port, lst_tmp->proto, $5,
1538
+                                                                        lst_tmp->flags)!=0) {
1539
+                                LM_CRIT("cfg. parser: failed to add listen address\n");
1540
+                                break;
1541
+                        }
1542
+                }
1543
+                free_socket_id_lst($3);
1544
+        }
1518 1545
 	| LISTEN EQUAL id_lst ADVERTISE listen_id COLON NUMBER {
1519 1546
 		for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next) {
1520 1547
 			if (add_listen_advertise_iface(	lst_tmp->addr_lst->name,
... ...
@@ -1528,6 +1555,20 @@ assign_stm:
1528 1555
 		}
1529 1556
 		free_socket_id_lst($3);
1530 1557
 	}
1558
+        | LISTEN EQUAL id_lst ADVERTISE listen_id COLON NUMBER VIRTUAL {
1559
+                for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next) {
1560
+			lst_tmp->flags |= SI_IS_VIRTUAL;
1561
+                        if (add_listen_advertise_iface( lst_tmp->addr_lst->name,
1562
+                                                                        lst_tmp->addr_lst->next,
1563
+                                                                        lst_tmp->port, lst_tmp->proto,
1564
+                                                                        $5, $7,
1565
+                                                                        lst_tmp->flags)!=0) {
1566
+                                LM_CRIT("cfg. parser: failed to add listen address\n");
1567
+                                break;
1568
+                        }
1569
+                }
1570
+                free_socket_id_lst($3);
1571
+        }
1531 1572
 	| LISTEN EQUAL id_lst ADVERTISE listen_id COLON NUMBER STRNAME STRING {
1532 1573
 		for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next) {
1533 1574
 			if (add_listen_advertise_iface_name(lst_tmp->addr_lst->name,
... ...
@@ -1541,6 +1582,20 @@ assign_stm:
1541 1582
 		}
1542 1583
 		free_socket_id_lst($3);
1543 1584
 	}
1585
+        | LISTEN EQUAL id_lst ADVERTISE listen_id COLON NUMBER STRNAME STRING VIRTUAL {
1586
+                for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next) {
1587
+			lst_tmp->flags |= SI_IS_VIRTUAL;
1588
+                        if (add_listen_advertise_iface_name(lst_tmp->addr_lst->name,
1589
+                                                                        lst_tmp->addr_lst->next,
1590
+                                                                        lst_tmp->port, lst_tmp->proto,
1591
+                                                                        $5, $7, $9,
1592
+                                                                        lst_tmp->flags)!=0) {
1593
+                                LM_CRIT("cfg. parser: failed to add listen address\n");
1594
+                                break;
1595
+                        }
1596
+                }
1597
+                free_socket_id_lst($3);
1598
+        }
1544 1599
 	| LISTEN EQUAL id_lst ADVERTISE listen_id {
1545 1600
 		for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next) {
1546 1601
 			if (add_listen_advertise_iface(	lst_tmp->addr_lst->name,
... ...
@@ -1554,6 +1609,20 @@ assign_stm:
1554 1609
 		}
1555 1610
 		free_socket_id_lst($3);
1556 1611
 	}
1612
+        | LISTEN EQUAL id_lst ADVERTISE listen_id VIRTUAL {
1613
+                for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next) {
1614
+			lst_tmp->flags |= SI_IS_VIRTUAL;
1615
+                        if (add_listen_advertise_iface( lst_tmp->addr_lst->name,
1616
+                                                                        lst_tmp->addr_lst->next,
1617
+                                                                        lst_tmp->port, lst_tmp->proto,
1618
+                                                                        $5, 0,
1619
+                                                                        lst_tmp->flags)!=0) {
1620
+                                LM_CRIT("cfg. parser: failed to add listen address\n");
1621
+                                break;
1622
+                        }
1623
+                }
1624
+                free_socket_id_lst($3);
1625
+        }
1557 1626
 	| LISTEN EQUAL id_lst ADVERTISE listen_id STRNAME STRING {
1558 1627
 		for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next) {
1559 1628
 			if (add_listen_advertise_iface_name(lst_tmp->addr_lst->name,
... ...
@@ -1567,6 +1636,20 @@ assign_stm:
1567 1636
 		}
1568 1637
 		free_socket_id_lst($3);
1569 1638
 	}
1639
+        | LISTEN EQUAL id_lst ADVERTISE listen_id STRNAME STRING VIRTUAL {
1640
+                for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next) {
1641
+			lst_tmp->flags |= SI_IS_VIRTUAL;
1642
+                        if (add_listen_advertise_iface_name(lst_tmp->addr_lst->name,
1643
+                                                                        lst_tmp->addr_lst->next,
1644
+                                                                        lst_tmp->port, lst_tmp->proto,
1645
+                                                                        $5, 0, $7,
1646
+                                                                        lst_tmp->flags)!=0) {
1647
+                                LM_CRIT("cfg. parser: failed to add listen address\n");
1648
+                                break;
1649
+                        }
1650
+                }
1651
+                free_socket_id_lst($3);
1652
+        }
1570 1653
 	| LISTEN EQUAL  error { yyerror("ip address, interface name or"
1571 1654
 									" hostname expected"); }
1572 1655
 	| ALIAS EQUAL  id_lst {
... ...
@@ -955,10 +955,11 @@ static void core_sockets_list(rpc_t* rpc, void* c)
955 955
 				for (ai=si->addr_info_lst; ai; ai=ai->next)
956 956
 					rpc->struct_add(ha, "ss",
957 957
 						"address", ai->address_str.s);
958
-				rpc->struct_add(ha, "sss",
958
+				rpc->struct_add(ha, "ssss",
959 959
 						"port", si->port_no_str.s,
960 960
 						"mcast", si->flags & SI_IS_MCAST ? "yes" : "no",
961
-						"mhomed", si->flags & SI_IS_MHOMED ? "yes" : "no");
961
+						"mhomed", si->flags & SI_IS_MHOMED ? "yes" : "no",
962
+						"virtual", si->flags & SI_IS_VIRTUAL ? "yes" : "no");
962 963
 			} else {
963 964
 				printf("             %s: %s",
964 965
 						get_proto_name(proto),
... ...
@@ -969,10 +970,11 @@ static void core_sockets_list(rpc_t* rpc, void* c)
969 970
 				if (!(si->flags & SI_IS_IP))
970 971
 					rpc->struct_add(ha, "s",
971 972
 						"ipaddress", si->address_str.s);
972
-				rpc->struct_add(ha, "sss",
973
+				rpc->struct_add(ha, "ssss",
973 974
 						"port", si->port_no_str.s,
974 975
 						"mcast", si->flags & SI_IS_MCAST ? "yes" : "no",
975
-						"mhomed", si->flags & SI_IS_MHOMED ? "yes" : "no");
976
+						"mhomed", si->flags & SI_IS_MHOMED ? "yes" : "no",
977
+						"virtual", si->flags & SI_IS_VIRTUAL ? "yes" : "no");
976 978
 			}
977 979
 		}
978 980
 	} while((proto=next_proto(proto)));
... ...
@@ -84,6 +84,7 @@ typedef enum si_flags {
84 84
 	SI_IS_MCAST     = (1<<2),
85 85
 	SI_IS_ANY       = (1<<3),
86 86
 	SI_IS_MHOMED    = (1<<4),
87
+	SI_IS_VIRTUAL	= (1<<5),
87 88
 } si_flags_t;
88 89
 
89 90
 typedef struct addr_info {
... ...
@@ -562,6 +562,67 @@ struct socket_info** get_sock_info_list(unsigned short proto)
562 562
 	return 0;
563 563
 }
564 564
 
565
+/* Check list of active local IPs for grep_sock_info
566
+ * This function is only used for sockets with the SI_IS_VIRTUAL flag set. This
567
+ * is so floating (virtual) IPs that are not currently local, are not returned
568
+ * as matches by grep_sock_info.
569
+ *
570
+ * Params:
571
+ * - si - Socket info of socket that has been flagged with SI_IS_VIRTUAL, 
572
+ *   that we want to check if it's actually local right now.
573
+ *
574
+ * Returns 1 if socket is local, or 0 if not.
575
+ */
576
+static int check_local_addresses(struct socket_info* si)
577
+{
578
+	int match = 0;
579
+	struct ifaddrs *ifap, *ifa;
580
+
581
+	if (si == NULL) {
582
+		LM_ERR("Socket info is NULL. Returning no match.\n");
583
+		return 0;
584
+	}
585
+
586
+	if (!(si->flags & SI_IS_VIRTUAL)) {
587
+		LM_ERR("Have been passed a socket without the virtual flag set. This should "
588
+			"not happen. Returning a match to maintain standard behaviour.\n");
589
+		return 1;
590
+	}
591
+
592
+	if (getifaddrs(&ifap) != 0) {
593
+		LM_ERR("getifaddrs failed. Assuming no match.\n");
594
+		return 0;
595
+	}
596
+
597
+	for (ifa = ifap; ifa; ifa = ifa->ifa_next)
598
+	{
599
+		/* skip if no IP addr associated with the interface */
600
+		if (ifa->ifa_addr==0)
601
+			continue;
602
+#ifdef AF_PACKET
603
+		/* skip AF_PACKET addr family since it is of no use later on */
604
+		if (ifa->ifa_addr->sa_family == AF_PACKET)
605
+			continue;
606
+#endif
607
+		struct ip_addr local_addr;
608
+		sockaddr2ip_addr(&local_addr, (struct sockaddr*)ifa->ifa_addr);
609
+
610
+		LM_DBG("Checking local address: %s\n", ip_addr2a(&local_addr));
611
+		if (ip_addr_cmp(&si->address, &local_addr)) {
612
+			match = 1;
613
+			LM_DBG("Found matching local IP %s for virtual socket %s\n", ip_addr2a(&local_addr), si->name.s);
614
+			break;
615
+		}
616
+	}
617
+	freeifaddrs(ifap);
618
+	//Default to not local if no match is found
619
+	if (!match) {
620
+		LM_DBG("No matching local IP found for socket %s.\n", si->name.s);
621
+		return 0;
622
+	} else {
623
+		return 1;
624
+	}
625
+}
565 626
 
566 627
 /* helper function for grep_sock_info
567 628
  * params:
... ...
@@ -653,7 +714,16 @@ retry:
653 714
 			}
654 715
 			if (si_hname_cmp(&hname, &si->name, &si->address_str,
655 716
 								&si->address, si->flags)==0) {
656
-				goto found;
717
+				if (si->flags & SI_IS_VIRTUAL) {
718
+					LM_DBG("Checking virtual socket: [%.*s]\n", si->name.len, si->name.s);
719
+					if (check_local_addresses(si)) {
720
+						goto found;
721
+					} else {
722
+						LM_DBG("Skipping virtual socket that is not local.\n");
723
+					}
724
+				} else {
725
+					goto found;
726
+				}
657 727
 			}
658 728
 			if(si->useinfo.name.s!=NULL) {
659 729
 				LM_DBG("checking advertise if host==us:"
... ...
@@ -2071,10 +2141,11 @@ void print_all_socket_lists()
2071 2141
 				for (ai=si->addr_info_lst; ai; ai=ai->next) {
2072 2142
 					printf(", %s", ai->address_str.s);
2073 2143
 				}
2074
-				printf("):%s%s%s\n",
2144
+				printf("):%s%s%s%s\n",
2075 2145
 						si->port_no_str.s,
2076
-						si->flags & SI_IS_MCAST ? " mcast" : "",
2077
-						si->flags & SI_IS_MHOMED? " mhomed" : "");
2146
+						si->flags & SI_IS_MCAST  ? " mcast" : "",
2147
+						si->flags & SI_IS_MHOMED ? " mhomed" : "",
2148
+						si->flags & SI_IS_VIRTUAL? " virtual" : "");
2078 2149
 			}else{
2079 2150
 				printf("             %s: %s",
2080 2151
 						get_valid_proto_name(proto),
... ...
@@ -2082,10 +2153,11 @@ void print_all_socket_lists()
2082 2153
 				if (!(si->flags & SI_IS_IP)) {
2083 2154
 					printf(" [%s]", si->address_str.s);
2084 2155
 				}
2085
-				printf( ":%s%s%s",
2156
+				printf( ":%s%s%s%s",
2086 2157
 						si->port_no_str.s,
2087
-						si->flags & SI_IS_MCAST ? " mcast" : "",
2088
-						si->flags & SI_IS_MHOMED? " mhomed" : "");
2158
+						si->flags & SI_IS_MCAST  ? " mcast" : "",
2159
+						si->flags & SI_IS_MHOMED ? " mhomed" : "",
2160
+						si->flags & SI_IS_VIRTUAL? " virtual" : "");
2089 2161
 				if (si->sockname.s) {
2090 2162
 					printf(" name %s", si->sockname.s);
2091 2163
 				}
... ...
@@ -95,10 +95,11 @@ static void corex_rpc_list_sockets(rpc_t* rpc, void* ctx)
95 95
 				}
96 96
 			}
97 97
 
98
-			if(rpc->struct_add(th, "sssss",
98
+			if(rpc->struct_add(th, "ssssss",
99 99
 					"PORT", si->port_no_str.s,
100 100
 					"MCAST", si->flags & SI_IS_MCAST ? "yes" : "no",
101
-					"MHOMED", si->flags & SI_IS_MHOMED? "yes" : "no",
101
+					"MHOMED", si->flags & SI_IS_MHOMED ? "yes" : "no",
102
+					"VIRTUAL", si->flags & SI_IS_VIRTUAL ? "yes" : "no",
102 103
 					"SOCKNAME", si->sockname.s? si->sockname.s : "-",
103 104
 					"ADVERTISE", si->useinfo.name.s?si->useinfo.name.s:"-")<0)
104 105
 			{
... ...
@@ -140,9 +140,9 @@ static void ipsec_print_all_socket_lists()
140 140
 				}
141 141
 
142 142
 				if(si->port_no_str.s){
143
-					sprintf(buf + cnt, "):%s%s%s", si->port_no_str.s, si->flags & SI_IS_MCAST ? " mcast" : "", si->flags & SI_IS_MHOMED? " mhomed" : "");
143
+					sprintf(buf + cnt, "):%s%s%s%s", si->port_no_str.s, si->flags & SI_IS_MCAST ? " mcast" : "", si->flags & SI_IS_MHOMED ? " mhomed" : "", si->flags & SI_IS_VIRTUAL ? " virtual" : "");
144 144
 				}else{
145
-					sprintf(buf + cnt, "):%u%s%s", si->port_no, si->flags & SI_IS_MCAST ? " mcast" : "", si->flags & SI_IS_MHOMED? " mhomed" : "");
145
+					sprintf(buf + cnt, "):%u%s%s%s", si->port_no, si->flags & SI_IS_MCAST ? " mcast" : "", si->flags & SI_IS_MHOMED ? " mhomed" : "", si->flags & SI_IS_VIRTUAL ? " virtual" : "");
146 146
 				}
147 147
 				cnt = strlen(buf);
148 148
 			}else{
... ...
@@ -157,9 +157,9 @@ static void ipsec_print_all_socket_lists()
157 157
 				}
158 158
 
159 159
 				if(si->port_no_str.s){
160
-					sprintf(buf + cnt, ":%s%s%s", si->port_no_str.s, si->flags & SI_IS_MCAST ? " mcast" : "", si->flags & SI_IS_MHOMED? " mhomed" : "");
160
+					sprintf(buf + cnt, ":%s%s%s%s", si->port_no_str.s, si->flags & SI_IS_MCAST ? " mcast" : "", si->flags & SI_IS_MHOMED ? " mhomed" : "", si->flags & SI_IS_VIRTUAL ? " virtual" : "");
161 161
 				}else{
162
-					sprintf(buf + cnt, ":%u%s%s", si->port_no, si->flags & SI_IS_MCAST ? " mcast" : "", si->flags & SI_IS_MHOMED? " mhomed" : "");
162
+					sprintf(buf + cnt, ":%u%s%s%s", si->port_no, si->flags & SI_IS_MCAST ? " mcast" : "", si->flags & SI_IS_MHOMED ? " mhomed" : "", si->flags & SI_IS_VIRTUAL ? " virtual" : "");
163 163
 				}
164 164
 				cnt = strlen(buf);
165 165