Ejemplo n.º 1
0
void
tcp_connection_state(int fd, enum connect_result status, thread_t * thread,
		     int (*func) (thread_t *)
		     , long timeout)
{
	switch (status) {
	case connect_error:
		close(fd);
		break;

	case connect_success:
		thread_add_write(thread->master, func, THREAD_ARG(thread),
				 fd, timeout);
		break;

		/* Checking non-blocking connect, we wait until socket is writable */
	case connect_in_progress:
		thread_add_write(thread->master, func, THREAD_ARG(thread),
				 fd, timeout);
		break;

	default:
		break;
	}
}
Ejemplo n.º 2
0
void smart_link_event(enum sl_event event, int sock)
{
    switch (event)
    {
        case SL_EVENT:
        {
            smart_link_log_event("sl-event event, fd(%d).\n", sock);
            thread_add_read(sl_master, smart_link_recv_event, NULL, sock);
            break;
        }
        case SL_MSG:
        {
            smart_link_log_event("sl-event msg, fd(%d).\n", sock);
            thread_add_read(sl_master, smart_link_recv_msg, NULL, sock);
            break;
        }
        case SL_DBUS_READ:
        {
            smart_link_log_event("sl-event dbus-read, fd(%d).\n", sock);
            thread_add_read(sl_master, smart_link_recv_cmd, NULL, sock);
            break;
        }
        case SL_DBUS_WRITE:
        {
            smart_link_log_event("sl-event dbus-write, fd(%d).\n", sock);
            thread_add_write(sl_master, smart_link_send_cmd, NULL, sock);
            break;
        }
        default :
        {
            smart_link_log_error("sl-event default, fd(%d).\n", sock);
            break;
        }
    }
}
Ejemplo n.º 3
0
static int
svz_tunnel_flush_data(struct thread * thread)
{
  struct tclient * tclient = THREAD_ARG(thread);
 
  tclient->t_write = NULL;
  if(tclient->sock < 0)
    return -1;

  switch (buffer_flush_available(tclient->wb, tclient->sock))
  {
    case BUFFER_ERROR:
      zlog_warn("%s: buffer_flush_available failed on zclient fd %d, closing",
                __func__, tclient->sock);
      return svz_tunnel_failed(tclient);
      break;
    case BUFFER_PENDING:
      tclient->t_write = thread_add_write(master, svz_tunnel_flush_data,
                                          tclient, tclient->sock);
      break;
    case BUFFER_EMPTY:
      break;
  }    
  return 0;
}
Ejemplo n.º 4
0
static int
zserv_flush_data(struct thread *thread)
{
  struct zserv *client = THREAD_ARG(thread);

  client->t_write = NULL;
  if (client->t_suicide)
    {
      zebra_client_close(client);
      return -1;
    }
  switch (buffer_flush_available(client->wb, client->sock))
    {
    case BUFFER_ERROR:
      zlog_warn("%s: buffer_flush_available failed on zserv client fd %d, "
      		"closing", __func__, client->sock);
      zebra_client_close(client);
      break;
    case BUFFER_PENDING:
      client->t_write = thread_add_write(zebrad.master, zserv_flush_data,
      					 client, client->sock);
      break;
    case BUFFER_EMPTY:
      break;
    }
  return 0;
}
Ejemplo n.º 5
0
mpls_return_enum mpls_socket_writelist_add(mpls_socket_mgr_handle handle,
  mpls_socket_handle socket, void *extra, mpls_socket_enum type)
{
  socket->type = type;
  socket->extra = extra;
  MPLS_ASSERT(socket && (socket->fd > -1));
  socket->write = thread_add_write(master,mplsd_write,socket,socket->fd);
  MPLS_ASSERT(socket->write);
  return MPLS_SUCCESS;
}
Ejemplo n.º 6
0
int
tcp_connection_state(int fd, enum connect_result status, thread_t * thread,
		     int (*func) (thread_t *), long timeout)
{
	checker_t *checker;

	checker = THREAD_ARG(thread);

	switch (status) {
	case connect_success:
		thread_add_write(thread->master, func, checker, fd, timeout);
		return 0;

		/* Checking non-blocking connect, we wait until socket is writable */
	case connect_in_progress:
		thread_add_write(thread->master, func, checker, fd, timeout);
		return 0;

	default:
		return 1;
	}
}
Ejemplo n.º 7
0
enum connect_result
tcp_socket_state(int fd, thread * thread_obj, uint32_t addr_ip, uint16_t addr_port,
		 int (*func) (struct _thread *))
{
	int status;
	socklen_t slen;
	int ret = 0;
	TIMEVAL timer_min;

	/* Handle connection timeout */
	if (thread_obj->type == THREAD_WRITE_TIMEOUT) {
		DBG("TCP connection timeout to [%s:%d].",
		    inet_ntop2(addr_ip), ntohs(addr_port));
		close(thread_obj->u.fd);
		return connect_timeout;
	}

	/* Check file descriptor */
	slen = sizeof (status);
	if (getsockopt
	    (thread_obj->u.fd, SOL_SOCKET, SO_ERROR, (void *) &status, &slen) < 0)
		ret = errno;

	/* Connection failed !!! */
	if (ret) {
		DBG("TCP connection failed to [%s:%d].",
		    inet_ntop2(addr_ip), ntohs(addr_port));
		close(thread_obj->u.fd);
		return connect_error;
	}

	/* If status = 0, TCP connection to remote host is established.
	 * Otherwise register checker thread to handle connection in progress,
	 * and other error code until connection is established.
	 * Recompute the write timeout (or pending connection).
	 */
	if (status == EINPROGRESS) {
		DBG("TCP connection to [%s:%d] still IN_PROGRESS.",
		    inet_ntop2(addr_ip), ntohs(addr_port));

		timer_min = timer_sub_now(thread_obj->sands);
		thread_add_write(thread_obj->master, func, THREAD_ARG(thread_obj)
				 , thread_obj->u.fd, TIMER_LONG(timer_min));
		return connect_in_progress;
	} else if (status != 0) {
		close(thread_obj->u.fd);
		return connect_error;
	}

	return connect_success;
}
Ejemplo n.º 8
0
void
tcp_connection_state(int fd, enum connect_result status, thread * thread_obj,
		     int (*func) (struct _thread *)
		     , long timeout)
{
	checker *checker_obj;

	checker_obj = THREAD_ARG(thread_obj);

	switch (status) {
	case connect_error:
		DBG("TCP connection ERROR to [%s:%d].",
		    inet_ntop2(SVR_IP(checker_obj->rs)),
		    ntohs(SVR_PORT(checker_obj->rs)));
		close(fd);
		break;

	case connect_success:
		DBG("TCP connection SUCCESS to [%s:%d].",
		    inet_ntop2(SVR_IP(checker_obj->rs)),
		    ntohs(SVR_PORT(checker_obj->rs)));
		thread_add_write(thread_obj->master, func, checker_obj, fd, timeout);
		break;

		/* Checking non-blocking connect, we wait until socket is writable */
	case connect_in_progress:
		DBG("TCP connection to [%s:%d] now IN_PROGRESS.",
		    inet_ntop2(SVR_IP(checker_obj->rs)),
		    ntohs(SVR_PORT(checker_obj->rs)));
		thread_add_write(thread_obj->master, func, checker_obj, fd, timeout);
		break;

	default:
		break;
	}
}
Ejemplo n.º 9
0
int mplsd_write(struct thread *thread) {
  struct ldp *ldp = ldp_get();
  int retval;
  mpls_socket_handle socket;

  MPLS_ASSERT(thread); 

  socket = THREAD_ARG(thread);
  socket->write = thread_add_write(master,mplsd_write,socket,socket->fd);
  if (socket->type != MPLS_SOCKET_TCP_CONNECT) {
    assert(0);
  }
  retval = ldp_event(ldp->h, socket, socket->extra,
    LDP_EVENT_TCP_CONNECT);

  return 0;
}
Ejemplo n.º 10
0
enum connect_result
tcp_socket_state(int fd, thread_t * thread, int (*func) (thread_t *))
{
	int status;
	socklen_t addrlen;
	int ret = 0;
	timeval_t timer_min;

	/* Handle connection timeout */
	if (thread->type == THREAD_WRITE_TIMEOUT) {
		close(thread->u.fd);
		return connect_timeout;
	}

	/* Check file descriptor */
	addrlen = sizeof(status);
	if (getsockopt(thread->u.fd, SOL_SOCKET, SO_ERROR, (void *) &status, &addrlen) < 0)
		ret = errno;

	/* Connection failed !!! */
	if (ret) {
		close(thread->u.fd);
		return connect_error;
	}

	/* If status = 0, TCP connection to remote host is established.
	 * Otherwise register checker thread to handle connection in progress,
	 * and other error code until connection is established.
	 * Recompute the write timeout (or pending connection).
	 */
	if (status == EINPROGRESS) {
		timer_min = timer_sub_now(thread->sands);
		thread_add_write(thread->master, func, THREAD_ARG(thread),
				 thread->u.fd, timer_long(timer_min));
		return connect_in_progress;
	} else if (status != 0) {
		close(thread->u.fd);
		return connect_error;
	}

	return connect_success;
}
Ejemplo n.º 11
0
/* SMTP protocol handlers */
static int
smtp_read_thread(thread_t * thread)
{
	smtp_t *smtp;
	char *buffer;
	char *reply;
	int rcv_buffer_size = 0;
	int status = -1;

	smtp = THREAD_ARG(thread);

	if (thread->type == THREAD_READ_TIMEOUT) {
		log_message(LOG_INFO, "Timeout reading data to remote SMTP server %s."
				    , FMT_SMTP_HOST());
		SMTP_FSM_READ(QUIT, thread, 0);
		return -1;
	}

	buffer = smtp->buffer;

	rcv_buffer_size = read(thread->u.fd, buffer + smtp->buflen,
			       SMTP_BUFFER_LENGTH - smtp->buflen);

	if (rcv_buffer_size == -1) {
		if (errno == EAGAIN)
			goto end;
		log_message(LOG_INFO, "Error reading data from remote SMTP server %s."
				    , FMT_SMTP_HOST());
		SMTP_FSM_READ(QUIT, thread, 0);
		return 0;
	} else if (rcv_buffer_size == 0) {
		log_message(LOG_INFO, "Remote SMTP server %s has closed the connection."
				    , FMT_SMTP_HOST());
		SMTP_FSM_READ(QUIT, thread, 0);
		return 0;
	}

	/* received data overflow buffer size ? */
	if (smtp->buflen >= SMTP_BUFFER_MAX) {
		log_message(LOG_INFO, "Received buffer from remote SMTP server %s"
				      " overflow our get read buffer length."
				    , FMT_SMTP_HOST());
		SMTP_FSM_READ(QUIT, thread, 0);
		return 0;
	} else {
		smtp->buflen += rcv_buffer_size;
		buffer[smtp->buflen] = 0;	/* NULL terminate */
	}

      end:

	/* parse the buffer, finding the last line of the response for the code */
	reply = buffer;
	while (reply < buffer + smtp->buflen) {
		char *p;

		p = strstr(reply, "\r\n");
		if (!p) {
			memmove(buffer, reply,
				smtp->buflen - (reply - buffer));
			smtp->buflen -= (reply - buffer);
			buffer[smtp->buflen] = 0;

			thread_add_read(thread->master, smtp_read_thread,
					smtp, thread->u.fd,
					global_data->smtp_connection_to);
			return 0;
		}

		if (reply[3] == '-') {
			/* Skip over the \r\n */
			reply = p + 2;
			continue;
		}

		status = ((reply[0] - '0') * 100) + ((reply[1] - '0') * 10) + (reply[2] - '0');

		reply = p + 2;
		break;
	}

	memmove(buffer, reply, smtp->buflen - (reply - buffer));
	smtp->buflen -= (reply - buffer);
	buffer[smtp->buflen] = 0;

	if (status == -1) {
		thread_add_read(thread->master, smtp_read_thread, smtp,
				thread->u.fd, global_data->smtp_connection_to);
		return 0;
	}

	SMTP_FSM_READ(smtp->stage, thread, status);

	/* Registering next smtp command processing thread */
	if (smtp->stage != ERROR) {
		thread_add_write(thread->master, smtp_send_thread, smtp,
				 smtp->fd, global_data->smtp_connection_to);
	} else {
		log_message(LOG_INFO, "Can not read data from remote SMTP server %s."
				    , FMT_SMTP_HOST());
		SMTP_FSM_READ(QUIT, thread, 0);
	}

	return 0;
}