Browse code

Merge 0f90cff05c1a448eb2f85f83b4c087ab32ede112 into 9f3d1c274ad926e9640d0091c9702a34f8b2e539

vanrein authored on 10/08/2022 09:44:34 • GitHub committed on 10/08/2022 09:44:34
Showing 2 changed files
... ...
@@ -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