Get ICMP type 3 to set the next-hop MTU

This commit is contained in:
Adrien Gallouët
2016-10-18 16:44:20 +00:00
parent c9f737197c
commit 0bb5be63b9
2 changed files with 31 additions and 1 deletions

2
mud

Submodule mud updated: 4c34454a23...b82534d54c

View File

@@ -310,6 +310,15 @@ int main (int argc, char **argv)
return 1; return 1;
} }
int icmp_fd = -1;
if (v4) {
icmp_fd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (icmp_fd==-1)
gt_log("couldn't create ICMP socket\n");
}
gt.state_fd = state_create(statefile); gt.state_fd = state_create(statefile);
if (statefile && gt.state_fd==-1) if (statefile && gt.state_fd==-1)
@@ -394,6 +403,9 @@ int main (int argc, char **argv)
while (!gt.quit) { while (!gt.quit) {
FD_SET(tun_fd, &rfds); FD_SET(tun_fd, &rfds);
if (icmp_fd!=-1)
FD_SET(icmp_fd, &rfds);
if (mud_can_pull(mud)) { if (mud_can_pull(mud)) {
FD_SET(mud_fd, &rfds); FD_SET(mud_fd, &rfds);
} else { } else {
@@ -414,6 +426,24 @@ int main (int argc, char **argv)
return 1; return 1;
} }
if (icmp_fd!=-1 && FD_ISSET(icmp_fd, &rfds)) {
uint8_t buf[1024];
struct sockaddr_storage ss;
socklen_t sl = sizeof(ss);
ssize_t r = recvfrom(icmp_fd, buf, sizeof(buf), 0, (struct sockaddr *)&ss, &sl);
if (r>=8) {
struct ip_common ic;
if (!ip_get_common(&ic, buf, r) && ic.proto==1) {
unsigned char *data = &buf[ic.hdr_size];
if (data[0]==3) {
int new_mtu = (data[6]<<8)|data[7];
gt_log("received MTU from ICMP: %i\n", new_mtu);
mud_set_mtu(mud, new_mtu-50);
}
}
}
}
if (mud_is_up(mud)) { if (mud_is_up(mud)) {
if (!started) { if (!started) {
state_send(gt.state_fd, "STARTED", tun_name); state_send(gt.state_fd, "STARTED", tun_name);