GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/ldpd/packet.c Lines: 0 374 0.0 %
Date: 2017-11-07 Branches: 0 235 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: packet.c,v 1.70 2017/03/04 00:06:10 renato Exp $ */
2
3
/*
4
 * Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
5
 * Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
6
 * Copyright (c) 2004, 2005, 2008 Esben Norby <norby@openbsd.org>
7
 *
8
 * Permission to use, copy, modify, and distribute this software for any
9
 * purpose with or without fee is hereby granted, provided that the above
10
 * copyright notice and this permission notice appear in all copies.
11
 *
12
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
 */
20
21
#include <sys/types.h>
22
#include <netinet/in.h>
23
#include <netinet/tcp.h>
24
#include <arpa/inet.h>
25
#include <net/if_dl.h>
26
#include <unistd.h>
27
#include <errno.h>
28
#include <stdlib.h>
29
#include <string.h>
30
31
#include "ldpd.h"
32
#include "ldpe.h"
33
#include "log.h"
34
35
static struct iface		*disc_find_iface(unsigned int, int,
36
				    union ldpd_addr *, int);
37
static void			 session_read(int, short, void *);
38
static void			 session_write(int, short, void *);
39
static ssize_t			 session_get_pdu(struct ibuf_read *, char **);
40
static void			 tcp_close(struct tcp_conn *);
41
static struct pending_conn	*pending_conn_new(int, int, union ldpd_addr *);
42
static void			 pending_conn_timeout(int, short, void *);
43
44
int
45
gen_ldp_hdr(struct ibuf *buf, uint16_t size)
46
{
47
	struct ldp_hdr	ldp_hdr;
48
49
	memset(&ldp_hdr, 0, sizeof(ldp_hdr));
50
	ldp_hdr.version = htons(LDP_VERSION);
51
	/* exclude the 'Version' and 'PDU Length' fields from the total */
52
	ldp_hdr.length = htons(size - LDP_HDR_DEAD_LEN);
53
	ldp_hdr.lsr_id = leconf->rtr_id.s_addr;
54
	ldp_hdr.lspace_id = 0;
55
56
	return (ibuf_add(buf, &ldp_hdr, LDP_HDR_SIZE));
57
}
58
59
int
60
gen_msg_hdr(struct ibuf *buf, uint16_t type, uint16_t size)
61
{
62
	static int	msgcnt = 0;
63
	struct ldp_msg	msg;
64
65
	memset(&msg, 0, sizeof(msg));
66
	msg.type = htons(type);
67
	/* exclude the 'Type' and 'Length' fields from the total */
68
	msg.length = htons(size - LDP_MSG_DEAD_LEN);
69
	msg.id = htonl(++msgcnt);
70
71
	return (ibuf_add(buf, &msg, sizeof(msg)));
72
}
73
74
/* send packets */
75
int
76
send_packet(int fd, int af, union ldpd_addr *dst, struct iface_af *ia,
77
    void *pkt, size_t len)
