Bug Summary

File:src/usr.sbin/npppd/npppd/../l2tp/l2tpd.c
Warning:line 267, column 2
Value stored to 'sock' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name l2tpd.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.sbin/npppd/npppd/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.sbin/npppd/npppd/../common -I /usr/src/usr.sbin/npppd/npppd -I /usr/src/usr.sbin/npppd/npppd/../pptp -I /usr/src/usr.sbin/npppd/npppd/../l2tp -I /usr/src/usr.sbin/npppd/npppd/../pppoe -D USE_NPPPD_PPTP -D USE_NPPPD_L2TP -D USE_NPPPD_PPPOE -D __COPYRIGHT(x)= -D __RCSID(x)= -D NPPPD_MAX_IFACE=8 -D NPPPD_MAX_POOL=8 -D USE_NPPPD_MPPE -D USE_NPPPD_PIPEX -D USE_NPPPD_RADIUS -D USE_SA_COOKIE -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/npppd/npppd/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.sbin/npppd/npppd/../l2tp/l2tpd.c
1/* $OpenBSD: l2tpd.c,v 1.22 2021/03/29 03:54:39 yasuoka Exp $ */
2
3/*-
4 * Copyright (c) 2009 Internet Initiative Japan Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28/**@file L2TP(Layer Two Tunneling Protocol "L2TP") / RFC2661 */
29/* $Id: l2tpd.c,v 1.22 2021/03/29 03:54:39 yasuoka Exp $ */
30#include <sys/types.h>
31#include <sys/socket.h>
32#include <sys/time.h>
33#include <netinet/in.h>
34#include <netinet/udp.h>
35#include <stdlib.h>
36#include <arpa/inet.h>
37#include <stdio.h>
38#include <unistd.h>
39#include <netdb.h>
40#include <syslog.h>
41#include <signal.h>
42#include <string.h>
43#include <fcntl.h>
44#include <errno(*__errno()).h>
45#include <stdarg.h>
46#include <event.h>
47
48#ifdef USE_LIBSOCKUTIL
49#include <seil/sockfromto.h>
50#else
51#include "recvfromto.h"
52#endif
53
54#include "bytebuf.h"
55#include "hash.h"
56#include "slist.h"
57#include "debugutil.h"
58#include "l2tp.h"
59#include "l2tp_subr.h"
60#include "l2tp_local.h"
61#include "addr_range.h"
62#include "net_utils.h"
63
64#ifdef L2TPD_DEBUG
65#define L2TPD_ASSERT(x) ASSERT(x)((void)0);
66#define L2TPD_DBG(x) l2tpd_log x
67#else
68#define L2TPD_ASSERT(x)
69#endif
70#define L2TPD_IPSEC_POLICY_IN"in ipsec esp/transport//require" "in ipsec esp/transport//require"
71#define L2TPD_IPSEC_POLICY_OUT"out ipsec esp/transport//require" "out ipsec esp/transport//require"
72
73static void l2tpd_io_event (int, short, void *);
74static inline int short_cmp (const void *, const void *);
75static inline uint32_t short_hash (const void *, int);
76
77/* sequence # of l2tpd ID */
78static u_int l2tpd_id_seq = 0;
79
80/* L2TP daemon instance */
81
82/**
83 * initialize L2TP daemon instance
84 * <p>
85 * {@link _l2tpd#bind_sin} will return with .sin_family = AF_INET,
86 * .sin_port = 1701 and .sin_len = "appropriate value"
87 * </p>
88 */
89int
90l2tpd_init(l2tpd *_this)
91{
92 int i, off;
93 u_int id;
94
95 L2TPD_ASSERT(_this != NULL);
96 memset(_this, 0, sizeof(l2tpd));
97
98 slist_init(&_this->listener);
99 slist_init(&_this->free_session_id_list);
100
101 _this->id = l2tpd_id_seq++;
102
103 if ((_this->ctrl_map = hash_create(short_cmp, short_hash,
104 L2TPD_TUNNEL_HASH_SIZ127)) == NULL((void *)0)) {
105 log_printf(LOG_ERR3, "hash_create() failed in %s(): %m",
106 __func__);
107 return 1;
108 }
109
110 if (slist_add(&_this->free_session_id_list,
111 (void *)L2TP_SESSION_ID_SHUFFLE_MARK0x10000000) == NULL((void *)0)) {
112 l2tpd_log(_this, LOG_ERR3, "slist_add() failed on %s(): %m",
113 __func__);
114 return 1;
115 }
116 off = arc4random() & L2TP_SESSION_ID_MASK0x00007fff;
117 for (i = 0; i < L2TP_NCALL10000; i++) {
118 id = (i + off) & L2TP_SESSION_ID_MASK0x00007fff;
119 if (id == 0)
120 id = (off - 1) & L2TP_SESSION_ID_MASK0x00007fff;
121 if (slist_add(&_this->free_session_id_list,
122 (void *)(uintptr_t)id) == NULL((void *)0)) {
123 l2tpd_log(_this, LOG_ERR3,
124 "slist_add() failed on %s(): %m", __func__);
125 return 1;
126 }
127 }
128 _this->purge_ipsec_sa = 1;
129 _this->state = L2TPD_STATE_INIT0;
130
131 return 0;
132}
133
134/*
135 * Add a {@link :l2tpd_listener} to the {@link ::l2tpd L2TP daemon}
136 * @param _this {@link ::l2tpd L2TP daemon}
137 * @param idx index of the lisnter
138 * @param tun_name tunnel name (ex. "L2TP")
139 * @param bindaddr bind address
140 */
141int
142l2tpd_add_listener(l2tpd *_this, int idx, struct l2tp_conf *conf,
143 struct sockaddr *addr)
144{
145 l2tpd_listener *plistener, *plsnr;
146
147 plistener = NULL((void *)0);
148 if (idx == 0 && slist_length(&_this->listener) > 0) {
149 slist_itr_first(&_this->listener);
150 while (slist_itr_has_next(&_this->listener)) {
151 slist_itr_next(&_this->listener);
152 plsnr = slist_itr_remove(&_this->listener);
153 L2TPD_ASSERT(plsnr != NULL);
154 L2TPD_ASSERT(plsnr->sock == -1);
155 free(plsnr);
156 }
157 }
158 L2TPD_ASSERT(slist_length(&_this->listener) == idx);
159 if (slist_length(&_this->listener) != idx) {
160 l2tpd_log(_this, LOG_ERR3,
161 "Invalid argument error on %s(): idx must be %d but %d",
162 __func__, slist_length(&_this->listener), idx);
163 goto fail;
164 }
165 if ((plistener = calloc(1, sizeof(l2tpd_listener))) == NULL((void *)0)) {
166 l2tpd_log(_this, LOG_ERR3, "calloc() failed in %s: %m",
167 __func__);
168 goto fail;
169 }
170 L2TPD_ASSERT(sizeof(plistener->bind) >= addr->sa_len);
171 memcpy(&plistener->bind, addr, addr->sa_len);
172
173 if (plistener->bind.sin6.sin6_port == 0)
174 plistener->bind.sin6.sin6_port = htons(L2TPD_DEFAULT_UDP_PORT)(__uint16_t)(__builtin_constant_p(1701) ? (__uint16_t)(((__uint16_t
)(1701) & 0xffU) << 8 | ((__uint16_t)(1701) & 0xff00U
) >> 8) : __swap16md(1701))
;
175
176 plistener->sock = -1;
177 plistener->self = _this;
178 plistener->index = idx;
179 plistener->conf = conf;
180 strlcpy(plistener->tun_name, conf->name, sizeof(plistener->tun_name));
181
182 if (slist_add(&_this->listener, plistener) == NULL((void *)0)) {
183 l2tpd_log(_this, LOG_ERR3, "slist_add() failed in %s: %m",
184 __func__);
185 goto fail;
186 }
187 return 0;
188fail:
189 free(plistener);
190 return 1;
191}
192
193/* finalize L2TP daemon instance */
194void
195l2tpd_uninit(l2tpd *_this)
196{
197 l2tpd_listener *plsnr;
198
199 L2TPD_ASSERT(_this != NULL);
200
201 slist_fini(&_this->free_session_id_list);
202 if (_this->ctrl_map != NULL((void *)0)) {
203 hash_free(_this->ctrl_map);
204 _this->ctrl_map = NULL((void *)0);
205 }
206
207 slist_itr_first(&_this->listener);
208 while (slist_itr_has_next(&_this->listener)) {
209 plsnr = slist_itr_next(&_this->listener);
210 L2TPD_ASSERT(plsnr != NULL);
211 L2TPD_ASSERT(plsnr->sock == -1);
212 free(plsnr);
213 }
214 slist_fini(&_this->listener);
215
216 event_del(&_this->ev_timeout); /* just in case */
217 _this->state = L2TPD_STATE_STOPPED3;
218}
219
220/** assign the call to the l2tpd */
221int
222l2tpd_assign_call(l2tpd *_this, l2tp_call *call)
223{
224 int shuffle_cnt;
225 u_int session_id;
226
227 shuffle_cnt = 0;
228 do {
229 session_id = (uintptr_t)slist_remove_first(
230 &_this->free_session_id_list);
231 if (session_id != L2TP_SESSION_ID_SHUFFLE_MARK0x10000000)
232 break;
233 L2TPD_ASSERT(shuffle_cnt == 0);
234 if (shuffle_cnt++ > 0) {
235 l2tpd_log(_this, LOG_ERR3,
236 "unexpected error in %s(): free_session_id_list "
237 "full", __func__);
238 slist_add(&_this->free_session_id_list,
239 (void *)L2TP_SESSION_ID_SHUFFLE_MARK0x10000000);
240 return 1;
241 }
242 slist_shuffle(&_this->free_session_id_list);
243 slist_add(&_this->free_session_id_list,
244 (void *)L2TP_SESSION_ID_SHUFFLE_MARK0x10000000);
245 } while (1);
246 call->id = session_id;
247
248 return 0;
249}
250
251/* this function will be called when the call is released */
252void
253l2tpd_release_call(l2tpd *_this, l2tp_call *call)
254{
255 slist_add(&_this->free_session_id_list, (void *)(uintptr_t)call->id);
256}
257
258/* start l2tpd listener */
259static int
260l2tpd_listener_start(l2tpd_listener *_this)
261{
262 l2tpd *_l2tpd;
263 int af, lvl, opt, sock, ival;
264 char hbuf[NI_MAXHOST256 + NI_MAXSERV32 + 16];
265
266 _l2tpd = _this->self;
267 sock = -1;
Value stored to 'sock' is never read
268 af = _this->bind.sin6.sin6_family;
269 lvl = (af == AF_INET2)? IPPROTO_IP0 : IPPROTO_IPV641;
270
271 if (_this->tun_name[0] == '\0')
272 strlcpy(_this->tun_name, L2TPD_DEFAULT_LAYER2_LABEL"L2TP",
273 sizeof(_this->tun_name));
274 if ((sock = socket(_this->bind.sin6.sin6_family,
275 SOCK_DGRAM2 | SOCK_NONBLOCK0x4000, IPPROTO_UDP17)) < 0) {
276 l2tpd_log(_l2tpd, LOG_ERR3,
277 "socket() failed in %s(): %m", __func__);
278 goto fail;
279 }
280#if defined(IP_STRICT_RCVIF) && defined(USE_STRICT_RCVIF)
281 ival = 1;
282 if (setsockopt(sock, IPPROTO_IP0, IP_STRICT_RCVIF, &ival, sizeof(ival))
283 != 0)
284 l2tpd_log(_l2tpd, LOG_WARNING4,
285 "%s(): setsockopt(IP_STRICT_RCVIF) failed: %m", __func__);
286#endif
287 ival = 1;
288 if (setsockopt(sock, SOL_SOCKET0xffff, SO_REUSEPORT0x0200, &ival, sizeof(ival))
289 != 0) {
290 l2tpd_log(_l2tpd, LOG_ERR3,
291 "setsockopt(,,SO_REUSEPORT) failed in %s(): %m", __func__);
292 goto fail;
293 }
294 if (bind(sock, (struct sockaddr *)&_this->bind,
295 _this->bind.sin6.sin6_len) != 0) {
296 l2tpd_log(_l2tpd, LOG_ERR3, "Binding %s/udp: %m",
297 addrport_tostring((struct sockaddr *)&_this->bind,
298 _this->bind.sin6.sin6_len, hbuf, sizeof(hbuf)));
299 goto fail;
300 }
301#ifdef USE_LIBSOCKUTIL
302 if (setsockoptfromto(sock) != 0) {
303 l2tpd_log(_l2tpd, LOG_ERR3,
304 "setsockoptfromto() failed in %s(): %m", __func__);
305 goto fail;
306 }
307#else
308 opt = (af == AF_INET2)? IP_RECVDSTADDR7 : IPV6_RECVPKTINFO36;
309 ival = 1;
310 if (setsockopt(sock, lvl, opt, &ival, sizeof(ival)) != 0) {
311 l2tpd_log(_l2tpd, LOG_ERR3,
312 "setsockopt(,,IP{,V6}_RECVDSTADDR) failed in %s(): %m",
313 __func__);
314 goto fail;
315 }
316#endif
317#ifdef USE_SA_COOKIE1
318 if (af == AF_INET2) {
319 ival = 1;
320 if (setsockopt(sock, IPPROTO_IP0, IP_IPSECFLOWINFO36, &ival,
321 sizeof(ival)) != 0) {
322 l2tpd_log(_l2tpd, LOG_ERR3,
323 "setsockopt(,,IP_IPSECFLOWINFO) failed in %s(): %m",
324 __func__);
325 goto fail;
326 }
327 }
328#endif
329#ifdef IP_PIPEX34
330 opt = (af == AF_INET2)? IP_PIPEX34 : IPV6_PIPEX63;
331 ival = 1;
332 if (setsockopt(sock, lvl, opt, &ival, sizeof(ival)) != 0)
333 l2tpd_log(_l2tpd, LOG_WARNING4,
334 "%s(): setsockopt(IP{,V6}_PIPEX) failed: %m", __func__);
335#endif
336 if (_this->conf->require_ipsec) {
337#ifdef IP_IPSEC_POLICY
338 caddr_t ipsec_policy_in, ipsec_policy_out;
339
340 opt = (af == AF_INET2)? IP_IPSEC_POLICY : IPV6_IPSEC_POLICY;
341 /*
342 * Note: ipsec_set_policy() will assign the buffer for
343 * yacc parser stack, however it never free.
344 * it cause memory leak (-2000byte).
345 */
346 if ((ipsec_policy_in = ipsec_set_policy(L2TPD_IPSEC_POLICY_IN"in ipsec esp/transport//require",
347 strlen(L2TPD_IPSEC_POLICY_IN"in ipsec esp/transport//require"))) == NULL((void *)0)) {
348 l2tpd_log(_l2tpd, LOG_ERR3,
349 "ipsec_set_policy(L2TPD_IPSEC_POLICY_IN) failed "
350 "at %s(): %s: %m", __func__, ipsec_strerror());
351 } else if (setsockopt(sock, lvl, opt, ipsec_policy_in,
352 ipsec_get_policylen(ipsec_policy_in)) < 0) {
353 l2tpd_log(_l2tpd, LOG_WARNING4,
354 "setsockopt(,,IP_IPSEC_POLICY(in)) failed "
355 "in %s(): %m", __func__);
356 }
357 if ((ipsec_policy_out = ipsec_set_policy(L2TPD_IPSEC_POLICY_OUT"out ipsec esp/transport//require",
358 strlen(L2TPD_IPSEC_POLICY_OUT"out ipsec esp/transport//require"))) == NULL((void *)0)) {
359 l2tpd_log(_l2tpd, LOG_ERR3,
360 "ipsec_set_policy(L2TPD_IPSEC_POLICY_OUT) failed "
361 "at %s(): %s: %m", __func__, ipsec_strerror());
362 }
363 if (ipsec_policy_out != NULL((void *)0) &&
364 setsockopt(sock, lvl, opt, ipsec_policy_out,
365 ipsec_get_policylen(ipsec_policy_out)) < 0) {
366 l2tpd_log(_l2tpd, LOG_WARNING4,
367 "setsockopt(,,IP_IPSEC_POLICY(out)) failed "
368 "in %s(): %m", __func__);
369 }
370 free(ipsec_policy_in);
371 free(ipsec_policy_out);
372#elif defined(IP_ESP_TRANS_LEVEL21)
373 opt = (af == AF_INET2)
374 ? IP_ESP_TRANS_LEVEL21 : IPV6_ESP_TRANS_LEVEL54;
375 ival = IPSEC_LEVEL_REQUIRE0x03;
376 if (setsockopt(sock, lvl, opt, &ival, sizeof(ival)) != 0) {
377 l2tpd_log(_l2tpd, LOG_WARNING4,
378 "setsockopt(,,IP{,V6}_ESP_TRANS_LEVEL(out)) failed "
379 "in %s(): %m", __func__);
380 }
381#else
382#error IP_IPSEC_POLICY or IP_ESP_TRANS_LEVEL21 must be usable.
383#endif
384 }
385
386 _this->sock = sock;
387
388 event_set(&_this->ev_sock, _this->sock, EV_READ0x02 | EV_PERSIST0x10,
389 l2tpd_io_event, _this);
390 event_add(&_this->ev_sock, NULL((void *)0));
391
392 l2tpd_log(_l2tpd, LOG_INFO6, "Listening %s/udp (L2TP LNS) [%s]",
393 addrport_tostring((struct sockaddr *)&_this->bind,
394 _this->bind.sin6.sin6_len, hbuf, sizeof(hbuf)), _this->tun_name);
395
396 return 0;
397fail:
398 if (sock >= 0)
399 close(sock);
400
401 return 1;
402}
403
404/* start L2TP daemon */
405int
406l2tpd_start(l2tpd *_this)
407{
408 int rval;
409 l2tpd_listener *plsnr;
410
411 rval = 0;
412
413 L2TPD_ASSERT(_this->state == L2TPD_STATE_INIT);
414 if (_this->state != L2TPD_STATE_INIT0) {
415 l2tpd_log(_this, LOG_ERR3, "Failed to start l2tpd: illegal "
416 "state.");
417 return -1;
418 }
419
420 slist_itr_first(&_this->listener);
421 while (slist_itr_has_next(&_this->listener)) {
422 plsnr = slist_itr_next(&_this->listener);
423 rval |= l2tpd_listener_start(plsnr);
424 }
425
426 if (rval == 0)
427 _this->state = L2TPD_STATE_RUNNING1;
428
429 return rval;
430}
431
432/* stop l2tp lisnter */
433static void
434l2tpd_listener_stop(l2tpd_listener *_this)
435{
436 char hbuf[NI_MAXHOST256 + NI_MAXSERV32 + 16];
437
438 if (_this->sock >= 0) {
439 event_del(&_this->ev_sock);
440 close(_this->sock);
441 l2tpd_log(_this->self, LOG_INFO6,
442 "Shutdown %s/udp (L2TP LNS)",
443 addrport_tostring((struct sockaddr *)&_this->bind,
444 _this->bind.sin6.sin6_len, hbuf, sizeof(hbuf)));
445 _this->sock = -1;
446 }
447}
448
449/* stop immediattly without disconnect operation */
450void
451l2tpd_stop_immediatly(l2tpd *_this)
452{
453 l2tpd_listener *plsnr;
454
455 slist_itr_first(&_this->listener);
456 while (slist_itr_has_next(&_this->listener)) {
457 plsnr = slist_itr_next(&_this->listener);
458 l2tpd_listener_stop(plsnr);
459 }
460 event_del(&_this->ev_timeout); /* XXX */
461 _this->state = L2TPD_STATE_STOPPED3;
462}
463
464/*
465 * this function will be called when {@link ::_l2tp_ctrl control}
466 * is terminated.
467 */
468void
469l2tpd_ctrl_finished_notify(l2tpd *_this)
470{
471 if (_this->state != L2TPD_STATE_SHUTTING_DOWN2)
472 return;
473
474 if (hash_first(_this->ctrl_map) != NULL((void *)0))
475 return;
476
477 l2tpd_stop_immediatly(_this);
478}
479
480static void
481l2tpd_stop_timeout(int fd, short evtype, void *ctx)
482{
483 hash_link *hl;
484 l2tp_ctrl *ctrl;
485 l2tpd *_this;
486
487 _this = ctx;
488 l2tpd_log(_this, LOG_INFO6, "Shutdown timeout");
489 for (hl = hash_first(_this->ctrl_map); hl != NULL((void *)0);
490 hl = hash_next(_this->ctrl_map)) {
491 ctrl = hl->item;
492 l2tp_ctrl_stop(ctrl, 0);
493 }
494 l2tpd_stop_immediatly(_this);
495}
496
497/* stop L2TP daemon */
498void
499l2tpd_stop(l2tpd *_this)
500{
501 int nctrls = 0;
502 hash_link *hl;
503 l2tp_ctrl *ctrl;
504
505 nctrls = 0;
506 event_del(&_this->ev_timeout);
507 if (l2tpd_is_stopped(_this)(((_this)->state != 2 && (_this)->state != 1)? 1
: 0)
)
508 return;
509 if (l2tpd_is_shutting_down(_this)(((_this)->state == 2)? 1 : 0)) {
510 /* terminate immediately, when 2nd call */
511 l2tpd_stop_immediatly(_this);
512 return;
513 }
514 for (hl = hash_first(_this->ctrl_map); hl != NULL((void *)0);
515 hl = hash_next(_this->ctrl_map)) {
516 ctrl = hl->item;
517 l2tp_ctrl_stop(ctrl, L2TP_STOP_CCN_RCODE_SHUTTING_DOWN6);
518 nctrls++;
519 }
520 _this->state = L2TPD_STATE_SHUTTING_DOWN2;
521 if (nctrls > 0) {
522 struct timeval tv0;
523
524 tv0.tv_usec = 0;
525 tv0.tv_sec = L2TPD_SHUTDOWN_TIMEOUT5;
526
527 evtimer_set(&_this->ev_timeout, l2tpd_stop_timeout, _this)event_set(&_this->ev_timeout, -1, 0, l2tpd_stop_timeout
, _this)
;
528 evtimer_add(&_this->ev_timeout, &tv0)event_add(&_this->ev_timeout, &tv0);
529
530 return;
531 }
532 l2tpd_stop_immediatly(_this);
533}
534
535/*
536 * Configuration
537 */
538int
539l2tpd_reload(l2tpd *_this, struct l2tp_confs *l2tp_conf)
540{
541 int i;
542 struct l2tp_conf *conf;
543 l2tpd_listener *listener;
544 struct l2tp_listen_addr *addr;
545
546 if (slist_length(&_this->listener) > 0) {
547 /*
548 * TODO: add / remove / restart listener.
549 */
550 slist_itr_first(&_this->listener);
551 while (slist_itr_has_next(&_this->listener)) {
552 listener = slist_itr_next(&_this->listener);
553 TAILQ_FOREACH(conf, l2tp_conf, entry)for((conf) = ((l2tp_conf)->tqh_first); (conf) != ((void *)
0); (conf) = ((conf)->entry.tqe_next))
{
554 if (strcmp(listener->tun_name,
555 conf->name) == 0) {
556 listener->conf = conf;
557 break;
558 }
559 }
560 }
561
562 return 0;
563 }
564
565 i = 0;
566 TAILQ_FOREACH(conf, l2tp_conf, entry)for((conf) = ((l2tp_conf)->tqh_first); (conf) != ((void *)
0); (conf) = ((conf)->entry.tqe_next))
{
567 TAILQ_FOREACH(addr, &conf->listen, entry)for((addr) = ((&conf->listen)->tqh_first); (addr) !=
((void *)0); (addr) = ((addr)->entry.tqe_next))
568 l2tpd_add_listener(_this, i++, conf,
569 (struct sockaddr *)&addr->addr);
570 }
571 if (l2tpd_start(_this) != 0)
572 return -1;
573
574 return 0;
575}
576
577/*
578 * I/O functions
579 */
580/* logging when deny an access */
581void
582l2tpd_log_access_deny(l2tpd *_this, const char *reason, struct sockaddr *peer)
583{
584 char buf[BUFSIZ1024];
585
586 l2tpd_log(_this, LOG_ALERT1, "Received packet from %s/udp: "
587 "%s", addrport_tostring(peer, peer->sa_len, buf, sizeof(buf)),
588 reason);
589}
590
591/* I/O event handler */
592static void
593l2tpd_io_event(int fd, short evtype, void *ctx)
594{
595 int sz;
596 l2tpd *_l2tpd;
597 l2tpd_listener *_this;
598 socklen_t peerlen, socklen;
599 struct sockaddr_storage peer, sock;
600 u_char buf[8192];
601 void *nat_t;
602
603 _this = ctx;
604 _l2tpd = _this->self;
605 if ((evtype & EV_READ0x02) != 0) {
606 peerlen = sizeof(peer);
607 socklen = sizeof(sock);
608 while (!l2tpd_is_stopped(_l2tpd)(((_l2tpd)->state != 2 && (_l2tpd)->state != 1)
? 1 : 0)
) {
609#if defined(USE_LIBSOCKUTIL) || defined(USE_SA_COOKIE1)
610 int sa_cookie_len;
611 struct in_ipsec_sa_cookie sa_cookie;
612
613 sa_cookie_len = sizeof(sa_cookie);
614 if ((sz = recvfromto_nat_t(_this->sock, buf,
615 sizeof(buf), 0,
616 (struct sockaddr *)&peer, &peerlen,
617 (struct sockaddr *)&sock, &socklen,
618 &sa_cookie, &sa_cookie_len)) == -1) {
619#else
620 if ((sz = recvfromto(_this->sock, buf,
621 sizeof(buf), 0,
622 (struct sockaddr *)&peer, &peerlen,
623 (struct sockaddr *)&sock, &socklen)) == -1) {
624#endif
625 if (errno(*__errno()) == EAGAIN35 || errno(*__errno()) == EINTR4)
626 break;
627 l2tpd_log(_l2tpd, LOG_ERR3,
628 "recvfrom() failed in %s(): %m",
629 __func__);
630 l2tpd_stop(_l2tpd);
631 return;
632 }
633 /* source address check (allows.in) */
634 switch (peer.ss_family) {
635 case AF_INET2:
636#if defined(USE_LIBSOCKUTIL) || defined(USE_SA_COOKIE1)
637 if (sa_cookie_len > 0)
638 nat_t = &sa_cookie;
639 else
640 nat_t = NULL((void *)0);
641#else
642 nat_t = NULL((void *)0);
643#endif
644 l2tp_ctrl_input(_l2tpd, _this->index,
645 (struct sockaddr *)&peer,
646 (struct sockaddr *)&sock, nat_t,
647 buf, sz);
648 break;
649 case AF_INET624:
650 l2tp_ctrl_input(_l2tpd, _this->index,
651 (struct sockaddr *)&peer,
652 (struct sockaddr *)&sock, NULL((void *)0),
653 buf, sz);
654 break;
655 default:
656 l2tpd_log(_l2tpd, LOG_ERR3,
657 "received from unknown address family = %d",
658 peer.ss_family);
659 break;
660 }
661 }
662 }
663}
664
665/*
666 * L2TP control
667 */
668l2tp_ctrl *
669l2tpd_get_ctrl(l2tpd *_this, unsigned tunid)
670{
671 hash_link *hl;
672
673 hl = hash_lookup(_this->ctrl_map, (void *)(uintptr_t)tunid);
674 if (hl == NULL((void *)0))
675 return NULL((void *)0);
676
677 return hl->item;
678}
679
680void
681l2tpd_add_ctrl(l2tpd *_this, l2tp_ctrl *ctrl)
682{
683 hash_insert(_this->ctrl_map, (void *)(uintptr_t)ctrl->tunnel_id, ctrl);
684}
685
686void
687l2tpd_remove_ctrl(l2tpd *_this, unsigned tunid)
688{
689 hash_delete(_this->ctrl_map, (void *)(uintptr_t)tunid, 0);
690}
691
692
693/*
694 * misc
695 */
696
697void
698l2tpd_log(l2tpd *_this, int prio, const char *fmt, ...)
699{
700 char logbuf[BUFSIZ1024];
701 va_list ap;
702
703 va_start(ap, fmt)__builtin_va_start(ap, fmt);
704#ifdef L2TPD_MULTIPLE
705 snprintf(logbuf, sizeof(logbuf), "l2tpd id=%u %s", _this->id, fmt);
706#else
707 snprintf(logbuf, sizeof(logbuf), "l2tpd %s", fmt);
708#endif
709 vlog_printf(prio, logbuf, ap);
710 va_end(ap)__builtin_va_end(ap);
711}