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; } }
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; } } }
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; }
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; }
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; }
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; } }
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; }
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; } }
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; }
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; }
/* 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; }