78
{
79
	struct sockaddr		*sa;
80
81
	switch (af) {
82
	case AF_INET:
83
		if (ia && IN_MULTICAST(ntohl(dst->v4.s_addr))) {
84
			/* set outgoing interface for multicast traffic */
85
			if (sock_set_ipv4_mcast(ia->iface) == -1) {
86
				log_debug("%s: error setting multicast "
87
				    "interface, %s", __func__, ia->iface->name);
88
				return (-1);
89
			}
90
		}
91
		break;
92
	case AF_INET6:
93
		if (ia && IN6_IS_ADDR_MULTICAST(&dst->v6)) {
94
			/* set outgoing interface for multicast traffic */
95
			if (sock_set_ipv6_mcast(ia->iface) == -1) {
96
				log_debug("%s: error setting multicast "
97
				    "interface, %s", __func__, ia->iface->name);
98
				return (-1);
99
			}
100
		}
101
		break;
102
	default:
103
		fatalx("send_packet: unknown af");
104
	}
105
106
	sa = addr2sa(af, dst, LDP_PORT);
107
	if (sendto(fd, pkt, len, 0, sa, sa->sa_len) == -1) {
108
		log_warn("%s: error sending packet to %s", __func__,
109
		    log_sockaddr(sa));
110
		return (-1);
111
	}
112
113
	return (0);
114
}
115
116
/* Discovery functions */
117
#define CMSG_MAXLEN max(sizeof(struct sockaddr_dl), sizeof(struct in6_pktinfo))
118
void
119
disc_recv_packet(int fd, short event, void *bula)
120
{
121
	union {
122
		struct	cmsghdr hdr;
123
		char	buf[CMSG_SPACE(CMSG_MAXLEN)];
124
	} cmsgbuf;
125
	struct msghdr		 m;
126
	struct sockaddr_storage	 from;
127
	struct iovec		 iov;
128
	char			*buf;
129
	struct cmsghdr		*cmsg;
130
	ssize_t			 r;
131
	int			 multicast;
132
	int			 af;
133
	union ldpd_addr		 src;
134
	unsigned int		 ifindex = 0;
135
	struct iface		*iface;
136
	uint16_t		 len;
137
	struct ldp_hdr		 ldp_hdr;
138
	uint16_t		 pdu_len;
139
	struct ldp_msg		 msg;
140
	uint16_t		 msg_len;
141
	struct in_addr		 lsr_id;
142
143
	if (event != EV_READ)
144
		return;
145
146
	/* setup buffer */
147
	memset(&m, 0, sizeof(m));
148
	iov.iov_base = buf = pkt_ptr;
149
	iov.iov_len = IBUF_READ_SIZE;
150
	m.msg_name = &from;
151
	m.msg_namelen = sizeof(from);
152
	m.msg_iov = &iov;
153
	m.msg_iovlen = 1;
154
	m.msg_control = &cmsgbuf.buf;
155
	m.msg_controllen = sizeof(cmsgbuf.buf);
156
157
	if ((r = recvmsg(fd, &m, 0)) == -1) {
158
		if (errno != EAGAIN && errno != EINTR)
159
			log_debug("%s: read error: %s", __func__,
160
			    strerror(errno));
161
		return;
162
	}
163
164
	multicast = (m.msg_flags & MSG_MCAST) ? 1 : 0;
165
	sa2addr((struct sockaddr *)&from, &af, &src);
166
	if (bad_addr(af, &src)) {
167
		log_debug("%s: invalid source address: %s", __func__,
168
		    log_addr(af, &src));
169
		return;
170
	}
171
172
	for (cmsg = CMSG_FIRSTHDR(&m); cmsg != NULL;
173
	    cmsg = CMSG_NXTHDR(&m, cmsg)) {
174
		if (af == AF_INET && cmsg->cmsg_level == IPPROTO_IP &&
175
		    cmsg->cmsg_type == IP_RECVIF) {
176
			ifindex = ((struct sockaddr_dl *)
177
			    CMSG_DATA(cmsg))->sdl_index;
178
			break;
179
		}
180
		if (af == AF_INET6 && cmsg->cmsg_level == IPPROTO_IPV6 &&
181
		    cmsg->cmsg_type == IPV6_PKTINFO) {
182
			ifindex = ((struct in6_pktinfo *)
183
			    CMSG_DATA(cmsg))->ipi6_ifindex;
184
			break;
185
		}
186
	}
187
188
	/* find a matching interface */
189
	iface = disc_find_iface(ifindex, af, &src, multicast);
190
	if (iface == NULL)
191
		return;
192
193
	/* check packet size */
194
	len = (uint16_t)r;
195
	if (len < (LDP_HDR_SIZE + LDP_MSG_SIZE) || len > LDP_MAX_LEN) {
196
		log_debug("%s: bad packet size, source %s", __func__,
197
		    log_addr(af, &src));
198
		return;
199
	}
200
201
	/* LDP header sanity checks */
202
	memcpy(&ldp_hdr, buf, sizeof(ldp_hdr));
203
	if (ntohs(ldp_hdr.version) != LDP_VERSION) {
204
		log_debug("%s: invalid LDP version %d, source %s", __func__,
205
		    ntohs(ldp_hdr.version), log_addr(af, &src));
206
		return;
207
	}
208
	if (ntohs(ldp_hdr.lspace_id) != 0) {
209
		log_debug("%s: invalid label space %u, source %s", __func__,
210
		    ntohs(ldp_hdr.lspace_id), log_addr(af, &src));
211
		return;
212
	}
213
	/* check "PDU Length" field */
214
	pdu_len = ntohs(ldp_hdr.length);
215
	if ((pdu_len < (LDP_HDR_PDU_LEN + LDP_MSG_SIZE)) ||
216
	    (pdu_len > (len - LDP_HDR_DEAD_LEN))) {
217
		log_debug("%s: invalid LDP packet length %u, source %s",
218
		    __func__, ntohs(ldp_hdr.length), log_addr(af, &src));
219
		return;
220
	}
221
	buf += LDP_HDR_SIZE;
222
	len -= LDP_HDR_SIZE;
223
224
	lsr_id.s_addr = ldp_hdr.lsr_id;
225
226
	/*
227
	 * For UDP, we process only the first message of each packet. This does
228
	 * not impose any restrictions since LDP uses UDP only for sending Hello
229
	 * packets.
230
	 */
231
	memcpy(&msg, buf, sizeof(msg));
232
233
	/* check "Message Length" field */
234
	msg_len = ntohs(msg.length);
235
	if (msg_len < LDP_MSG_LEN || ((msg_len + LDP_MSG_DEAD_LEN) > pdu_len)) {
236
		log_debug("%s: invalid LDP message length %u, source %s",
237
		    __func__, ntohs(msg.length), log_addr(af, &src));
238
		return;
239
	}
240
	buf += LDP_MSG_SIZE;
241
	len -= LDP_MSG_SIZE;
242
243
	/* switch LDP packet type */
244
	switch (ntohs(msg.type)) {
245
	case MSG_TYPE_HELLO:
246
		recv_hello(lsr_id, &msg, af, &src, iface, multicast, buf, len);
247
		break;
248
	default:
249
		log_debug("%s: unknown LDP packet type, source %s", __func__,
250
		    log_addr(af, &src));
251
	}
252
}
253
254
static struct iface *
255
disc_find_iface(unsigned int ifindex, int af, union ldpd_addr *src,
256
    int multicast)
