summaryrefslogtreecommitdiff
blob: c1be28cbc0dba72f375604007d9fe42621bb3179 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
From 858da540f70a4411ad8fbe7144cef6ce9da18f89 Mon Sep 17 00:00:00 2001
From: wouter <wouter@be551aaa-1e26-0410-a405-d3ace91eadb9>
Date: Mon, 5 Jan 2015 13:51:22 +0000
Subject: [PATCH] - Fix #634: fix fail to start on Linux LTS 3.14.X, ignores
 missing   IP_MTU_DISCOVER OMIT option.

--- a/services/listen_dnsport.c
+++ b/services/listen_dnsport.c
@@ -368,29 +368,47 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
  * (and also uses the interface mtu to determine the size of the packets).
  * So there won't be any EMSGSIZE error.  Against DNS fragmentation attacks.
  * FreeBSD already has same semantics without setting the option. */
-#    if defined(IP_PMTUDISC_OMIT)
-		int action = IP_PMTUDISC_OMIT;
-#    else
-		int action = IP_PMTUDISC_DONT;
-#    endif
+		int omit_set = 0;
+		int action;
+#   if defined(IP_PMTUDISC_OMIT)
+		action = IP_PMTUDISC_OMIT;
 		if (setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, 
 			&action, (socklen_t)sizeof(action)) < 0) {
-			log_err("setsockopt(..., IP_MTU_DISCOVER, "
-#    if defined(IP_PMTUDISC_OMIT)
-				"IP_PMTUDISC_OMIT"
+
+			if (errno != EINVAL) {
+				log_err("setsockopt(..., IP_MTU_DISCOVER, IP_PMTUDISC_OMIT...) failed: %s",
+					strerror(errno));
+
+#    ifndef USE_WINSOCK
+				close(s);
 #    else
-				"IP_PMTUDISC_DONT"
+				closesocket(s);
 #    endif
-				"...) failed: %s",
-				strerror(errno));
+				*noproto = 0;
+				*inuse = 0;
+				return -1;
+			}
+		}
+		else
+		{
+		    omit_set = 1;
+		}
+#   endif
+		if (omit_set == 0) {
+   			action = IP_PMTUDISC_DONT;
+			if (setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER,
+				&action, (socklen_t)sizeof(action)) < 0) {
+				log_err("setsockopt(..., IP_MTU_DISCOVER, IP_PMTUDISC_DONT...) failed: %s",
+					strerror(errno));
 #    ifndef USE_WINSOCK
-			close(s);
+				close(s);
 #    else
-			closesocket(s);
+				closesocket(s);
 #    endif
-			*noproto = 0;
-			*inuse = 0;
-			return -1;
+				*noproto = 0;
+				*inuse = 0;
+				return -1;
+			}
 		}
 #  elif defined(IP_DONTFRAG)
 		int off = 0;