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