257
{
258
	struct iface	*iface;
259
	struct iface_af	*ia;
260
	struct if_addr	*if_addr;
261
	in_addr_t	 mask;
262
263
	iface = if_lookup(leconf, ifindex);
264
	if (iface == NULL)
265
		return (NULL);
266
267
	/*
268
	 * For unicast packets, we just need to make sure that the interface
269
	 * is enabled for the given address-family.
270
	 */
271
	if (!multicast) {
272
		ia = iface_af_get(iface, af);
273
		if (ia->enabled)
274
			return (iface);
275
		return (NULL);
276
	}
277
278
	switch (af) {
279
	case AF_INET:
280
		LIST_FOREACH(if_addr, &iface->addr_list, entry) {
281
			if (if_addr->af != AF_INET)
282
				continue;
283
284
			switch (iface->type) {
285
			case IF_TYPE_POINTOPOINT:
286
				if (if_addr->dstbrd.v4.s_addr == src->v4.s_addr)
287
					return (iface);
288
				break;
289
			default:
290
				mask = prefixlen2mask(if_addr->prefixlen);
291
				if ((if_addr->addr.v4.s_addr & mask) ==
292
				    (src->v4.s_addr & mask))
293
					return (iface);
294
				break;
295
			}
296
		}
297
		break;
298
	case AF_INET6:
299
		if (IN6_IS_ADDR_LINKLOCAL(&src->v6))
300
			return (iface);
301
		break;
302
	default:
303
		fatalx("disc_find_iface: unknown af");
304
	}
305
306
	return (NULL);
307
}
308
309
void
310
session_accept(int fd, short event, void *bula)
311
{
312
	struct sockaddr_storage	 src;
313
	socklen_t		 len = sizeof(src);
314
	int			 newfd;
315
	int			 af;
316
	union ldpd_addr		 addr;
317
	struct nbr		*nbr;
318
	struct pending_conn	*pconn;
319
320
	if (!(event & EV_READ))
321
		return;
322
323
	newfd = accept4(fd, (struct sockaddr *)&src, &len,
324
	    SOCK_NONBLOCK | SOCK_CLOEXEC);
325
	if (newfd == -1) {
326
		/*
327
		 * Pause accept if we are out of file descriptors, or
328
		 * libevent will haunt us here too.
329
		 */
330
		if (errno == ENFILE || errno == EMFILE) {
331
			accept_pause();
332
		} else if (errno != EWOULDBLOCK && errno != EINTR &&
333
		    errno != ECONNABORTED)
334
			log_debug("%s: accept error: %s", __func__,
335
			    strerror(errno));
336
		return;
337
	}
338
339
	sa2addr((struct sockaddr *)&src, &af, &addr);
340
341
	/*
342
	 * Since we don't support label spaces, we can identify this neighbor
343
	 * just by its source address. This way we don't need to wait for its
344
	 * Initialization message to know who we are talking to.
345
	 */
346
	nbr = nbr_find_addr(af, &addr);
347
	if (nbr == NULL) {
348
		/*
349
		 * According to RFC 5036, we would need to send a No Hello
350
		 * Error Notification message and close this TCP connection
351
		 * right now. But doing so would trigger the backoff exponential
352
		 * timer in the remote peer, which would considerably slow down
353
		 * the session establishment process. The trick here is to wait
354
		 * five seconds before sending the Notification Message. There's
355
		 * a good chance that the remote peer will send us a Hello
356
		 * message within this interval, so it's worth waiting before
357
		 * taking a more drastic measure.
358
		 */
359
		pconn = pending_conn_find(af, &addr);
360
		if (pconn)
361
			close(newfd);
362
		else
363
			pending_conn_new(newfd, af, &addr);
364
		return;
365
	}
366
	/* protection against buggy implementations */
367
	if (nbr_session_active_role(nbr)) {
368
		close(newfd);
369
		return;
370
	}
371
	if (nbr->state != NBR_STA_PRESENT) {
372
		log_debug("%s: lsr-id %s: rejecting additional transport "
373
		    "connection", __func__, inet_ntoa(nbr->id));
374
		close(newfd);
375
		return;
376
	}
377
378
	session_accept_nbr(nbr, newfd);
379
}
380
381
void
382
session_accept_nbr(struct nbr *nbr, int fd)
383
{
384
	struct nbr_params	*nbrp;
385
	int			 opt;
386
	socklen_t		 len;
387
388
	nbrp = nbr_params_find(leconf, nbr->id);
389
	if (nbr_gtsm_check(fd, nbr, nbrp)) {
390
		close(fd);
391
		return;
392
	}
393
394
	if (nbrp && nbrp->auth.method == AUTH_MD5SIG) {
395
		if (sysdep.no_pfkey || sysdep.no_md5sig) {
396
			log_warnx("md5sig configured but not available");
397
			close(fd);
398
			return;
399
		}
400
401
		len = sizeof(opt);
402
		if (getsockopt(fd, IPPROTO_TCP, TCP_MD5SIG, &opt, &len) == -1)
403
			fatal("getsockopt TCP_MD5SIG");
404
		if (!opt) {	/* non-md5'd connection! */
405
			log_warnx("connection attempt without md5 signature");
406
			close(fd);
407
			return;
408
		}
409
	}
410
411
	nbr->tcp = tcp_new(fd, nbr);
412
	nbr_fsm(nbr, NBR_EVT_MATCH_ADJ);
413
}
414
415
static void
416
session_read(int fd, short event, void *arg)
417
{
418
	struct nbr	*nbr = arg;
419
	struct tcp_conn	*tcp = nbr->tcp;
420
	struct ldp_hdr	*ldp_hdr;
421
	struct ldp_msg	*msg;
422
	char		*buf, *pdu;
423
	ssize_t		 n, len;
424
	uint16_t	 pdu_len, msg_len, msg_size, max_pdu_len;
425
	int		 ret;
426
427
	if (event != EV_READ)
428
		return;
429
430
	if ((n = read(fd, tcp->rbuf->buf + tcp->rbuf->wpos,
431
	    sizeof(tcp->rbuf->buf) - tcp->rbuf->wpos)) == -1) {
432
		if (errno != EINTR && errno != EAGAIN) {
433
			log_warn("%s: read error", __func__);
434
			nbr_fsm(nbr, NBR_EVT_CLOSE_SESSION);
435
			return;
436
		}
437
		/* retry read */
438
		return;
439
	}
440
	if (n == 0) {
441
		/* connection closed */
442
		log_debug("%s: connection closed by remote end", __func__);
443
		nbr_fsm(nbr, NBR_EVT_CLOSE_SESSION);
444
		return;
445
	}
446
	tcp->rbuf->wpos += n;
447
448
	while ((len = session_get_pdu(tcp->rbuf, &buf)) > 0) {
449
		pdu = buf;
450
		ldp_hdr = (struct ldp_hdr *)pdu;
451
		if (ntohs(ldp_hdr->version) != LDP_VERSION) {
452
			session_shutdown(nbr, S_BAD_PROTO_VER, 0, 0);
453
			free(buf);
454
			return;
455
		}
456
457
		pdu_len = ntohs(ldp_hdr->length);
458
		/*
459
	 	 * RFC 5036 - Section 3.5.3:
460
		 * "Prior to completion of the negotiation, the maximum
461
		 * allowable length is 4096 bytes".
462
		 */
463
		if (nbr->state == NBR_STA_OPER)
464
			max_pdu_len = nbr->max_pdu_len;
465
		else
466
			max_pdu_len = LDP_MAX_LEN;
467
		if (pdu_len < (LDP_HDR_PDU_LEN + LDP_MSG_SIZE) ||
468
		    pdu_len > max_pdu_len) {
469
			session_shutdown(nbr, S_BAD_PDU_LEN, 0, 0);
470
			free(buf);
471
			return;
472
		}
473
		pdu_len -= LDP_HDR_PDU_LEN;
474
		if (ldp_hdr->lsr_id != nbr->id.s_addr ||
475
		    ldp_hdr->lspace_id != 0) {
476
			session_shutdown(nbr, S_BAD_LDP_ID, 0, 0);
477
			free(buf);
478
			return;
479
		}
480
		pdu += LDP_HDR_SIZE;
481
		len -= LDP_HDR_SIZE;
482
483
		nbr_fsm(nbr, NBR_EVT_PDU_RCVD);
484
485
		while (len >= LDP_MSG_SIZE) {
486
			uint16_t type;
487
488
			msg = (struct ldp_msg *)pdu;
489
			type = ntohs(msg->type);
490
			msg_len = ntohs(msg->length);
491
			if (msg_len < LDP_MSG_LEN ||
492
			    (msg_len + LDP_MSG_DEAD_LEN) > pdu_len) {
493
				session_shutdown(nbr, S_BAD_TLV_LEN, msg->id,
494
				    msg->type);
495
				free(buf);
496
				return;
497
			}
498
			msg_size = msg_len + LDP_MSG_DEAD_LEN;
499
			pdu_len -= msg_size;
500
501
			/* check for error conditions earlier */
502
			switch (type) {
503
			case MSG_TYPE_INIT:
504
				if ((nbr->state != NBR_STA_INITIAL) &&
505
				    (nbr->state != NBR_STA_OPENSENT)) {
506
					session_shutdown(nbr, S_SHUTDOWN,
507
					    msg->id, msg->type);
508
					free(buf);
509
					return;
510
				}
511
				break;
512
			case MSG_TYPE_KEEPALIVE:
513
				if ((nbr->state == NBR_STA_INITIAL) ||
514
				    (nbr->state == NBR_STA_OPENSENT)) {
515
					session_shutdown(nbr, S_SHUTDOWN,
516
					    msg->id, msg->type);
517
					free(buf);
518
					return;
519
				}
520
				break;
521
			default:
522
				if (nbr->state != NBR_STA_OPER) {
523
					session_shutdown(nbr, S_SHUTDOWN,
524
					    msg->id, msg->type);
525
					free(buf);
526
					return;
527
				}
528
				break;
529
			}
530
531
			/* switch LDP packet type */
532
			switch (type) {
533
			case MSG_TYPE_NOTIFICATION:
534
				ret = recv_notification(nbr, pdu, msg_size);
535
				break;
536
			case MSG_TYPE_INIT:
537
				ret = recv_init(nbr, pdu, msg_size);
538
				break;
539
			case MSG_TYPE_KEEPALIVE:
540
				ret = recv_keepalive(nbr, pdu, msg_size);
541
				break;
542
			case MSG_TYPE_CAPABILITY:
543
				ret = recv_capability(nbr, pdu, msg_size);
544
				break;
545
			case MSG_TYPE_ADDR:
546
			case MSG_TYPE_ADDRWITHDRAW:
547
				ret = recv_address(nbr, pdu, msg_size);
548
				break;
549
			case MSG_TYPE_LABELMAPPING:
550
			case MSG_TYPE_LABELREQUEST:
551
			case MSG_TYPE_LABELWITHDRAW:
552
			case MSG_TYPE_LABELRELEASE:
553
			case MSG_TYPE_LABELABORTREQ:
554
				ret = recv_labelmessage(nbr, pdu, msg_size,
555
				    type);
556
				break;
557
			default:
558
				log_debug("%s: unknown LDP message from nbr %s",
559
				    __func__, inet_ntoa(nbr->id));
560
				if (!(ntohs(msg->type) & UNKNOWN_FLAG))
561
					send_notification(nbr->tcp,
562
					    S_UNKNOWN_MSG, msg->id, msg->type);
563
				/* ignore the message */
564
				ret = 0;
565
				break;
566
			}
567
568
			if (ret == -1) {
569
				/* parser failed, giving up */
570
				free(buf);
571
				return;
572
			}
573
574
			/* Analyse the next message */
575
			pdu += msg_size;
576
			len -= msg_size;
577
		}
578
		free(buf);
579
		if (len != 0) {
580
			session_shutdown(nbr, S_BAD_PDU_LEN, 0, 0);
581
			return;
582
		}
583
	}
584
}
585
586
static void
587
session_write(int fd, short event, void *arg)
588
{
589
	struct tcp_conn *tcp = arg;
590
	struct nbr	*nbr = tcp->nbr;
591
592
	if (!(event & EV_WRITE))
593
		return;
594
595
	if (msgbuf_write(&tcp->wbuf.wbuf) <= 0)
596
		if (errno != EAGAIN && nbr)
597
			nbr_fsm(nbr, NBR_EVT_CLOSE_SESSION);
598
599
	if (nbr == NULL && !tcp->wbuf.wbuf.queued) {
600
		/*
601
		 * We are done sending the notification message, now we can
602
		 * close the socket.
603
		 */
604
		tcp_close(tcp);
605
		return;
606
	}
607
608
	evbuf_event_add(&tcp->wbuf);
609
}
610
611
void
612
session_shutdown(struct nbr *nbr, uint32_t status, uint32_t msg_id,
613
    uint32_t msg_type)
