... | ... |
@@ -720,7 +720,7 @@ new config variables: |
720 | 720 |
dropping the connection. Linux only. |
721 | 721 |
tcp_crlf_ping = yes | no (set by default) - enable CRLF keepalives aka |
722 | 722 |
SIP outbound. |
723 |
- pmtu_discovery = 0 | 1 (default 0) - set DF bit in outbound IP if enabled |
|
723 |
+ pmtu_discovery = 0 | 1 (default 0) - set DF bit in outbound IPv4 if enabled |
|
724 | 724 |
dns_srv_lb = yes | no (default no) - enable dns srv weight based load |
725 | 725 |
balancing (see doc/dns.txt) |
726 | 726 |
dns_try_naptr = yes | no (default no) - enable naptr support |
... | ... |
@@ -329,22 +329,46 @@ int udp_init(struct socket_info* sock_info) |
329 | 329 |
} |
330 | 330 |
|
331 | 331 |
#if defined (__OS_linux) && defined(UDP_ERRORS) |
332 |
+ /* Ask for the ability to recvmsg (...,MSG_ERRQUEUE) for immediate |
|
333 |
+ * resend when hitting Path MTU limits. */ |
|
332 | 334 |
optval=1; |
333 | 335 |
/* enable error receiving on unconnected sockets */ |
334 |
- if(setsockopt(sock_info->socket, SOL_IP, IP_RECVERR, |
|
336 |
+ if (addr->s.sa_family==AF_INET){ |
|
337 |
+ if(setsockopt(sock_info->socket, SOL_IP, IP_RECVERR, |
|
335 | 338 |
(void*)&optval, sizeof(optval)) ==-1){ |
336 |
- LM_ERR("setsockopt: %s\n", strerror(errno)); |
|
337 |
- goto error; |
|
339 |
+ LM_ERR("setsockopt: %s\n", strerror(errno)); |
|
340 |
+ goto error; |
|
341 |
+ } |
|
342 |
+ } else if (addr->s.sa_family==AF_INET6){ |
|
343 |
+ if(setsockopt(sock_info->socket, SOL_IPV6, IPV6_RECVERR, |
|
344 |
+ (void*)&optval, sizeof(optval)) ==-1){ |
|
345 |
+ LM_ERR("setsockopt: %s\n", strerror(errno)); |
|
346 |
+ goto error; |
|
347 |
+ } |
|
338 | 348 |
} |
339 | 349 |
#endif |
340 | 350 |
#if defined (__OS_linux) |
341 |
- /* if pmtu_discovery=1 then set DF bit and do Path MTU discovery |
|
342 |
- * disabled by default */ |
|
343 |
- optval= (pmtu_discovery) ? IP_PMTUDISC_DO : IP_PMTUDISC_DONT; |
|
344 |
- if(setsockopt(sock_info->socket, IPPROTO_IP, IP_MTU_DISCOVER, |
|
345 |
- (void*)&optval, sizeof(optval)) ==-1){ |
|
346 |
- LM_ERR("setsockopt: %s\n", strerror(errno)); |
|
347 |
- goto error; |
|
351 |
+ if (addr->s.sa_family==AF_INET){ |
|
352 |
+ /* If pmtu_discovery=1 then set DF bit and do Path MTU discovery |
|
353 |
+ * disabled by default. Specific to IPv4. */ |
|
354 |
+ optval= (pmtu_discovery) ? IP_PMTUDISC_DO : IP_PMTUDISC_DONT; |
|
355 |
+ if(setsockopt(sock_info->socket, IPPROTO_IP, IP_MTU_DISCOVER, |
|
356 |
+ (void*)&optval, sizeof(optval)) ==-1){ |
|
357 |
+ LM_ERR("setsockopt: %s\n", strerror(errno)); |
|
358 |
+ goto error; |
|
359 |
+ } |
|
360 |
+ } else if (addr->s.sa_family==AF_INET6){ |
|
361 |
+ /* Since IPv6 never fragments but sends ICMPv6 Packet too Big, |
|
362 |
+ * we always want to benefit from kernel Path MTU knowledge; |
|
363 |
+ * especially because our sockets are unconnected and cannot |
|
364 |
+ * learn this for themselves. Details in Issue #3119. */ |
|
365 |
+ optval= IPV6_PMTUDISC_WANT; |
|
366 |
+ if(setsockopt(sock_info->socket, IPPROTO_IPV6, |
|
367 |
+ IPV6_MTU_DISCOVER, |
|
368 |
+ (void*)&optval, sizeof(optval)) ==-1){ |
|
369 |
+ LM_ERR("setsockopt: %s\n", strerror(errno)); |
|
370 |
+ goto error; |
|
371 |
+ } |
|
348 | 372 |
} |
349 | 373 |
#endif |
350 | 374 |
|