Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
/**
 * 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;
}
Exemplo n.º 4
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;
}