614
{
615
	switch (nbr->state) {
616
	case NBR_STA_PRESENT:
617
		if (nbr_pending_connect(nbr))
618
			event_del(&nbr->ev_connect);
619
		break;
620
	case NBR_STA_INITIAL:
621
	case NBR_STA_OPENREC:
622
	case NBR_STA_OPENSENT:
623
	case NBR_STA_OPER:
624
		log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id));
625
626
		send_notification(nbr->tcp, status, msg_id, msg_type);
627
628
		nbr_fsm(nbr, NBR_EVT_CLOSE_SESSION);
629
		break;
630
	default:
631
		fatalx("session_shutdown: unknown neighbor state");
632
	}
633
}
634
635
void
636
session_close(struct nbr *nbr)
637
{
638
	log_debug("%s: closing session with lsr-id %s", __func__,
639
	    inet_ntoa(nbr->id));
640
641
	tcp_close(nbr->tcp);
642
	nbr_stop_ktimer(nbr);
643
	nbr_stop_ktimeout(nbr);
644
	nbr_stop_itimeout(nbr);
645
}
646
647
static ssize_t
648
session_get_pdu(struct ibuf_read *r, char **b)
649
{
650
	struct ldp_hdr	l;
651
	size_t		av, dlen, left;
652
653
	av = r->wpos;
654
	if (av < sizeof(l))
655
		return (0);
656
657
	memcpy(&l, r->buf, sizeof(l));
658
	dlen = ntohs(l.length) + LDP_HDR_DEAD_LEN;
659
	if (dlen > av)
660
		return (0);
661
662
	if ((*b = malloc(dlen)) == NULL)
663
		return (-1);
664
665
	memcpy(*b, r->buf, dlen);
666
	if (dlen < av) {
667
		left = av - dlen;
668
		memmove(r->buf, r->buf + dlen, left);
669
		r->wpos = left;
670
	} else
671
		r->wpos = 0;
672
673
	return (dlen);
674
}
675
676
struct tcp_conn *
677
tcp_new(int fd, struct nbr *nbr)
678
{
679
	struct tcp_conn *tcp;
680
681
	if ((tcp = calloc(1, sizeof(*tcp))) == NULL)
682
		fatal(__func__);
683
684
	tcp->fd = fd;
685
	evbuf_init(&tcp->wbuf, tcp->fd, session_write, tcp);
686
687
	if (nbr) {
688
		if ((tcp->rbuf = calloc(1, sizeof(struct ibuf_read))) == NULL)
689
			fatal(__func__);
690
691
		event_set(&tcp->rev, tcp->fd, EV_READ | EV_PERSIST,
692
		    session_read, nbr);
693
		event_add(&tcp->rev, NULL);
694
		tcp->nbr = nbr;
695
	}
696
697
	return (tcp);
698
}
699
700
static void
701
tcp_close(struct tcp_conn *tcp)
702
{
703
	/* try to flush write buffer */
704
	msgbuf_write(&tcp->wbuf.wbuf);
705
	evbuf_clear(&tcp->wbuf);
706
707
	if (tcp->nbr) {
708
		event_del(&tcp->rev);
709
		free(tcp->rbuf);
710
		tcp->nbr->tcp = NULL;
711
	}
712
713
	close(tcp->fd);
714
	accept_unpause();
715
	free(tcp);
716
}
717
718
static struct pending_conn *
719
pending_conn_new(int fd, int af, union ldpd_addr *addr)
720
{
721
	struct pending_conn	*pconn;
722
	struct timeval		 tv;
723
724
	if ((pconn = calloc(1, sizeof(*pconn))) == NULL)
725
		fatal(__func__);
726
727
	pconn->fd = fd;
728
	pconn->af = af;
729
	pconn->addr = *addr;
730
	evtimer_set(&pconn->ev_timeout, pending_conn_timeout, pconn);
731
	TAILQ_INSERT_TAIL(&global.pending_conns, pconn, entry);
732
733
	timerclear(&tv);
734
	tv.tv_sec = PENDING_CONN_TIMEOUT;
735
	if (evtimer_add(&pconn->ev_timeout, &tv) == -1)
736
		fatal(__func__);
737
738
	return (pconn);
739
}
740
741
void
742
pending_conn_del(struct pending_conn *pconn)
743
{
744
	if (evtimer_pending(&pconn->ev_timeout, NULL) &&
745
	    evtimer_del(&pconn->ev_timeout) == -1)
746
		fatal(__func__);
747
748
	TAILQ_REMOVE(&global.pending_conns, pconn, entry);
749
	free(pconn);
750
}
751
752
struct pending_conn *
753
pending_conn_find(int af, union ldpd_addr *addr)
754
{
755
	struct pending_conn	*pconn;
756
757
	TAILQ_FOREACH(pconn, &global.pending_conns, entry)
758
		if (af == pconn->af &&
759
		    ldp_addrcmp(af, addr, &pconn->addr) == 0)
760
			return (pconn);
761
762
	return (NULL);
763
}
764
765
static void
766
pending_conn_timeout(int fd, short event, void *arg)
767
{
768
	struct pending_conn	*pconn = arg;
769
	struct tcp_conn		*tcp;
770
771
	log_debug("%s: no adjacency with remote end: %s", __func__,
772
	    log_addr(pconn->af, &pconn->addr));
773
774
	/*
775
	 * Create a write buffer detached from any neighbor to send a
776
	 * notification message reliably.
777
	 */
778
	tcp = tcp_new(pconn->fd, NULL);
779
	send_notification(tcp, S_NO_HELLO, 0, 0);
780
	msgbuf_write(&tcp->wbuf.wbuf);
781
782
	pending_conn_del(pconn);
783
}