1 |
floppym 12/12/26 04:14:30 |
2 |
|
3 |
Added: xl2tpd-1.3.1-kernelmode.patch |
4 |
xl2tpd-1.3.1-no-type-punning-b119c0da.patch |
5 |
Log: |
6 |
Add fix for kernel mode by Sergey Fionov, resolves bug 441828 by nE0sIghT. Cherry-pick a patch from upstream to avoid type-punning. |
7 |
|
8 |
(Portage version: 2.2.0_alpha149/cvs/Linux x86_64, signed Manifest commit with key 0BBEEA1FEA4843A4) |
9 |
|
10 |
Revision Changes Path |
11 |
1.1 net-dialup/xl2tpd/files/xl2tpd-1.3.1-kernelmode.patch |
12 |
|
13 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/net-dialup/xl2tpd/files/xl2tpd-1.3.1-kernelmode.patch?rev=1.1&view=markup |
14 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/net-dialup/xl2tpd/files/xl2tpd-1.3.1-kernelmode.patch?rev=1.1&content-type=text/plain |
15 |
|
16 |
Index: xl2tpd-1.3.1-kernelmode.patch |
17 |
=================================================================== |
18 |
https://bugs.gentoo.org/show_bug.cgi?id=441828 |
19 |
|
20 |
Based on Fedora patch |
21 |
http://pkgs.fedoraproject.org/cgit/xl2tpd.git/plain/xl2tpd-1.3.1-kernelmode.patch |
22 |
|
23 |
Which is based on a patch by Sergey Fionov (sigwall) |
24 |
https://github.com/sigwall/overlay/blob/master/net-dialup/xl2tpd/files/xl2tpd-1.3.0-kernel.patch |
25 |
|
26 |
diff --git a/call.c b/call.c |
27 |
index d1b1858..b672f91 100644 |
28 |
--- a/call.c |
29 |
+++ b/call.c |
30 |
@@ -680,6 +680,8 @@ struct call *get_call (int tunnel, int call, struct in_addr addr, int port, |
31 |
st->peer.sin_port = port; |
32 |
st->refme = refme; |
33 |
st->refhim = refhim; |
34 |
+ st->udp_fd = -1; |
35 |
+ st->pppox_fd = -1; |
36 |
bcopy (&addr, &st->peer.sin_addr, sizeof (addr)); |
37 |
st->next = tunnels.head; |
38 |
tunnels.head = st; |
39 |
diff --git a/control.c b/control.c |
40 |
index 6a41143..8937f2e 100644 |
41 |
--- a/control.c |
42 |
+++ b/control.c |
43 |
@@ -596,6 +596,9 @@ int control_finish (struct tunnel *t, struct call *c) |
44 |
if (gconfig.debug_state) |
45 |
l2tp_log (LOG_DEBUG, "%s: sending SCCCN\n", __FUNCTION__); |
46 |
control_xmit (buf); |
47 |
+ |
48 |
+ connect_pppol2tp(t); |
49 |
+ |
50 |
/* Schedule a HELLO */ |
51 |
tv.tv_sec = HELLO_DELAY; |
52 |
tv.tv_usec = 0; |
53 |
@@ -608,6 +611,7 @@ int control_finish (struct tunnel *t, struct call *c) |
54 |
"Connection established to %s, %d. Local: %d, Remote: %d (ref=%u/%u).\n", |
55 |
IPADDY (t->peer.sin_addr), |
56 |
ntohs (t->peer.sin_port), t->ourtid, t->tid, t->refme, t->refhim); |
57 |
+ |
58 |
if (t->lac) |
59 |
{ |
60 |
/* This is part of a LAC, so we want to go ahead |
61 |
@@ -635,6 +639,9 @@ int control_finish (struct tunnel *t, struct call *c) |
62 |
IPADDY (t->peer.sin_addr), |
63 |
ntohs (t->peer.sin_port), t->ourtid, t->tid, t->refme, t->refhim, |
64 |
t->lns->entname); |
65 |
+ |
66 |
+ connect_pppol2tp(t); |
67 |
+ |
68 |
/* Schedule a HELLO */ |
69 |
tv.tv_sec = HELLO_DELAY; |
70 |
tv.tv_usec = 0; |
71 |
diff --git a/l2tp.h b/l2tp.h |
72 |
index ac22f3f..0062095 100644 |
73 |
--- a/l2tp.h |
74 |
+++ b/l2tp.h |
75 |
@@ -167,6 +167,8 @@ struct tunnel |
76 |
int ourrws; /* Receive Window Size */ |
77 |
int rxspeed; /* Receive bps */ |
78 |
int txspeed; /* Transmit bps */ |
79 |
+ int udp_fd; /* UDP fd */ |
80 |
+ int pppox_fd; /* PPPOX tunnel fd */ |
81 |
struct call *self; |
82 |
struct lns *lns; /* LNS that owns us */ |
83 |
struct lac *lac; /* LAC that owns us */ |
84 |
@@ -220,6 +222,7 @@ extern void control_xmit (void *); |
85 |
extern int ppd; |
86 |
extern int switch_io; /* jz */ |
87 |
extern int control_fd; |
88 |
+extern int connect_pppol2tp(struct tunnel *t); |
89 |
extern int start_pppd (struct call *c, struct ppp_opts *); |
90 |
extern void magic_lac_dial (void *); |
91 |
extern int get_entropy (unsigned char *, int); |
92 |
diff --git a/network.c b/network.c |
93 |
index 82aedd7..8a3fec2 100644 |
94 |
--- a/network.c |
95 |
+++ b/network.c |
96 |
@@ -22,6 +22,7 @@ |
97 |
#include <unistd.h> |
98 |
#include <stdlib.h> |
99 |
#include <sys/ioctl.h> |
100 |
+#include <sys/wait.h> |
101 |
#ifndef LINUX |
102 |
# include <sys/uio.h> |
103 |
#endif |
104 |
@@ -36,7 +37,6 @@ int server_socket; /* Server socket */ |
105 |
int kernel_support; /* Kernel Support there or not? */ |
106 |
#endif |
107 |
|
108 |
- |
109 |
int init_network (void) |
110 |
{ |
111 |
long arg; |
112 |
@@ -45,6 +45,7 @@ int init_network (void) |
113 |
server.sin_family = AF_INET; |
114 |
server.sin_addr.s_addr = gconfig.listenaddr; |
115 |
server.sin_port = htons (gconfig.port); |
116 |
+ int flags; |
117 |
if ((server_socket = socket (PF_INET, SOCK_DGRAM, 0)) < 0) |
118 |
{ |
119 |
l2tp_log (LOG_CRIT, "%s: Unable to allocate socket. Terminating.\n", |
120 |
@@ -52,6 +53,10 @@ int init_network (void) |
121 |
return -EINVAL; |
122 |
}; |
123 |
|
124 |
+ flags = 1; |
125 |
+ setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &flags, sizeof(flags)); |
126 |
+ setsockopt(server_socket, SOL_SOCKET, SO_NO_CHECK, &flags, sizeof(flags)); |
127 |
+ |
128 |
if (bind (server_socket, (struct sockaddr *) &server, sizeof (server))) |
129 |
{ |
130 |
close (server_socket); |
131 |
@@ -94,7 +99,7 @@ int init_network (void) |
132 |
int kernel_fd = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OL2TP); |
133 |
if (kernel_fd < 0) |
134 |
{ |
135 |
- l2tp_log (LOG_INFO, "L2TP kernel support not detected.\n"); |
136 |
+ l2tp_log (LOG_INFO, "L2TP kernel support not detected (try modprobing l2tp_ppp and pppol2tp)\n"); |
137 |
kernel_support = 0; |
138 |
} |
139 |
else |
140 |
@@ -321,6 +326,11 @@ int build_fdset (fd_set *readfds) |
141 |
|
142 |
while (tun) |
143 |
{ |
144 |
+ if (tun->udp_fd > -1) { |
145 |
+ if (tun->udp_fd > max) |
146 |
+ max = tun->udp_fd; |
147 |
+ FD_SET (tun->udp_fd, readfds); |
148 |
+ } |
149 |
call = tun->call_head; |
150 |
while (call) |
151 |
{ |
152 |
@@ -390,6 +400,8 @@ void network_thread () |
153 |
struct iovec iov; |
154 |
char cbuf[256]; |
155 |
unsigned int refme, refhim; |
156 |
+ int * currentfd; |
157 |
+ int server_socket_processed; |
158 |
|
159 |
/* This one buffer can be recycled for everything except control packets */ |
160 |
buf = new_buf (MAX_RECV_SIZE); |
161 |
@@ -428,7 +440,21 @@ void network_thread () |
162 |
{ |
163 |
do_control (); |
164 |
} |
165 |
- if (FD_ISSET (server_socket, &readfds)) |
166 |
+ server_socket_processed = 0; |
167 |
+ currentfd = NULL; |
168 |
+ st = tunnels.head; |
169 |
+ while (st || !server_socket_processed) { |
170 |
+ if (st && (st->udp_fd == -1)) { |
171 |
+ st=st->next; |
172 |
+ continue; |
173 |
+ } |
174 |
+ if (st) { |
175 |
+ currentfd = &st->udp_fd; |
176 |
+ } else { |
177 |
+ currentfd = &server_socket; |
178 |
+ server_socket_processed = 1; |
179 |
+ } |
180 |
+ if (FD_ISSET (*currentfd, &readfds)) |
181 |
{ |
182 |
/* |
183 |
* Okay, now we're ready for reading and processing new data. |
184 |
@@ -456,12 +482,19 @@ void network_thread () |
185 |
msgh.msg_flags = 0; |
186 |
|
187 |
/* Receive one packet. */ |
188 |
- recvsize = recvmsg(server_socket, &msgh, 0); |
189 |
+ recvsize = recvmsg(*currentfd, &msgh, 0); |
190 |
|
191 |
if (recvsize < MIN_PAYLOAD_HDR_LEN) |
192 |
{ |
193 |
if (recvsize < 0) |
194 |
{ |
195 |
+ if (errno == ECONNREFUSED) { |
196 |
+ close(*currentfd); |
197 |
+ } |
198 |
+ if ((errno == ECONNREFUSED) || |
199 |
+ (errno == EBADF)) { |
200 |
+ *currentfd = -1; |
201 |
+ } |
202 |
if (errno != EAGAIN) |
203 |
l2tp_log (LOG_WARNING, |
204 |
"%s: recvfrom returned error %d (%s)\n", |
205 |
@@ -566,6 +599,8 @@ void network_thread () |
206 |
} |
207 |
}; |
208 |
} |
209 |
+ if (st) st=st->next; |
210 |
+ } |
211 |
|
212 |
/* |
213 |
* finished obvious sources, look for data from PPP connections. |
214 |
@@ -638,3 +673,82 @@ void network_thread () |
215 |
} |
216 |
|
217 |
} |
218 |
+ |
219 |
+int connect_pppol2tp(struct tunnel *t) { |
220 |
+#ifdef USE_KERNEL |
221 |
+ if (kernel_support) { |
222 |
+ int ufd = -1, fd2 = -1; |
223 |
+ int flags; |
224 |
+ struct sockaddr_pppol2tp sax; |
225 |
+ |
226 |
+ struct sockaddr_in server; |
227 |
+ server.sin_family = AF_INET; |
228 |
+ server.sin_addr.s_addr = gconfig.listenaddr; |
229 |
+ server.sin_port = htons (gconfig.port); |
230 |
+ if ((ufd = socket (PF_INET, SOCK_DGRAM, 0)) < 0) |
231 |
+ { |
232 |
+ l2tp_log (LOG_CRIT, "%s: Unable to allocate UDP socket. Terminating.\n", |
233 |
+ __FUNCTION__); |
234 |
+ return -EINVAL; |
235 |
+ }; |
236 |
+ |
237 |
+ flags=1; |
238 |
+ setsockopt(ufd, SOL_SOCKET, SO_REUSEADDR, &flags, sizeof(flags)); |
239 |
+ setsockopt(ufd, SOL_SOCKET, SO_NO_CHECK, &flags, sizeof(flags)); |
240 |
+ |
241 |
+ if (bind (ufd, (struct sockaddr *) &server, sizeof (server))) |
242 |
+ { |
243 |
+ close (ufd); |
244 |
+ l2tp_log (LOG_CRIT, "%s: Unable to bind UDP socket: %s. Terminating.\n", |
245 |
+ __FUNCTION__, strerror(errno), errno); |
246 |
+ return -EINVAL; |
247 |
+ }; |
248 |
+ server = t->peer; |
249 |
+ flags = fcntl(ufd, F_GETFL); |
250 |
+ if (flags == -1 || fcntl(ufd, F_SETFL, flags | O_NONBLOCK) == -1) { |
251 |
+ l2tp_log (LOG_WARNING, "%s: Unable to set UDP socket nonblock.\n", |
252 |
+ __FUNCTION__); |
253 |
+ return -EINVAL; |
254 |
+ } |
255 |
+ if (connect (ufd, (struct sockaddr *) &server, sizeof(server)) < 0) { |
256 |
+ l2tp_log (LOG_CRIT, "%s: Unable to connect UDP peer. Terminating.\n", |
257 |
+ __FUNCTION__); |
258 |
+ return -EINVAL; |
259 |
+ } |
260 |
+ |
261 |
+ t->udp_fd=ufd; |
262 |
+ |
263 |
+ fd2 = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OL2TP); |
264 |
+ if (fd2 < 0) { |
265 |
+ l2tp_log (LOG_WARNING, "%s: Unable to allocate PPPoL2TP socket.\n", |
266 |
+ __FUNCTION__); |
267 |
+ return -EINVAL; |
268 |
+ } |
269 |
+ flags = fcntl(fd2, F_GETFL); |
270 |
+ if (flags == -1 || fcntl(fd2, F_SETFL, flags | O_NONBLOCK) == -1) { |
271 |
+ l2tp_log (LOG_WARNING, "%s: Unable to set PPPoL2TP socket nonblock.\n", |
272 |
+ __FUNCTION__); |
273 |
+ return -EINVAL; |
274 |
+ } |
275 |
+ sax.sa_family = AF_PPPOX; |
276 |
+ sax.sa_protocol = PX_PROTO_OL2TP; |
277 |
+ sax.pppol2tp.pid = 0; |
278 |
+ sax.pppol2tp.fd = t->udp_fd; |
279 |
+ sax.pppol2tp.addr.sin_addr.s_addr = t->peer.sin_addr.s_addr; |
280 |
+ sax.pppol2tp.addr.sin_port = t->peer.sin_port; |
281 |
+ sax.pppol2tp.addr.sin_family = AF_INET; |
282 |
+ sax.pppol2tp.s_tunnel = t->ourtid; |
283 |
+ sax.pppol2tp.s_session = 0; |
284 |
+ sax.pppol2tp.d_tunnel = t->tid; |
285 |
+ sax.pppol2tp.d_session = 0; |
286 |
+ if ((connect(fd2, (struct sockaddr *)&sax, sizeof(sax))) < 0) { |
287 |
+ l2tp_log (LOG_WARNING, "%s: Unable to connect PPPoL2TP socket. %d %s\n", |
288 |
+ __FUNCTION__, errno, strerror(errno)); |
289 |
+ close(fd2); |
290 |
+ return -EINVAL; |
291 |
+ } |
292 |
+ t->pppox_fd = fd2; |
293 |
+ } |
294 |
+#endif |
295 |
+ return 0; |
296 |
+} |
297 |
diff --git a/xl2tpd.c b/xl2tpd.c |
298 |
index e98c948..8d7d117 100644 |
299 |
--- a/xl2tpd.c |
300 |
+++ b/xl2tpd.c |
301 |
@@ -278,7 +278,11 @@ void death_handler (int signal) |
302 |
struct tunnel *st, *st2; |
303 |
int sec; |
304 |
l2tp_log (LOG_CRIT, "%s: Fatal signal %d received\n", __FUNCTION__, signal); |
305 |
+#ifdef USE_KERNEL |
306 |
+ if (kernel_support || signal != SIGTERM) { |
307 |
+#else |
308 |
if (signal != SIGTERM) { |
309 |
+#endif |
310 |
st = tunnels.head; |
311 |
while (st) |
312 |
{ |
313 |
@@ -349,7 +353,7 @@ int start_pppd (struct call *c, struct ppp_opts *opts) |
314 |
int flags; |
315 |
#endif |
316 |
int pos = 1; |
317 |
- int fd2; |
318 |
+ int fd2 = -1; |
319 |
#ifdef DEBUG_PPPD |
320 |
int x; |
321 |
#endif |
322 |
@@ -397,7 +401,7 @@ int start_pppd (struct call *c, struct ppp_opts *opts) |
323 |
sax.sa_family = AF_PPPOX; |
324 |
sax.sa_protocol = PX_PROTO_OL2TP; |
325 |
sax.pppol2tp.pid = 0; |
326 |
- sax.pppol2tp.fd = server_socket; |
327 |
+ sax.pppol2tp.fd = c->container->udp_fd; |
328 |
sax.pppol2tp.addr.sin_addr.s_addr = c->container->peer.sin_addr.s_addr; |
329 |
sax.pppol2tp.addr.sin_port = c->container->peer.sin_port; |
330 |
sax.pppol2tp.addr.sin_family = AF_INET; |
331 |
@@ -408,6 +412,7 @@ int start_pppd (struct call *c, struct ppp_opts *opts) |
332 |
if (connect(fd2, (struct sockaddr *)&sax, sizeof(sax)) < 0) { |
333 |
l2tp_log (LOG_WARNING, "%s: Unable to connect PPPoL2TP socket.\n", |
334 |
__FUNCTION__); |
335 |
+ close(fd2); |
336 |
return -EINVAL; |
337 |
} |
338 |
stropt[pos++] = strdup ("plugin"); |
339 |
@@ -484,7 +489,7 @@ int start_pppd (struct call *c, struct ppp_opts *opts) |
340 |
dup2 (fd2, 0); |
341 |
dup2 (fd2, 1); |
342 |
close(fd2); |
343 |
- |
344 |
+ } |
345 |
/* close all the calls pty fds */ |
346 |
st = tunnels.head; |
347 |
while (st) |
348 |
@@ -492,12 +497,17 @@ int start_pppd (struct call *c, struct ppp_opts *opts) |
349 |
sc = st->call_head; |
350 |
while (sc) |
351 |
{ |
352 |
- close (sc->fd); |
353 |
+#ifdef USE_KERNEL |
354 |
+ if (kernel_support) { |
355 |
+ close(st->udp_fd); /* tunnel UDP fd */ |
356 |
+ close(st->pppox_fd); /* tunnel PPPoX fd */ |
357 |
+ } else |
358 |
+#endif |
359 |
+ close (sc->fd); /* call pty fd */ |
360 |
sc = sc->next; |
361 |
} |
362 |
st = st->next; |
363 |
} |
364 |
- } |
365 |
|
366 |
/* close the UDP socket fd */ |
367 |
close (server_socket); |
368 |
@@ -615,6 +625,10 @@ void destroy_tunnel (struct tunnel *t) |
369 |
the memory pointed to by t->chal_us.vector at some other place */ |
370 |
if (t->chal_them.vector) |
371 |
free (t->chal_them.vector); |
372 |
+ if (t->pppox_fd > -1 ) |
373 |
+ close (t->pppox_fd); |
374 |
+ if (t->udp_fd > -1 ) |
375 |
+ close (t->udp_fd); |
376 |
free (t); |
377 |
free (me); |
378 |
} |
379 |
|
380 |
|
381 |
|
382 |
1.1 net-dialup/xl2tpd/files/xl2tpd-1.3.1-no-type-punning-b119c0da.patch |
383 |
|
384 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/net-dialup/xl2tpd/files/xl2tpd-1.3.1-no-type-punning-b119c0da.patch?rev=1.1&view=markup |
385 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/net-dialup/xl2tpd/files/xl2tpd-1.3.1-no-type-punning-b119c0da.patch?rev=1.1&content-type=text/plain |
386 |
|
387 |
Index: xl2tpd-1.3.1-no-type-punning-b119c0da.patch |
388 |
=================================================================== |
389 |
commit b119c0daf006dcf9d960e5a98902d619cdfdf485 |
390 |
Author: Ted Phelps <phelps@××××××.com> |
391 |
Date: Thu Dec 20 17:53:54 2012 +1100 |
392 |
|
393 |
Avoid type punning: it makes gcc grumpy. |
394 |
|
395 |
Compilers don't like it when we write to memory as one type and read from it |
396 |
as another. Use memcpy instead of typecast games to avoid doing that. |
397 |
|
398 |
diff --git a/md5.c b/md5.c |
399 |
index 175edcc..cb056da 100644 |
400 |
--- a/md5.c |
401 |
+++ b/md5.c |
402 |
@@ -161,8 +161,7 @@ void MD5Final (unsigned char digest[16], struct MD5Context *ctx) |
403 |
byteReverse (ctx->in, 14); |
404 |
|
405 |
/* Append length in bits and transform */ |
406 |
- ((uint32 *) ctx->in)[14] = ctx->bits[0]; |
407 |
- ((uint32 *) ctx->in)[15] = ctx->bits[1]; |
408 |
+ memcpy(ctx->in + 14 * sizeof(uint32), ctx->bits, sizeof(ctx->bits)); |
409 |
|
410 |
MD5Transform (ctx->buf, (uint32 *) ctx->in); |
411 |
byteReverse ((unsigned char *) ctx->buf, 4); |