static void pim_msdp_peer_active_connect(struct pim_msdp_peer *mp) { int rc; ++mp->conn_attempts; rc = pim_msdp_sock_connect(mp); if (PIM_DEBUG_MSDP_INTERNAL) { zlog_debug("MSDP peer %s pim_msdp_peer_active_connect: %d", mp->key_str, rc); } switch (rc) { case connect_error: case -1: /* connect failed restart the connect-retry timer */ pim_msdp_peer_cr_timer_setup(mp, true /* start */); break; case connect_success: /* connect was sucessful move to established */ pim_msdp_peer_established(mp); break; case connect_in_progress: /* for NB content we need to wait till sock is readable or * writeable */ PIM_MSDP_PEER_WRITE_ON(mp); PIM_MSDP_PEER_READ_ON(mp); /* also restart connect-retry timer to reset the socket if * connect is * not sucessful */ pim_msdp_peer_cr_timer_setup(mp, true /* start */); break; } }
/* passive peer socket accept */ static int pim_msdp_sock_accept(struct thread *thread) { union sockunion su; struct pim_instance *pim = THREAD_ARG(thread); int accept_sock; int msdp_sock; struct pim_msdp_peer *mp; char buf[SU_ADDRSTRLEN]; sockunion_init(&su); /* re-register accept thread */ accept_sock = THREAD_FD(thread); if (accept_sock < 0) { flog_err(LIB_ERR_DEVELOPMENT, "accept_sock is negative value %d", accept_sock); return -1; } pim->msdp.listener.thread = NULL; thread_add_read(master, pim_msdp_sock_accept, pim, accept_sock, &pim->msdp.listener.thread); /* accept client connection. */ msdp_sock = sockunion_accept(accept_sock, &su); if (msdp_sock < 0) { flog_err_sys(LIB_ERR_SOCKET, "pim_msdp_sock_accept failed (%s)", safe_strerror(errno)); return -1; } /* see if have peer config for this */ mp = pim_msdp_peer_find(pim, su.sin.sin_addr); if (!mp || !PIM_MSDP_PEER_IS_LISTENER(mp)) { ++pim->msdp.rejected_accepts; if (PIM_DEBUG_MSDP_EVENTS) { flog_err(PIM_ERR_MSDP_PACKET, "msdp peer connection refused from %s", sockunion2str(&su, buf, SU_ADDRSTRLEN)); } close(msdp_sock); return -1; } if (PIM_DEBUG_MSDP_INTERNAL) { zlog_debug("MSDP peer %s accept success%s", mp->key_str, mp->fd >= 0 ? "(dup)" : ""); } /* if we have an existing connection we need to kill that one * with this one */ if (mp->fd >= 0) { if (PIM_DEBUG_MSDP_EVENTS) { zlog_notice( "msdp peer new connection from %s stop old connection", sockunion2str(&su, buf, SU_ADDRSTRLEN)); } pim_msdp_peer_stop_tcp_conn(mp, true /* chg_state */); } mp->fd = msdp_sock; set_nonblocking(mp->fd); pim_msdp_update_sock_send_buffer_size(mp->fd); pim_msdp_peer_established(mp); return 0; }