xref: /netbsd-src/usr.sbin/ldpd/socketops.c (revision 4817a0b0b8fe9612e8ebe21a9bf2d97b95038a97)
1 /* $NetBSD: socketops.c,v 1.2 2010/12/09 00:10:59 christos Exp $ */
2 
3 /*-
4  * Copyright (c) 2010 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Mihai Chelaru <kefren@NetBSD.org>
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <sys/socket.h>
35 #include <sys/ioctl.h>
36 #include <net/if.h>
37 #include <netinet/in.h>
38 #include <arpa/inet.h>
39 
40 #include <errno.h>
41 #include <signal.h>
42 #include <stdlib.h>
43 #include <unistd.h>
44 #include <strings.h>
45 #include <stdio.h>
46 #include <ifaddrs.h>
47 #include <poll.h>
48 
49 #include "fsm.h"
50 #include "ldp.h"
51 #include "ldp_command.h"
52 #include "tlv.h"
53 #include "ldp_peer.h"
54 #include "notifications.h"
55 #include "tlv_stack.h"
56 #include "mpls_interface.h"
57 #include "label.h"
58 #include "mpls_routes.h"
59 #include "ldp_errors.h"
60 #include "socketops.h"
61 
62 int             ls;			/* TCP listening socket on port 646 */
63 int             route_socket;		/* used to see when a route is added/deleted */
64 int		hello_socket;		/* hello multicast listener - transmitter */
65 int		command_socket;		/* Listening socket for interface command */
66 int             current_msg_id = 0x233;
67 int		command_port = LDP_COMMAND_PORT;
68 extern int      replay_index;
69 extern struct rt_msg replay_rt[REPLAY_MAX];
70 extern struct com_sock	csockets[MAX_COMMAND_SOCKETS];
71 
72 int	ldp_hello_time = LDP_HELLO_TIME;
73 
74 void	recv_pdu(int);
75 void	send_hello_alarm(int);
76 void	bail_out(int);
77 static int get_local_addr(struct sockaddr_dl *, struct in_addr *);
78 
79 int
80 create_hello_socket()
81 {
82 	struct ip_mreq  mcast_addr;
83 	int             s = socket(PF_INET, SOCK_DGRAM, 17);
84 
85 	if (s < 0)
86 		return s;
87 
88 	/*
89 	 * RFC3036 specifies we should listen to all subnet routers multicast
90 	 * group
91 	 */
92 	mcast_addr.imr_multiaddr.s_addr = inet_addr(ALL_ROUTERS);
93 	mcast_addr.imr_interface.s_addr = htonl(INADDR_ANY);
94 
95 	socket_reuse_port(s);
96 	/* Bind it to port 646 on specific address */
97 	if (bind_socket(s, htonl(INADDR_ANY)) == -1) {
98 		warnp("Cannot bind hello socket\n");
99 		close(s);
100 		return -1;
101 	}
102 	/* We don't need to receive back our messages */
103 	if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, &(uint8_t){0},
104 	    sizeof(uint8_t)) == -1) {
105 		fatalp("setsockopt: %s", strerror(errno));
106 		close(s);
107 		return -1;
108 	}
109 	/* Finally join the group */
110         if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &mcast_addr,
111 	    sizeof(mcast_addr)) == -1) {
112                 fatalp("setsockopt: %s", strerror(errno));
113                 close(s);
114                 return -1;
115         }
116 	/* TTL:1, TOS: 0xc0 */
117 	if (set_mcast_ttl(s) == -1) {
118 		close(s);
119 		return -1;
120 	}
121 	if (set_tos(s) == -1) {
122 		fatalp("set_tos: %s", strerror(errno));
123 		close(s);
124 		return -1;
125 	}
126 	if (setsockopt(s, IPPROTO_IP, IP_RECVIF, &(uint32_t){1}, sizeof(uint32_t)) == -1) {
127 		fatalp("Cannot set IP_RECVIF\n");
128 		close(s);
129 		return -1;
130 	}
131 	hello_socket = s;
132 	return hello_socket;
133 }
134 
135 /* Sets the TTL to 1 as we don't want to transmit outside this subnet */
136 int
137 set_ttl(int s)
138 {
139 	int             ret;
140 	if ((ret = setsockopt(s, IPPROTO_IP, IP_TTL, &(int){1}, sizeof(int)))
141 	    == -1)
142 		fatalp("set_ttl: %s", strerror(errno));
143 	return ret;
144 }
145 
146 /* Sets multicast TTL to 1 */
147 int
148 set_mcast_ttl(int s)
149 {
150 	int	ret;
151 	if ((ret = setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, &(int){1},
152 	    sizeof(int))) == -1)
153 		fatalp("set_mcast_ttl: %s", strerror(errno));
154 	return ret;
155 }
156 
157 /* Sets TOS to 0xc0 aka IP Precedence 6 */
158 int
159 set_tos(int s)
160 {
161 	int             ret;
162 	if ((ret = setsockopt(s, IPPROTO_IP, IP_TOS, &(int){0xc0},
163 	    sizeof(int))) == -1)
164 		fatalp("set_tos: %s", strerror(errno));
165 	return ret;
166 }
167 
168 int
169 socket_reuse_port(int s)
170 {
171 	int             ret;
172 	if ((ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &(int){1},
173 	    sizeof(int))) == -1)
174 		fatalp("socket_reuse_port: %s", strerror(errno));
175 	return ret;
176 }
177 
178 /* binds an UDP socket */
179 int
180 bind_socket(int s, uint32_t addr)
181 {
182 	struct sockaddr_in sa;
183 
184 	sa.sin_len = sizeof(sa);
185 	sa.sin_family = AF_INET;
186 	sa.sin_port = htons(LDP_PORT);
187 	sa.sin_addr.s_addr = addr;
188 	if (bind(s, (struct sockaddr *) (&sa), sizeof(sa))) {
189 		fatalp("bind_socket: %s", strerror(errno));
190 		return -1;
191 	}
192 	return 0;
193 }
194 
195 /* Create / bind the TCP socket */
196 int
197 create_listening_socket(void)
198 {
199 	struct sockaddr_in sa;
200 	int             s;
201 
202 	sa.sin_len = sizeof(sa);
203 	sa.sin_family = AF_INET;
204 	sa.sin_port = htons(LDP_PORT);
205 	sa.sin_addr.s_addr = htonl(INADDR_ANY);
206 
207 	s = socket(PF_INET, SOCK_STREAM, 6);
208 	if (s < 0)
209 		return s;
210 	if (bind(s, (struct sockaddr *) & sa, sizeof(sa))) {
211 		fatalp("bind: %s", strerror(errno));
212 		close(s);
213 		return -1;
214 	}
215 	if (listen(s, 10) == -1) {
216 		fatalp("listen: %s", strerror(errno));
217 		close(s);
218 		return -1;
219 	}
220 /*	if (set_tos(s) == -1) {
221 		fatalp("set_tos: %s", strerror(errno));
222 		close(s);
223 		return -1;
224 	}
225 */	return s;
226 }
227 
228 /*
229  * It's ugly. We need a function to pass all tlvs and create pdu but since I
230  * use UDP socket only to send hellos, I didn't bother
231  */
232 void
233 send_hello(void)
234 {
235 	struct hello_tlv *t;
236 	struct common_hello_tlv *cht;
237 	struct ldp_pdu  *spdu;
238 	struct transport_address_tlv *trtlv;
239 	void *v;
240 	struct sockaddr_in sadest;	/* Destination ALL_ROUTERS */
241 	int sb = 0;			/* sent bytes */
242 	struct ifaddrs *ifa, *ifb;
243 	struct sockaddr_in *if_sa;
244 	char lastifname[20];
245 
246 #define HELLO_MSG_SIZE (sizeof(struct ldp_pdu) + 	/* PDU */	\
247 			TLV_TYPE_LENGTH + MSGID_SIZE +	/* Hello TLV */	\
248 			/* Common Hello TLV */				\
249 			sizeof(struct common_hello_tlv) +		\
250 			/* IPv4 Transport Address */			\
251 			sizeof(struct transport_address_tlv))
252 
253 	if ((v = calloc(1, HELLO_MSG_SIZE)) == NULL) {
254 		fatalp("malloc problem in send_hello()\n");
255 		return;
256 	}
257 
258 	spdu = (struct ldp_pdu *)((char *)v);
259 	t = (struct hello_tlv *)(spdu + 1);
260 	cht = &t->ch;	/* Hello tlv struct includes CHT */
261 	trtlv = (struct transport_address_tlv *)(t + 1);
262 
263 	/* Prepare PDU envelope */
264 	spdu->version = htons(LDP_VERSION);
265 	spdu->length = htons(HELLO_MSG_SIZE - PDU_VER_LENGTH);
266 	inet_aton(LDP_ID, &spdu->ldp_id);
267 
268 	/* Prepare Hello TLV */
269 	t->type = htons(LDP_HELLO);
270 	t->length = htons(MSGID_SIZE +
271 			sizeof(struct common_hello_tlv) +
272 			sizeof(struct transport_address_tlv));
273 	/*
274 	 * I used ID 0 instead of htonl(get_message_id()) because I've
275 	 * seen hellos from a cisco router doing the same thing
276 	 */
277 	t->messageid = 0;
278 
279 	/* Prepare Common Hello attributes */
280 	cht->type = htons(TLV_COMMON_HELLO);
281 	cht->length = htons(sizeof(cht->holdtime) + sizeof(cht->res));
282 	cht->holdtime = htons(LDP_HOLDTIME);
283 	cht->res = 0;
284 
285 	/*
286 	 * Prepare Transport Address TLV RFC3036 says: "If this optional TLV
287 	 * is not present the IPv4 source address for the UDP packet carrying
288 	 * the Hello should be used." But we send it because everybody seems
289 	 * to do so
290 	 */
291 	trtlv->type = htons(TLV_IPV4_TRANSPORT);
292 	trtlv->length = htons(sizeof(struct in_addr));
293 	/* trtlv->address will be set for each socket */
294 
295 	/* Destination sockaddr */
296 	memset(&sadest, 0, sizeof(sadest));
297 	sadest.sin_len = sizeof(sadest);
298 	sadest.sin_family = AF_INET;
299 	sadest.sin_port = htons(LDP_PORT);
300 	inet_aton(ALL_ROUTERS, &sadest.sin_addr);
301 
302 	if (getifaddrs(&ifa) == -1) {
303 		free(v);
304 		return;
305 	}
306 
307 	lastifname[0] = '\0';
308 	for (ifb = ifa; ifb; ifb = ifb->ifa_next) {
309 		if_sa = (struct sockaddr_in *) ifb->ifa_addr;
310 		if (if_sa->sin_family != AF_INET)
311 			continue;
312 		if (ntohl(if_sa->sin_addr.s_addr) >> 24 == IN_LOOPBACKNET)
313 			continue;
314 		/* Send only once per interface, using master address */
315 		if (strcmp(ifb->ifa_name, lastifname) == 0)
316 			continue;
317 		debugp("Sending hello on %s\n", ifb->ifa_name);
318 		if (setsockopt(hello_socket, IPPROTO_IP, IP_MULTICAST_IF,
319 		    &if_sa->sin_addr, sizeof(struct in_addr)) == -1) {
320 			warnp("setsockopt failed: %s\n", strerror(errno));
321 			continue;
322 		}
323 		trtlv->address.s_addr = if_sa->sin_addr.s_addr;
324 
325 		strlcpy(lastifname, ifb->ifa_name, sizeof(lastifname));
326 
327 		/* Send to the wire */
328 		sb = sendto(hello_socket, v, HELLO_MSG_SIZE,
329 			    0, (struct sockaddr *) & sadest, sizeof(sadest));
330 		if (sb < (int)HELLO_MSG_SIZE)
331 		    fatalp("send: %s", strerror(errno));
332 		else
333 		    debugp("Send %d bytes (PDU: %d, Hello TLV: %d, CH: %d)\n",
334 			sb, (int) (sizeof(struct ldp_pdu) - PDU_VER_LENGTH),
335 		       (int) (TLV_TYPE_LENGTH + MSGID_SIZE),
336 		       (int) (sizeof(struct common_hello_tlv)));
337 
338 	}
339 	freeifaddrs(ifa);
340 	free(v);
341 }
342 
343 int
344 get_message_id(void)
345 {
346 	current_msg_id++;
347 	return current_msg_id;
348 }
349 
350 static int
351 get_local_addr(struct sockaddr_dl *sdl, struct in_addr *sin)
352 {
353 	struct ifaddrs *ifa, *ifb;
354 	struct sockaddr_in *sinet;
355 
356 	if (sdl == NULL)
357 		return -1;
358 
359 	if (getifaddrs(&ifa) == -1)
360 		return -1;
361 	for (ifb = ifa; ifb; ifb = ifb->ifa_next)
362 		if (ifb->ifa_addr->sa_family == AF_INET) {
363 			if (if_nametoindex(ifb->ifa_name) != sdl->sdl_index)
364 				continue;
365 			sinet = (struct sockaddr_in*) ifb->ifa_addr;
366 			sin->s_addr = sinet->sin_addr.s_addr;
367 			freeifaddrs(ifa);
368 			return 0;
369 		}
370 	freeifaddrs(ifa);
371 	return -1;
372 }
373 
374 /* Receive PDUs on Multicast UDP socket */
375 void
376 recv_pdu(int sock)
377 {
378 	struct ldp_pdu  rpdu;
379 	int             c, i;
380 	struct msghdr msg;
381 	struct iovec iov[1];
382 	unsigned char recvspace[MAX_PDU_SIZE];
383 	struct hello_tlv *t;
384 	struct sockaddr_in fromsa;
385 	struct sockaddr_dl *sdl = NULL;
386 	struct in_addr my_ldp_addr, local_addr;
387 	struct cmsghdr *cmptr;
388 	union {
389 		struct cmsghdr cm;
390 		char control[1024];
391 	} control_un;
392 
393 	debugp("Entering RECV_PDU\n");
394 
395 	memset(&msg, 0, sizeof(msg));
396 	msg.msg_control = control_un.control;
397 	msg.msg_controllen = sizeof(control_un.control);
398 	msg.msg_flags = 0;
399 	msg.msg_name = &fromsa;
400 	msg.msg_namelen = sizeof(fromsa);
401 	iov[0].iov_base = recvspace;
402 	iov[0].iov_len = sizeof(recvspace);
403 	msg.msg_iov = iov;
404 	msg.msg_iovlen = 1;
405 
406 	c = recvmsg(sock, &msg, MSG_WAITALL);
407 	debugp("Incoming PDU size: %d\n", c);
408 
409 	debugp("PDU from: %s\n", inet_ntoa(fromsa.sin_addr));
410 
411 	/* Check to see if this is larger than MIN_PDU_SIZE */
412 	if (c < MIN_PDU_SIZE)
413 		return;
414 
415 	/* Read the PDU */
416 	i = get_pdu(recvspace, &rpdu);
417 
418 	/* We currently understand Version 1 */
419 	if (rpdu.version != LDP_VERSION) {
420 		fatalp("recv_pdu: Version mismatch\n");
421 		return;
422 	}
423 
424 	/* Maybe it's our hello */
425 	inet_aton(LDP_ID, &my_ldp_addr);
426 	if (rpdu.ldp_id.s_addr == my_ldp_addr.s_addr) {
427 		fatalp("Received our PDU..\n");	/* it should be not looped */
428 		return;
429 	}
430 
431 	if (msg.msg_controllen < (socklen_t)sizeof(struct cmsghdr) ||
432 	    (msg.msg_flags & MSG_CTRUNC))
433 		local_addr.s_addr = my_ldp_addr.s_addr;
434 	else {
435 		for (cmptr = CMSG_FIRSTHDR(&msg); cmptr != NULL;
436 		    cmptr = CMSG_NXTHDR(&msg, cmptr))
437 			if (cmptr->cmsg_level == IPPROTO_IP &&
438 			    cmptr->cmsg_type == IP_RECVIF) {
439 				sdl = (struct sockaddr_dl *) CMSG_DATA(cmptr);
440 				break;
441 			}
442 		if (get_local_addr(sdl, &local_addr) != 0)
443 			local_addr.s_addr = my_ldp_addr.s_addr;
444 	}
445 
446 
447 	debugp("Read %d bytes from address %s Length: %.4d Version: %d\n",
448 	       c, inet_ntoa(rpdu.ldp_id), rpdu.length, rpdu.version);
449 
450 	/* Fill the TLV messages */
451 	t = get_hello_tlv(recvspace + i, c - i);
452 	run_ldp_hello(&rpdu, t, &fromsa.sin_addr, &local_addr, sock);
453 }
454 
455 void
456 send_hello_alarm(int unused)
457 {
458 	struct ldp_peer *p;
459 	struct hello_info *hi;
460 	time_t          t = time(NULL);
461 	int             olderrno = errno;
462 
463 	/* Send hellos */
464 	if (!(t % ldp_hello_time))
465 		send_hello();
466 
467 	/* Timeout -- */
468 	SLIST_FOREACH(p, &ldp_peer_head, peers)
469 		p->timeout--;
470 
471 	/* Check for timeout */
472 check_peer:
473 	SLIST_FOREACH(p, &ldp_peer_head, peers)
474 		if (p->timeout < 1)
475 			switch (p->state) {
476 			case LDP_PEER_HOLDDOWN:
477 				debugp("LDP holddown expired for peer %s\n",
478 				       inet_ntoa(p->ldp_id));
479 				ldp_peer_delete(p);
480 				goto check_peer;
481 			case LDP_PEER_ESTABLISHED:
482 			case LDP_PEER_CONNECTED:
483 				send_notification(p, 0,
484 				    NOTIF_KEEP_ALIVE_TIMER_EXPIRED);
485 				warnp("Keepalive expired for %s\n",
486 				    inet_ntoa(p->ldp_id));
487 				ldp_peer_holddown(p);
488 				break;
489 			}	/* switch */
490 
491 	/* send keepalives */
492 	if (!(t % LDP_KEEPALIVE_TIME)) {
493 		SLIST_FOREACH(p, &ldp_peer_head, peers)
494 		    if (p->state == LDP_PEER_ESTABLISHED) {
495 			debugp("Sending KeepAlive to %s\n",
496 			    inet_ntoa(p->ldp_id));
497 			keep_alive(p);
498 		    }
499 	}
500 
501 	/* Decrement hello info keepalives */
502 	SLIST_FOREACH(hi, &hello_info_head, infos)
503 		hi->keepalive--;
504 
505 	/* Check hello keepalives */
506 check_hello:
507 	SLIST_FOREACH(hi, &hello_info_head, infos)
508 		if (hi->keepalive < 1) {
509 			SLIST_REMOVE(&hello_info_head, hi, hello_info, infos);
510 			goto check_hello;
511 		}
512 
513 	/* Set the alarm again and bail out */
514 	alarm(1);
515 	errno = olderrno;
516 }
517 
518 void
519 bail_out(int x)
520 {
521 	ldp_peer_holddown_all();
522 	flush_mpls_routes();
523 	exit(0);
524 }
525 
526 /*
527  * The big poll that catches every single event
528  * on every socket.
529  */
530 void
531 the_big_loop(void)
532 {
533 	int		sock_error;
534 	uint32_t	i;
535 	socklen_t       sock_error_size = sizeof(int);
536 	struct ldp_peer *p;
537 	struct com_sock	*cs;
538 	struct pollfd	pfd[MAX_POLL_FDS];
539 
540 	SLIST_INIT(&hello_info_head);
541 
542 	signal(SIGALRM, send_hello_alarm);
543 	signal(SIGPIPE, SIG_IGN);
544 	signal(SIGTERM, bail_out);
545 	send_hello_alarm(1);
546 
547 	route_socket = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC);
548 
549 	if (bind_current_routes() != LDP_E_OK)
550 		fatalp("Cannot get current routes\n");
551 
552 	for (;;) {
553 		nfds_t pollsum = 4;
554 
555 		pfd[0].fd = ls;
556 		pfd[0].events = POLLRDNORM;
557 		pfd[0].revents = 0;
558 
559 		pfd[1].fd = route_socket;
560 		pfd[1].events = POLLRDNORM;
561 		pfd[1].revents = 0;
562 
563 		pfd[2].fd = command_socket;
564 		pfd[2].events = POLLRDNORM;
565 		pfd[2].revents = 0;
566 
567 		/* Hello socket */
568 		pfd[3].fd = hello_socket;
569 		pfd[3].events = POLLIN;
570 		pfd[3].revents = 0;
571 
572 		/* Command sockets */
573 		for (i=0; i < MAX_COMMAND_SOCKETS; i++)
574 			if (csockets[i].socket != -1) {
575 				pfd[pollsum].fd = csockets[i].socket;
576 				pfd[pollsum].events = POLLIN;
577 				pfd[pollsum].revents = 0;
578 				pollsum++;
579 			}
580 
581 		/* LDP Peer sockets */
582 		SLIST_FOREACH(p, &ldp_peer_head, peers) {
583 			if (p->socket < 1)
584 				continue;
585 			switch (p->state) {
586 			    case LDP_PEER_CONNECTED:
587 			    case LDP_PEER_ESTABLISHED:
588 				pfd[pollsum].fd = p->socket;
589 				pfd[pollsum].events = POLLRDNORM;
590 				pfd[pollsum].revents = 0;
591 				pollsum++;
592 				break;
593 			    case LDP_PEER_CONNECTING:
594 				pfd[pollsum].fd = p->socket;
595 				pfd[pollsum].events = POLLWRNORM;
596 				pfd[pollsum].revents = 0;
597 				pollsum++;
598 				break;
599 			}
600 		}
601 
602 		if (pollsum >= MAX_POLL_FDS) {
603 			fatalp("Too many sockets. Increase MAX_POLL_FDS\n");
604 			return;
605 			}
606 		if (poll(pfd, pollsum, INFTIM) < 0) {
607 			if (errno != EINTR)
608 				fatalp("poll: %s", strerror(errno));
609 			continue;
610 			}
611 
612 		for (i = 0; i < pollsum; i++) {
613 			if ((pfd[i].revents & POLLRDNORM) ||
614 			    (pfd[i].revents & POLLIN)) {
615 				if(pfd[i].fd == ls) {
616 					new_peer_connection();
617 				} else if (pfd[i].fd == route_socket) {
618 					struct rt_msg xbuf;
619 					int l, to_read;
620 					do {
621 					    l = recv(route_socket, &xbuf,
622 					      sizeof(struct rt_msg), MSG_PEEK);
623 					} while ((l == -1) && (errno == EINTR));
624 
625 					if (l == -1)
626 						break;
627 
628 					to_read = l;
629 					l = 0;
630 					do {
631 					    l += recv(route_socket, &xbuf,
632 						to_read - l, MSG_WAITALL);
633 					} while (l != to_read);
634 
635 					check_route(&xbuf, to_read);
636 
637 				} else if (pfd[i].fd == hello_socket) {
638 					/* Receiving hello socket */
639 					recv_pdu(pfd[i].fd);
640 				} else if (pfd[i].fd == command_socket) {
641 					command_accept(command_socket);
642 				} else if ((cs = is_command_socket(pfd[i].fd))
643 						!= NULL) {
644 					command_dispatch(cs);
645 				} else {
646 					/* ldp peer socket */
647 					p = get_ldp_peer_by_socket(pfd[i].fd);
648 					if (p)
649 						recv_session_pdu(p);
650 				}
651 			} else if(pfd[i].revents & POLLWRNORM) {
652 				p = get_ldp_peer_by_socket(pfd[i].fd);
653 				if (!p)
654 					continue;
655 				if ((getsockopt(pfd[i].fd, SOL_SOCKET, SO_ERROR,
656 					&sock_error, &sock_error_size) != 0) ||
657 					    (sock_error)) {
658 						ldp_peer_holddown(p);
659 					} else {
660 						p->state = LDP_PEER_CONNECTED;
661 						send_initialize(p);
662 				}
663 			}
664 		}
665 
666 		for (int ri = 0; ri < replay_index; ri++) {
667 			debugp("Replaying: PID %d, SEQ %d\n",
668 				replay_rt[ri].m_rtm.rtm_pid,
669 				replay_rt[ri].m_rtm.rtm_seq);
670 			check_route(&replay_rt[ri], sizeof(struct rt_msg));
671                 }
672 		replay_index = 0;
673 	}	/* for (;;) */
674 }
675 
676 void
677 new_peer_connection()
678 {
679 	struct sockaddr_in sa, sin_me;
680 	int             s;
681 
682 	s = accept(ls, (struct sockaddr *) & sa,
683 		& (socklen_t) { sizeof(struct sockaddr_in) } );
684 	if (s < 0) {
685 		fatalp("accept: %s", strerror(errno));
686 		return;
687 	}
688 
689 	if (get_ldp_peer(&sa.sin_addr) != NULL) {
690 		close(s);
691 		return;
692 	}
693 
694 	warnp("Accepted a connection from %s\n", inet_ntoa(sa.sin_addr));
695 
696 	if (getsockname(s, (struct sockaddr *)&sin_me,
697 	    & (socklen_t) { sizeof(struct sockaddr_in) } )) {
698 		fatalp("new_peer_connection(): cannot getsockname\n");
699 		close(s);
700 		return;
701 	}
702 
703 	if (ntohl(sa.sin_addr.s_addr) < ntohl(sin_me.sin_addr.s_addr)) {
704 		fatalp("Peer %s: connect from lower ID\n",
705 		    inet_ntoa(sa.sin_addr));
706 		close(s);
707 		return;
708 	}
709 	/* XXX: sa.sin_addr ain't peer LDP ID ... */
710 	ldp_peer_new(&sa.sin_addr, &sa.sin_addr, NULL, LDP_HOLDTIME, s);
711 
712 }
713 
714 void
715 send_initialize(struct ldp_peer * p)
716 {
717 	struct init_tlv ti;
718 
719 	ti.type = htons(LDP_INITIALIZE);
720 	ti.length = htons(sizeof(struct init_tlv) - TLV_TYPE_LENGTH);
721 	ti.messageid = htonl(get_message_id());
722 	ti.cs_type = htons(TLV_COMMON_SESSION);
723 	ti.cs_len = htons(CS_LEN);
724 	ti.cs_version = htons(LDP_VERSION);
725 	ti.cs_keepalive = htons(2 * LDP_KEEPALIVE_TIME);
726 	ti.cs_adpvlim = 0;
727 	ti.cs_maxpdulen = htons(MAX_PDU_SIZE);
728 	ti.cs_peeraddress.s_addr = p->ldp_id.s_addr;
729 	ti.cs_peeraddrspace = 0;
730 
731 	send_tlv(p, (struct tlv *) (void *) &ti);
732 }
733 
734 void
735 keep_alive(struct ldp_peer * p)
736 {
737 	struct ka_tlv   kt;
738 
739 	kt.type = htons(LDP_KEEPALIVE);
740 	kt.length = htons(sizeof(kt.messageid));
741 	kt.messageid = htonl(get_message_id());
742 
743 	send_tlv(p, (struct tlv *) (void *) &kt);
744 
745 }
746 
747 void
748 recv_session_pdu(struct ldp_peer * p)
749 {
750 	struct ldp_pdu *rpdu;
751 	struct address_tlv *atlv;
752 	struct al_tlv  *altlv;
753 	struct init_tlv	*itlv;
754 	struct label_map_tlv *lmtlv;
755 	struct fec_tlv *fectlv;
756 	struct label_tlv *__packed labeltlv;
757 	struct notification_tlv *nottlv;
758 	struct hello_info *hi;
759 
760 	int             c;
761 	int32_t         wo = 0;
762 	struct tlv     *ttmp;
763 	unsigned char   recvspace[MAX_PDU_SIZE];
764 
765 	memset(recvspace, 0, MAX_PDU_SIZE);
766 
767 	c = recv(p->socket, (void *) recvspace, MAX_PDU_SIZE, MSG_PEEK);
768 
769 	debugp("Ready to read %d bytes\n", c);
770 
771 	if (c < 1) {		/* Session closed */
772 		warnp("Error in connection with %s\n", inet_ntoa(p->ldp_id));
773 		ldp_peer_holddown(p);
774 		return;
775 	}
776 	if (c > MAX_PDU_SIZE) {
777 		debugp("Incoming PDU size exceeds MAX_PDU_SIZE !\n");
778 		return;
779 	}
780 	if (c < MIN_PDU_SIZE) {
781 		debugp("PDU too small received from peer %s\n", inet_ntoa(p->ldp_id));
782 		return;
783 	}
784 	rpdu = (struct ldp_pdu *) recvspace;
785 	/* XXX: buggy messages may crash the whole thing */
786 	c = recv(p->socket, (void *) recvspace,
787 		ntohs(rpdu->length) + PDU_VER_LENGTH, MSG_WAITALL);
788 	rpdu = (struct ldp_pdu *) recvspace;
789 
790 	/* Check if it's somehow OK... */
791 	if (check_recv_pdu(p, rpdu, c) != 0)
792 		return;
793 
794 	debugp("Read %d bytes, PDU size: %d bytes\n", c, ntohs(rpdu->length));
795 	wo = sizeof(struct ldp_pdu);
796 
797 	while (wo + TLV_TYPE_LENGTH < (uint)c) {
798 
799 		ttmp = (struct tlv *) (&recvspace[wo]);
800 
801 		if ((ntohs(ttmp->type) != LDP_KEEPALIVE) &&
802 		    (ntohs(ttmp->type) != LDP_LABEL_MAPPING)) {
803 			debugp("Got Type: 0x%.4X (Length: %d) from %s\n",
804 			    ntohs(ttmp->type), ntohs(ttmp->length),
805 			    inet_ntoa(p->ldp_id));
806 		} else
807 			debugp("Got Type: 0x%.4X (Length: %d) from %s\n",
808 			    ntohs(ttmp->type), ntohs(ttmp->length),
809 			    inet_ntoa(p->ldp_id));
810 
811 		/* Should we get the message ? */
812 		if (p->state != LDP_PEER_ESTABLISHED &&
813 		    ntohs(ttmp->type) != LDP_INITIALIZE &&
814 		    ntohs(ttmp->type) != LDP_KEEPALIVE)
815 			break;
816 		/* The big switch */
817 		switch (ntohs(ttmp->type)) {
818 		case LDP_INITIALIZE:
819 			itlv = (struct init_tlv *)ttmp;
820 			/* Check size */
821 			if (ntohs(itlv->length) <
822 			    sizeof(struct init_tlv) - TLV_TYPE_LENGTH) {
823 				send_notification(p, 0,
824 				    NOTIF_BAD_PDU_LEN | NOTIF_FATAL);
825 				ldp_peer_holddown(p);
826 				break;
827 			}
828 			/* Check version */
829 			if (ntohs(itlv->cs_version) != LDP_VERSION) {
830 				send_notification(p, ntohl(itlv->messageid),
831 					NOTIF_BAD_LDP_VER | NOTIF_FATAL);
832 				ldp_peer_holddown(p);
833 				break;
834 			}
835 			/* Check if we got any hello from this one */
836 			SLIST_FOREACH(hi, &hello_info_head, infos)
837 				if (hi->ldp_id.s_addr == rpdu->ldp_id.s_addr)
838 					break;
839 			if (hi == NULL) {
840 			    send_notification(p, ntohl(itlv->messageid),
841 				NOTIF_SESSION_REJECTED_NO_HELLO | NOTIF_FATAL);
842 			    ldp_peer_holddown(p);
843 			    break;
844 			}
845 
846 			if (!p->master) {
847 				keep_alive(p);
848 				send_initialize(p);
849 			} else {
850 				p->state = LDP_PEER_ESTABLISHED;
851 				p->established_t = time(NULL);
852 				keep_alive(p);
853 
854 				/*
855 				 * Recheck here ldp id because we accepted
856 				 * connection without knowing who is it for sure
857 				 */
858 				p->ldp_id.s_addr = rpdu->ldp_id.s_addr;
859 
860 				fatalp("LDP neighbour %s is UP\n",
861 				    inet_ntoa(p->ldp_id));
862 				mpls_add_ldp_peer(p);
863 				send_addresses(p);
864 				send_all_bindings(p);
865 			}
866 			break;
867 		case LDP_KEEPALIVE:
868 			if ((p->state == LDP_PEER_CONNECTED) && (!p->master)) {
869 				p->state = LDP_PEER_ESTABLISHED;
870 				p->established_t = time(NULL);
871 				fatalp("LDP neighbour %s is UP\n",
872 				    inet_ntoa(p->ldp_id));
873 				mpls_add_ldp_peer(p);
874 				send_addresses(p);
875 				send_all_bindings(p);
876 			}
877 			p->timeout = p->holdtime;
878 			break;
879 		case LDP_ADDRESS:
880 			/* Add peer addresses */
881 			atlv = (struct address_tlv *) ttmp;
882 			altlv = (struct al_tlv *) (&atlv[1]);
883 			add_ifaddresses(p, altlv);
884 			print_bounded_addresses(p);
885 			break;
886 		case LDP_ADDRESS_WITHDRAW:
887 			atlv = (struct address_tlv *) ttmp;
888 			altlv = (struct al_tlv *) (&atlv[1]);
889 			del_ifaddresses(p, altlv);
890 			break;
891 		case LDP_LABEL_MAPPING:
892 			lmtlv = (struct label_map_tlv *) ttmp;
893 			fectlv = (struct fec_tlv *) (&lmtlv[1]);
894 			labeltlv = (struct label_tlv *)((unsigned char *)fectlv
895 				+ ntohs(fectlv->length) + TLV_TYPE_LENGTH);
896 			map_label(p, fectlv, labeltlv);
897 			break;
898 		case LDP_LABEL_REQUEST:
899 			lmtlv = (struct label_map_tlv *) ttmp;
900 			fectlv = (struct fec_tlv *) (&lmtlv[1]);
901 			switch (request_respond(p, lmtlv, fectlv)) {
902 			case LDP_E_BAD_FEC:
903 				send_notification(p, ntohl(lmtlv->messageid),
904 					NOTIF_UNKNOWN_TLV);
905 				break;
906 			case LDP_E_BAD_AF:
907 				send_notification(p, ntohl(lmtlv->messageid),
908 					NOTIF_UNSUPPORTED_AF);
909 				break;
910 			case LDP_E_NO_SUCH_ROUTE:
911 				send_notification(p, ntohl(lmtlv->messageid),
912 					NOTIF_NO_ROUTE);
913 				break;
914 			}
915 			break;
916 		case LDP_LABEL_WITHDRAW:
917 			lmtlv = (struct label_map_tlv *) ttmp;
918 			fectlv = (struct fec_tlv *) (&lmtlv[1]);
919 			if (withdraw_label(p, fectlv) == LDP_E_OK) {
920 				/* Send RELEASE */
921 				prepare_release(ttmp);
922 				send_tlv(p, ttmp);
923 				}
924 			break;
925 		case LDP_LABEL_RELEASE:
926 			/*
927 			 * XXX: we need to make a timed queue...
928 			 * For now I just assume peers are processing messages
929 			 * correctly so I just ignore confirmations
930 			 */
931 			wo = -1;	/* Ignore rest of message */
932 			break;
933 		case LDP_LABEL_ABORT:
934 		/* XXX: For now I pretend I can process everything
935 		 * RFC 3036, Section 3.5.9.1
936 		 * If an LSR receives a Label Abort Request Message after it
937 		 * has responded to the Label Request in question with a Label
938 		 * Mapping message or a Notification message, it ignores the
939 		 * abort request.
940 		 */
941 			wo = -1;
942 			break;
943 		case LDP_NOTIFICATION:
944 			nottlv = (struct notification_tlv *) ttmp;
945 			nottlv->st_code = ntohl(nottlv->st_code);
946 			fatalp("Got notification 0x%X from peer %s\n",
947 			    nottlv->st_code, inet_ntoa(p->ldp_id));
948 			if (nottlv->st_code >> 31) {
949 				fatalp("LDP peer %s signalized %s\n",
950 				    inet_ntoa(p->ldp_id),
951 				    NOTIF_STR[(nottlv->st_code << 1) >> 1]);
952 				ldp_peer_holddown(p);
953 				wo = -1;
954 			}
955 			break;
956 		case LDP_HELLO:
957 			/* No hellos should came on tcp session */
958 			wo = -1;
959 			break;
960 		default:
961 			warnp("Unknown TLV received from %s\n",
962 			    inet_ntoa(p->ldp_id));
963 			debug_tlv(ttmp);
964 			wo = -1;/* discard the rest of the message */
965 			break;
966 		}
967 		if (wo < 0) {
968 			debugp("Discarding the rest of the message\n");
969 			break;
970 		} else {
971 			wo += ntohs(ttmp->length) + TLV_TYPE_LENGTH;
972 			debugp("WORKED ON %u bytes (Left %d)\n", wo, c - wo);
973 		}
974 	}			/* while */
975 
976 }
977 
978 /* Sends a pdu, tlv pair to a connected peer */
979 int
980 send_message(struct ldp_peer * p, struct ldp_pdu * pdu, struct tlv * t)
981 {
982 	unsigned char   sendspace[MAX_PDU_SIZE];
983 
984 	/* Check if peer is connected */
985 	switch (p->state) {
986 	case LDP_PEER_CONNECTED:
987 	case LDP_PEER_ESTABLISHED:
988 		break;
989 	default:
990 		return -1;
991 	}
992 
993 	/* Check length validity first */
994 	if (ntohs(pdu->length) !=
995 	    ntohs(t->length) + TLV_TYPE_LENGTH + PDU_PAYLOAD_LENGTH) {
996 		fatalp("LDP: TLV - PDU incompability. Message discarded\n");
997 		fatalp("LDP: TLV len %d - PDU len %d\n", ntohs(t->length),
998 		    ntohs(pdu->length));
999 		return -1;
1000 	}
1001 	if (ntohs(t->length) + PDU_VER_LENGTH > MAX_PDU_SIZE) {
1002 		fatalp("Message to large discarded\n");
1003 		return -1;
1004 	}
1005 	/* Arrange them in a buffer and send */
1006 	memcpy(sendspace, pdu, sizeof(struct ldp_pdu));
1007 	memcpy(sendspace + sizeof(struct ldp_pdu), t,
1008 	    ntohs(t->length) + TLV_TYPE_LENGTH);
1009 
1010 	/* Report keepalives only for DEBUG */
1011 	if ((ntohs(t->type) != 0x201) && (ntohs(t->type) != 0x400)) {
1012 		debugp("Sending message type 0x%.4X to %s (size: %d)\n",
1013 		    ntohs(t->type), inet_ntoa(p->ldp_id), ntohs(t->length));
1014 	} else
1015 	/* downgraded from warnp to debugp for now */
1016 		debugp("Sending message type 0x%.4X to %s (size: %d)\n",
1017 		    ntohs(t->type), inet_ntoa(p->ldp_id), ntohs(t->length));
1018 
1019 	/* Send it finally */
1020 	return send(p->socket, sendspace,
1021 		ntohs(pdu->length) + PDU_VER_LENGTH, 0);
1022 }
1023 
1024 /*
1025  * Encapsulates TLV into a PDU and sends it to a peer
1026  */
1027 int
1028 send_tlv(struct ldp_peer * p, struct tlv * t)
1029 {
1030 	struct ldp_pdu  pdu;
1031 
1032 	pdu.version = htons(LDP_VERSION);
1033 	inet_aton(LDP_ID, &pdu.ldp_id);
1034 	pdu.label_space = 0;
1035 	pdu.length = htons(ntohs(t->length) + TLV_TYPE_LENGTH +
1036 		PDU_PAYLOAD_LENGTH);
1037 
1038 	return send_message(p, &pdu, t);
1039 }
1040 
1041 
1042 int
1043 send_addresses(struct ldp_peer * p)
1044 {
1045 	struct address_list_tlv *t;
1046 	int             ret;
1047 
1048 	t = build_address_list_tlv();
1049 
1050 	ret = send_tlv(p, (struct tlv *) t);
1051 	free(t);
1052 	return ret;
1053 
1054 }
1055