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