int32_t connector_start(connector_t* con) { if (!con || con->h.fd < 0) return -1; sock_set_nonblock(con->h.fd); sock_set_nodelay(con->h.fd); return reactor_register(con->r, &con->h, EVENT_IN); }
/** * Initialization if IPC stuff * * @param __hostname - server hostname * @param __port - server port * @return socket to use */ static int lrvm_ipc_init (const char *__hostname, long __port) { char buf[128]; sock = sock_create_client_inet (__hostname, __port); if (sock < 0) { term (); } sock_set_nonblock (sock, TRUE); lrvm_ipc_wait_answer (127, buf); if (strncmp (buf, "+OK", 3)) { /* If answer not equals to +OK, smth strange has been */ /* happened, so terminate */ term (); } return sock; }
int main(void) { static const char HELLO[] = "hello, world!"; HANDLE epoll_port; SOCKET send_sock, recv_sock; { /* Create an epoll instance. */ epoll_port = epoll_create(1); check(epoll_port != NULL); } { /* Create a TCP socket pair. */ SOCKET socks[2]; int r = tcp_socketpair(socks); check(r == 0); send_sock = socks[0]; recv_sock = socks[1]; } { /* Enable non-blocking mode on the receiving end. */ int r = sock_set_nonblock(recv_sock, true); check(r == 0); } { /* Send some data in order to trigger an event on the receiving socket. */ int r = send(send_sock, HELLO, sizeof HELLO, 0); check(r == sizeof HELLO); } { /* Add the receiving socket to the epoll set. */ struct epoll_event ev; int r; ev.events = EPOLLIN | EPOLLONESHOT; ev.data.sock = recv_sock; r = epoll_ctl(epoll_port, EPOLL_CTL_ADD, recv_sock, &ev); check(r >= 0); } { /* Receive the EPOLLIN event for recv_sock. */ struct epoll_event ev; int r; memset(&ev, 0, sizeof ev); r = epoll_wait(epoll_port, &ev, 1, -1); check(r == 1); check(ev.events == EPOLLIN); check(ev.data.sock == recv_sock); } { /* Read the data from the socket. */ char buffer[16]; int r = recv(recv_sock, buffer, sizeof buffer, 0); check(r > 0); } { /* Since the last epoll_ctl() call specified the EPOLLONESOT flag, * no events should be reported here -- neither EPOLLIN nor EPOLLHUP. */ static const int timeout = 250; /* Quarter second. */ struct epoll_event ev; int r; memset(&ev, 0, sizeof ev); r = epoll_wait(epoll_port, &ev, 1, timeout); check(r == 0); /* Time-out. */ } { /* Attempt to EPOLL_CTL_ADD the socket to the port. This should fail, * because EPOLLONESHOT causes events to be disabled after one is reported, * but the socket should not be dropped from the epoll set. */ struct epoll_event ev; int r; ev.events = EPOLLIN | EPOLLONESHOT; ev.data.sock = recv_sock; r = epoll_ctl(epoll_port, EPOLL_CTL_ADD, recv_sock, &ev); check(r == -1); check(errno == EEXIST); check(GetLastError() == ERROR_ALREADY_EXISTS); } { /* Modify the read socket event mask to EPOLLRDHUP. */ struct epoll_event ev; int r; ev.events = EPOLLRDHUP | EPOLLONESHOT; ev.data.sock = recv_sock; r = epoll_ctl(epoll_port, EPOLL_CTL_MOD, recv_sock, &ev); check(r == 0); } { /* Send some data, which will never be read by the receiving end, otherwise * Windows won't detect that the connection is closed. */ int r = send(send_sock, HELLO, sizeof HELLO, 0); check(r == sizeof HELLO); } { /* Send FIN packet. */ int r = shutdown(send_sock, SD_SEND); check(r == 0); } { /* Receive the EPOLLRDHUP event for recv_sock. */ struct epoll_event ev; int r; memset(&ev, 0, sizeof ev); r = epoll_wait(epoll_port, &ev, 1, -1); check(r == 1); check(ev.events == EPOLLRDHUP); check(ev.data.sock == recv_sock); } { /* Close to receiving socket, so the sending socket should detect a * connection hang-up */ int r = closesocket(recv_sock); check(r == 0); } { /* Add the *write* socket to the epoll set. The event mask is empty, but * since EPOLLHUP and EPOLLERR are always reportable, the next call to * epoll_wait() should detect that the connection has been closed. */ struct epoll_event ev; int r; ev.events = 0; ev.data.sock = send_sock; r = epoll_ctl(epoll_port, EPOLL_CTL_ADD, send_sock, &ev); check(r == 0); } { /* Receive the EPOLLHUP event for write end of the connection. */ struct epoll_event ev; int r; memset(&ev, 0, sizeof ev); r = epoll_wait(epoll_port, &ev, 1, -1); check(r == 1); check(ev.events == EPOLLHUP); check(ev.data.sock == send_sock); } { /* Close the send socket. */ int r = closesocket(send_sock); check(r == 0); } { /* Close the epoll port. */ int r = epoll_close(epoll_port); check(r == 0); } return 0; }
int node_connect(int link, struct node *local_node, struct node *remote_node) { int fd; int ret; struct sockaddr local_addr; struct sockaddr remote_addr; struct sock_packet *sock_pkt; fd_set rset; fd_set wset; struct timeval tv; int error; int len; if(link == NODE_DATA_LINK && remote_node->data_conn_state == NODE_DFD_CONNECTED) { return 0; } if(link == NODE_META_LINK && remote_node->meta_conn_state == NODE_MFD_CONNECTED) { return 0; } fd = sock_create(); if(fd < 0) { return -1; } if(sock_get_addr(local_node->remote_ip, NULL, &local_addr) < 0) { goto err; } if(sock_get_addr(remote_node->remote_ip, remote_node->remote_port, &remote_addr) < 0) { goto err; } if(sock_bind(fd, &local_addr) < 0) { goto err; } sock_set_nonblock(fd); ret = sock_connect(fd, &remote_addr); if(ret < 0 && errno != EINPROGRESS) { goto err; } else if(ret == 0) { goto done; } else { FD_ZERO(&rset); FD_SET(fd, &rset); wset = rset; tv.tv_sec = SOCK_TIMEOUT; tv.tv_usec = 0; ret = select(SELECT_MAX_FDS, &rset, &wset, NULL, &tv); if(ret <= 0) { goto err; } error = 0; len = sizeof(int); if(FD_ISSET(fd, &rset) || FD_ISSET(fd, &wset)) { if(getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { goto err; } } if(error) { goto err; } goto done; } done: if(link == NODE_DATA_LINK) { sock_pkt = create_sock_packet(local_node->id, DATA_HANDSHAKE); } else if(link == NODE_META_LINK) { sock_pkt = create_sock_packet(local_node->id, META_HANDSHAKE); } else { goto err; } if(sock_pkt == NULL) { goto err; } sock_clear_nonblock(fd); sock_packet_send(fd, sock_pkt); free_sock_packet(sock_pkt); if(link == NODE_DATA_LINK) { remote_node->dfd = fd; } else if(link == NODE_META_LINK) { remote_node->mfd = fd; } return 0; err: sock_close(fd); return -1; }