/********************************************************************** * %FUNCTION: free_state * %ARGUMENTS: * state -- EventTcpState to free * %RETURNS: * Nothing * %DESCRIPTION: * Frees all state associated with the TcpEvent. ***********************************************************************/ static void free_state(EventTcpState *state) { if (!state) return; EVENT_DEBUG(("tcp_free_state(state=%p)\n", state)); if (state->buf) free(state->buf); if (state->eh) Event_DelHandler(state->es, state->eh); free(state); }
/********************************************************************** * %FUNCTION: network_init * %ARGUMENTS: * es -- an event selector * %RETURNS: * >= 0 if all is OK, <0 if not * %DESCRIPTION: * Initializes network; opens socket on UDP port 1701; sets up * event handler for incoming packets. ***********************************************************************/ int l2tp_network_init(EventSelector *es) { struct sockaddr_in me; int flags; gethostname(Hostname, sizeof(Hostname)); Hostname[sizeof(Hostname)-1] = 0; Event_HandleSignal(es, SIGINT, sigint_handler); if (Sock >= 0) { if (NetworkReadHandler) { Event_DelHandler(es, NetworkReadHandler); NetworkReadHandler = NULL; } close(Sock); Sock = -1; } Sock = socket(PF_INET, SOCK_DGRAM, 0); if (Sock < 0) { l2tp_set_errmsg("network_init: socket: %s", strerror(errno)); return -1; } me.sin_family = AF_INET; me.sin_addr = Settings.listen_addr; me.sin_port = htons((uint16_t) Settings.listen_port); if (bind(Sock, (struct sockaddr *) &me, sizeof(me)) < 0) { l2tp_set_errmsg("network_init: bind: %s", strerror(errno)); close(Sock); Sock = -1; return -1; } /* Set socket non-blocking */ flags = fcntl(Sock, F_GETFL); flags |= O_NONBLOCK; fcntl(Sock, F_SETFL, flags); /* Set up the network read handler */ Event_AddHandler(es, Sock, EVENT_FLAG_READABLE, network_readable, NULL); return Sock; }
/********************************************************************** * %FUNCTION: handle_connect * %ARGUMENTS: * es -- event selector * fd -- socket * flags -- ignored * data -- the accept callback function * %RETURNS: * Nothing * %DESCRIPTION: * Calls accept; if a connection arrives, calls the accept callback * function with connected descriptor ***********************************************************************/ static void handle_connect(EventSelector *es, int fd, unsigned int flags, void *data) { int error = 0; socklen_t len = sizeof(error); EventTcpConnectState *state = (EventTcpConnectState *) data; EVENT_DEBUG(("tcp_handle_connect(es=%p, fd=%d, flags=%u, data=%p)\n", es, fd, flags, data)); /* Cancel writable event */ Event_DelHandler(es, state->conn); state->conn = NULL; /* Timeout? */ if (flags & EVENT_FLAG_TIMEOUT) { errno = ETIMEDOUT; state->f(es, fd, EVENT_TCP_FLAG_TIMEOUT, state->data); free(state); return; } /* Check for pending error */ if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { state->f(es, fd, EVENT_TCP_FLAG_IOERROR, state->data); free(state); return; } if (error) { errno = error; state->f(es, fd, EVENT_TCP_FLAG_IOERROR, state->data); free(state); return; } /* It looks cool! */ state->f(es, fd, EVENT_TCP_FLAG_COMPLETE, state->data); free(state); }