Пример #1
0
static int ext_client_bgp_accept(struct thread * thread)
{
  int accept_fd;
  union sockunion su;
  struct ext_client_bgp * ext_client_bgp = THREAD_ARG(thread);
  struct bgp_listener * listener;

  accept_fd = THREAD_FD(thread);
  if (accept_fd < 0)
  {   
    printf("accept_fd is negative value %d", accept_fd);
    return -1; 
  }   

  LIST_FOR_EACH(listener, struct bgp_listener, node, &ext_client_bgp->listen_sockets)
  {
    // if we found a listener matching fd, we are done
    if(listener->accept_fd == accept_fd)
      break;
  }

  ext_client_bgp_event(EXT_CLIENT_BGP_ACCEPT, ext_client_bgp, listener);

  /* Accept connections */
  listener->peer_fd = sockunion_accept (accept_fd, &su);
  if (listener->peer_fd < 0)
  {   
    printf("[Error] BGP socket accept failed (%s)", strerror (errno));
    return -1; 
  } 

  ext_client_bgp_event(EXT_CLIENT_BGP_READ, ext_client_bgp, listener);
  return 0;
}
Пример #2
0
s32 ldp_accept(struct thread * t)
{
	s32 fd ;
	union sockunion su ;
	struct ldp_peer * peer ;
	s32 sock = THREAD_FD(t);
	struct ldp * ldp = THREAD_ARG(t);
	
	ldp->t_accept = NULL ;
	THREAD_READ_ON(master, ldp->t_accept, ldp_accept, ldp, sock);

	fd = sockunion_accept(sock, &su);
	if( fd <= 0 ) 
		return -1 ;

	peer = ldp_peer_new();
	if( NULL == peer )
	{
		close(fd);
		return -1 ;
	}
	
	peer->state = ACCEPT_PEER ;
	peer->fd = fd ;
	peer->ldp = ldp;
	peer->transport = su.sin.sin_addr.s_addr;
	peer->input = stream_new(LDP_MAX_PDU_LEN);
	
	listnode_add(ldp->accepts, peer);

	LDP_FSM_EVENT(peer, ConnectSuccess);

	return 0 ;
}
Пример #3
0
int
shim_sisis_accept(struct thread * thread)
{
  int accept_sock;
  int sisis_sock;
  struct sisis_listener *listener;
  union sockunion su;
  char buf[SU_ADDRSTRLEN];

  accept_sock = THREAD_FD (thread);
  if (accept_sock < 0)
  {
    zlog_err ("accept_sock is negative value %d", accept_sock);
    return -1;
  }
  thread_add_read (master, shim_sisis_accept, NULL, accept_sock);

  sisis_sock = sockunion_accept(accept_sock, &su);

  if (sisis_sock < 0)
  {
    zlog_err ("[Error] SISIS socket accept failed (%s)", safe_strerror (errno));
    return -1;
  }

  zlog_notice ("SISIS connection from host %s", inet_sutop (&su, buf));
 
  listener = XMALLOC (MTYPE_SHIM_SISIS_LISTENER, sizeof(*listener));
  listener->fd = accept_sock;
  listener->ibuf = stream_new (SV_HEADER_SIZE + 1500);
//  memcpy(&listener->su, sa, salen);
  listener->sisis_fd = sisis_sock;
  listener->dif = stream_fifo_new();
  listener->chksum_stream = stream_new(4 * 20); // need to figure out good size for buffering
  listener->read_thread = thread_add_read (master, shim_sisis_read, listener, sisis_sock);
  listnode_add (sm->listen_sockets, listener);

  return 0;
}
Пример #4
0
/* BGP Peer Incoming Connection Accept thread handler */
s_int32_t
bpn_sock_accept (struct thread *t_accept)
{
  struct bgp_listen_sock_lnode *tmp_lnode;
  struct bgp_peer_inconn_req *peer_icr;
  u_int8_t su_buf [SU_ADDRSTRLEN];
  pal_sock_handle_t accept_sock;
  pal_sock_handle_t bgp_sock;
  struct lib_globals *blg;
  struct bgp_peer *peer;
  union sockunion su;
  struct bgp *bgp;
  s_int32_t ret;

  bgp_sock = THREAD_FD (t_accept);
  blg = THREAD_GLOB (t_accept);
  bgp = THREAD_ARG (t_accept);
  ret = 0;

  /* Sanity check thread variables */
  if (! blg || &BLG != blg)
    {
      ret = -1;
      goto EXIT;
    }

  if (! bgp)
    {
      zlog_err (&BLG, "[NETWORK] Accept Thread: Invalid Vital Vars, "
                "blg(%p) bgp(%p)", blg, bgp);

      ret = -1;
      goto EXIT;
    }

  /* Verify integrity of thread variables */
  for (tmp_lnode = bgp->listen_sock_lnode; tmp_lnode;
       tmp_lnode = tmp_lnode->next)
    {
      if (tmp_lnode->listen_sock == bgp_sock)
        break;
    }

  if (! tmp_lnode)
    {
      zlog_err (&BLG, "[NETWORK] Accept Thread: Mismatch in thread args"
                "blg(%p) bgp(%p)", blg, bgp);

      ret = -1;
      goto EXIT;
    }

  /* Set BGP VR Context */
  BGP_SET_VR_CONTEXT (&BLG, bgp->owning_bvr);

  /* Re-regiser accept thread */
  t_accept = NULL;
  BGP_READ_ON (&BLG, t_accept, bgp, bpn_sock_accept, bgp_sock);

  /* Update the Accept Thread List Node */
  tmp_lnode->t_accept = t_accept;

  /* Accept Incoming Connection (Blocking) */
  accept_sock = sockunion_accept (&BLG, bgp_sock, &su);
  if (accept_sock < 0)
    {
      zlog_err (&BLG, "[NETWORK] Accept Thread: accept() Failed for Server"
                " Sock %d, Err:%d-%s", bgp_sock, errno, pal_strerror (errno));

      ret = -1;
      goto EXIT;
    }

  if (BGP_DEBUG (events, EVENTS))
    zlog_info (&BLG, "[NETWORK] Accept Thread: Incoming conn from host"
               " %s (FD=%u)", inet_sutop (&su, su_buf), accept_sock);

  /* Search for Configured Peer with same Remote IP address */
  peer = bgp_peer_search (bgp, &su);

  if (! peer)
    {
      if (BGP_DEBUG (events, EVENTS))
        zlog_info (&BLG, "[NETWORK] Accept Thread: %s - No such Peer "
                   "configured", inet_sutop (&su, su_buf));

      SSOCK_FD_CLOSE (&BLG, accept_sock);

      ret = -1;
      goto EXIT;
    }

  /* Prepare an Incoming Connection Req. Info structure */
  peer_icr = XCALLOC (MTYPE_TMP, sizeof (struct bgp_peer_inconn_req));
  if (! peer_icr)
    {
      zlog_err (&BLG, "[NETWORK] Accept Thread:"
                " Cannot allocate memory (%d) @ %s:%d",
                sizeof (struct bgp_peer_inconn_req), __FILE__, __LINE__);

      SSOCK_FD_CLOSE (&BLG, accept_sock);

      ret = -1;
      goto EXIT;
    }

  /* Initialize the FIFO Node */
  FIFO_INIT (&peer_icr->icr_fifo);

  /* Store the ICR Information */
  peer_icr->icr_sock = accept_sock;
  switch (su.sa.sa_family)
    {
    case AF_INET:
      peer_icr->icr_port = su.sin.sin_port;
      break;
#ifdef HAVE_IPV6
    case AF_INET6:
      peer_icr->icr_port = su.sin6.sin6_port;
      break;
#endif /* HAVE_IPV6 */
    }

  /* Enqueue into Peer's 'bicr_fifo' */
  FIFO_ADD (&peer->bicr_fifo, &peer_icr->icr_fifo);

  /* Generate BGP Peer FSM ICR Event */
  BGP_PEER_FSM_EVENT_ADD (&BLG, peer, BPF_EVENT_TCP_CONN_VALID);

 EXIT:

  return ret;
}
Пример #5
0
/* 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;
}
/* Accept bgp connection. */
static int
bgp_accept (struct thread *thread)
{
  int bgp_sock;
  int accept_sock;
  union sockunion su;
  struct bgp_listener *listener = THREAD_ARG(thread);
  struct peer *peer;
  struct peer *peer1;
  char buf[SU_ADDRSTRLEN];

  /* Register accept thread. */
  accept_sock = THREAD_FD (thread);
  if (accept_sock < 0)
    {
      zlog_err ("accept_sock is nevative value %d", accept_sock);
      return -1;
    }
  listener->thread = thread_add_read (master, bgp_accept, listener, accept_sock);

  /* Accept client connection. */
  bgp_sock = sockunion_accept (accept_sock, &su);
  if (bgp_sock < 0)
    {
      zlog_err ("[Error] BGP socket accept failed (%s)", safe_strerror (errno));
      return -1;
    }
  set_nonblocking (bgp_sock);

  /* Set socket send buffer size */
  bgp_update_sock_send_buffer_size(bgp_sock);

  if (BGP_DEBUG (events, EVENTS))
    zlog_debug ("[Event] BGP connection from host %s", inet_sutop (&su, buf));
  
  /* Check remote IP address */
  peer1 = peer_lookup (NULL, &su);
  if (! peer1 || peer1->status == Idle)
    {
      if (BGP_DEBUG (events, EVENTS))
	{
	  if (! peer1)
	    zlog_debug ("[Event] BGP connection IP address %s is not configured",
		       inet_sutop (&su, buf));
	  else
	    zlog_debug ("[Event] BGP connection IP address %s is Idle state",
		       inet_sutop (&su, buf));
	}
      close (bgp_sock);
      return -1;
    }

  bgp_set_socket_ttl (peer1, bgp_sock);

  /* Make dummy peer until read Open packet. */
  if (BGP_DEBUG (events, EVENTS))
    zlog_debug ("[Event] Make dummy peer structure until read Open packet");

  {
    char buf[SU_ADDRSTRLEN];

    peer = peer_create_accept (peer1->bgp);
    SET_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER);
    peer->su = su;
    peer->fd = bgp_sock;
    peer->status = Active;
    peer->local_id = peer1->local_id;
    peer->v_holdtime = peer1->v_holdtime;
    peer->v_keepalive = peer1->v_keepalive;

    /* Make peer's address string. */
    sockunion2str (&su, buf, SU_ADDRSTRLEN);
    peer->host = XSTRDUP (MTYPE_BGP_PEER_HOST, buf);
  }

  BGP_EVENT_ADD (peer, TCP_connection_open);

  return 0;
}
Пример #7
0
/* Accept bgp connection. */
static int
bgp_accept (struct thread *thread)
{
  int bgp_sock;
  int accept_sock;
  union sockunion su;
  struct peer *peer;
  struct peer *peer1;
  struct bgp *bgp;
  char buf[SU_ADDRSTRLEN];

  /* Regiser accept thread. */
  accept_sock = THREAD_FD (thread);
  bgp = THREAD_ARG (thread);

  if (accept_sock < 0)
    {
      zlog_err ("accept_sock is nevative value %d", accept_sock);
      return -1;
    }
  thread_add_read (master, bgp_accept, bgp, accept_sock);

  /* Accept client connection. */
  bgp_sock = sockunion_accept (accept_sock, &su);
  if (bgp_sock < 0)
    {
      zlog_err ("[Error] BGP socket accept failed (%s)", strerror (errno));
      return -1;
    }

  if (BGP_DEBUG (events, EVENTS))
    zlog_info ("[Event] BGP connection from host %s", inet_sutop (&su, buf));
  
  /* Check remote IP address */
  peer1 = peer_lookup (bgp, &su);
  if (! peer1 || peer1->status == Idle)
    {
      if (BGP_DEBUG (events, EVENTS))
	{
	  if (! peer1)
	    zlog_info ("[Event] BGP connection IP address %s is not configured",
		       inet_sutop (&su, buf));
	  else
	    zlog_info ("[Event] BGP connection IP address %s is Idle state",
		       inet_sutop (&su, buf));
	}
      close (bgp_sock);
      return -1;
    }

  /* In case of peer is EBGP, we should set TTL for this connection.  */
  if (peer_sort (peer1) == BGP_PEER_EBGP)
    sockopt_ttl (peer1->su.sa.sa_family, bgp_sock, peer1->ttl);

  if (! bgp)
    bgp = peer1->bgp;

  /* Make dummy peer until read Open packet. */
  if (BGP_DEBUG (events, EVENTS))
    zlog_info ("[Event] Make dummy peer structure until read Open packet");

  {
    char buf[SU_ADDRSTRLEN + 1];

    peer = peer_create_accept (bgp);
    SET_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER);
    peer->su = su;
    peer->fd = bgp_sock;
    peer->status = Active;
    peer->local_id = peer1->local_id;

    /* Make peer's address string. */
    sockunion2str (&su, buf, SU_ADDRSTRLEN);
    peer->host = strdup (buf);
  }

  BGP_EVENT_ADD (peer, TCP_connection_open);

  return 0;
}
Пример #8
0
/* Accept bgp connection. */
static int bgp_accept(struct thread *thread)
{
	int bgp_sock;
	int accept_sock;
	union sockunion su;
	struct bgp_listener *listener = THREAD_ARG(thread);
	struct peer *peer;
	struct peer *peer1;
	char buf[SU_ADDRSTRLEN];
	struct bgp *bgp = NULL;

	sockunion_init(&su);

	/* Register accept thread. */
	accept_sock = THREAD_FD(thread);
	if (accept_sock < 0) {
		flog_err_sys(EC_LIB_SOCKET, "accept_sock is nevative value %d",
			     accept_sock);
		return -1;
	}
	listener->thread = NULL;

	thread_add_read(bm->master, bgp_accept, listener, accept_sock,
			&listener->thread);

	/* Accept client connection. */
	bgp_sock = sockunion_accept(accept_sock, &su);
	if (bgp_sock < 0) {
		flog_err_sys(EC_LIB_SOCKET,
			     "[Error] BGP socket accept failed (%s)",
			     safe_strerror(errno));
		return -1;
	}
	set_nonblocking(bgp_sock);

	/* Obtain BGP instance this connection is meant for.
	 * - if it is a VRF netns sock, then BGP is in listener structure
	 * - otherwise, the bgp instance need to be demultiplexed
	 */
	if (listener->bgp)
		bgp = listener->bgp;
	else if (bgp_get_instance_for_inc_conn(bgp_sock, &bgp)) {
		if (bgp_debug_neighbor_events(NULL))
			zlog_debug(
				"[Event] Could not get instance for incoming conn from %s",
				inet_sutop(&su, buf));
		close(bgp_sock);
		return -1;
	}

	/* Set socket send buffer size */
	setsockopt_so_sendbuf(bgp_sock, BGP_SOCKET_SNDBUF_SIZE);

	/* Check remote IP address */
	peer1 = peer_lookup(bgp, &su);

	if (!peer1) {
		peer1 = peer_lookup_dynamic_neighbor(bgp, &su);
		if (peer1) {
			/* Dynamic neighbor has been created, let it proceed */
			peer1->fd = bgp_sock;
			bgp_fsm_change_status(peer1, Active);
			BGP_TIMER_OFF(
				peer1->t_start); /* created in peer_create() */

			if (peer_active(peer1))
				BGP_EVENT_ADD(peer1, TCP_connection_open);

			return 0;
		}
	}

	if (!peer1) {
		if (bgp_debug_neighbor_events(NULL)) {
			zlog_debug(
				"[Event] %s connection rejected - not configured"
				" and not valid for dynamic",
				inet_sutop(&su, buf));
		}
		close(bgp_sock);
		return -1;
	}

	if (CHECK_FLAG(peer1->flags, PEER_FLAG_SHUTDOWN)) {
		if (bgp_debug_neighbor_events(peer1))
			zlog_debug(
				"[Event] connection from %s rejected due to admin shutdown",
				inet_sutop(&su, buf));
		close(bgp_sock);
		return -1;
	}

	/*
	 * Do not accept incoming connections in Clearing state. This can result
	 * in incorect state transitions - e.g., the connection goes back to
	 * Established and then the Clearing_Completed event is generated. Also,
	 * block incoming connection in Deleted state.
	 */
	if (peer1->status == Clearing || peer1->status == Deleted) {
		if (bgp_debug_neighbor_events(peer1))
			zlog_debug(
				"[Event] Closing incoming conn for %s (%p) state %d",
				peer1->host, peer1, peer1->status);
		close(bgp_sock);
		return -1;
	}

	/* Check that at least one AF is activated for the peer. */
	if (!peer_active(peer1)) {
		if (bgp_debug_neighbor_events(peer1))
			zlog_debug(
				"%s - incoming conn rejected - no AF activated for peer",
				peer1->host);
		close(bgp_sock);
		return -1;
	}

	if (bgp_debug_neighbor_events(peer1))
		zlog_debug("[Event] BGP connection from host %s fd %d",
			   inet_sutop(&su, buf), bgp_sock);

	if (peer1->doppelganger) {
		/* We have an existing connection. Kill the existing one and run
		   with this one.
		*/
		if (bgp_debug_neighbor_events(peer1))
			zlog_debug(
				"[Event] New active connection from peer %s, Killing"
				" previous active connection",
				peer1->host);
		peer_delete(peer1->doppelganger);
	}

	if (bgp_set_socket_ttl(peer1, bgp_sock) < 0)
		if (bgp_debug_neighbor_events(peer1))
			zlog_debug(
				"[Event] Unable to set min/max TTL on peer %s, Continuing",
				peer1->host);

	peer = peer_create(&su, peer1->conf_if, peer1->bgp, peer1->local_as,
			   peer1->as, peer1->as_type, 0, 0, NULL);
	hash_release(peer->bgp->peerhash, peer);
	hash_get(peer->bgp->peerhash, peer, hash_alloc_intern);

	peer_xfer_config(peer, peer1);
	UNSET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);

	peer->doppelganger = peer1;
	peer1->doppelganger = peer;
	peer->fd = bgp_sock;
	vrf_bind(peer->bgp->vrf_id, bgp_sock, bgp_get_bound_name(peer));
	bgp_fsm_change_status(peer, Active);
	BGP_TIMER_OFF(peer->t_start); /* created in peer_create() */

	SET_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER);

	/* Make dummy peer until read Open packet. */
	if (peer1->status == Established
	    && CHECK_FLAG(peer1->sflags, PEER_STATUS_NSF_MODE)) {
		/* If we have an existing established connection with graceful
		 * restart
		 * capability announced with one or more address families, then
		 * drop
		 * existing established connection and move state to connect.
		 */
		peer1->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
		SET_FLAG(peer1->sflags, PEER_STATUS_NSF_WAIT);
		bgp_event_update(peer1, TCP_connection_closed);
	}

	if (peer_active(peer)) {
		BGP_EVENT_ADD(peer, TCP_connection_open);
	}

	return 0;
}
Пример #9
0
/* Accept bgp connection. */
static int
bgp_accept (struct thread *thread)
{
  int bgp_sock;		//socket used for BGP connection
  int accept_sock;
  union sockunion su;
  struct bgp_listener *listener = THREAD_ARG(thread);
  struct peer *peer;
  struct peer *peer1;
  char buf[SU_ADDRSTRLEN];
  

  /* Register accept thread to accept connections from a client */
  accept_sock = THREAD_FD (thread);
  if (accept_sock < 0)
    {
      zlog_err ("accept_sock is nevative value %d", accept_sock);
      return -1;
    }
    
    /*creating a new reading thread*/
  listener->thread = thread_add_read (master, bgp_accept, listener, accept_sock);
  
  /* --------------------------------------------------
   * -               BGP ACCEPT                       -
   * --------------------------------------------------
   * 
   */

  printf("\n BGP ACCEPT: About to initialise SSL \n");
  ssl_init();		//initialise the library, method, contact of ssl session, returns nothing
  
  printf("\n BGP ACCEPT: About to do socket call \n");
  
  bgp_sock = sockunion_accept (accept_sock, &su);

  SSL_accept(BGPoTLS->ssl);
  
  if (bgp_sock < 0)
    {
      zlog_err ("[Error] BGP socket accept failed (%s)", safe_strerror (errno));
      return -1;
    }
  set_nonblocking (bgp_sock);

  if (BGP_DEBUG (events, EVENTS))
		zlog_debug("[Event] BGP connection from host %s", inet_sutop (&su, buf));
  
  /* Check remote IP address */
  peer1 = peer_lookup (NULL, &su);
  if (! peer1 || peer1->status == Idle)
    {
      if (BGP_DEBUG (events, EVENTS))
	{
	  if (! peer1)
	    zlog_debug ("[Event] BGP connection IP address %s is not configured",
		       inet_sutop (&su, buf));
	  else
	    zlog_debug ("[Event] BGP connection IP address %s is Idle state",
		       inet_sutop (&su, buf));
	}
      close (bgp_sock);
      return -1;
    }

  /* In case of peer is EBGP, we should set TTL for this connection.  */
  if (peer1->sort == BGP_PEER_EBGP) {
    sockopt_ttl (peer1->su.sa.sa_family, bgp_sock, peer1->ttl);
    if (peer1->gtsm_hops)
      sockopt_minttl (peer1->su.sa.sa_family, bgp_sock, MAXTTL + 1 - peer1->gtsm_hops);
  }

  /* Make dummy peer until read Open packet. */
  if (BGP_DEBUG (events, EVENTS))
    zlog_debug ("[Event] Make dummy peer structure until read Open packet");

  {
    char buf[SU_ADDRSTRLEN];

    peer = peer_create_accept (peer1->bgp);
    SET_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER);
    peer->su = su;
    peer->fd = bgp_sock;
    peer->status = Active;
    peer->local_id = peer1->local_id;
    peer->v_holdtime = peer1->v_holdtime;
    peer->v_keepalive = peer1->v_keepalive;

    /* Make peer's address string. */
    sockunion2str (&su, buf, SU_ADDRSTRLEN);
    peer->host = XSTRDUP (MTYPE_BGP_PEER_HOST, buf);
  }

  BGP_EVENT_ADD (peer, TCP_connection_open);

  return 0;
}