Example #1
0
static void
socket_accept(int fd, int flags, void *data) {
  int                 sock, error;
  struct sockaddr_in  remote;
  socklen_t           n;
  qsocket_t          *socket;
  lua_State          *state;
  qengine_t          *engine;
  qactor_t           *actor;

  UNUSED(fd);
  UNUSED(flags);

  n = sizeof(remote);

  socket = (qsocket_t*)data;
  qassert(socket->state == QINET_STATE_ACCEPTING);
  actor = qactor_get(socket->aid);
  if (actor == NULL) {
    return;
  }
  actor->waiting_netio = 0;
  state = actor->state;
  sock = qnet_tcp_accept(socket->fd, (struct sockaddr*)&remote,
                         &n, &error);
  if (sock == -1) {
    lua_pushnil(state);
    lua_pushfstring(state, "%s accept error:%s",
                    socket->peer, strerror(error));
    qlua_resume(state, 2);
    return;
  }

  /* restore the listen fd state */
  engine = qactor_get_engine(actor->aid);
  qevent_del(&socket->event, QEVENT_READ);
  socket->state = QINET_STATE_LISTENING;
  
  socket = new_tcp_socket(sock, state, actor, &remote);
  if (!socket) {
    qnet_close(fd);
    lua_pushnil(state);
    lua_pushliteral(state, "create socket error");
    qlua_resume(state, 2);
    return;
  }
  lua_pushlightuserdata(state, socket);
  qlua_resume(state, 1);
  return;
}
Example #2
0
static void
socket_connect(int fd, int flags, void *data) {
  int                 error;
  socklen_t           len;
  struct sockaddr_in  remote;
  qsocket_t          *socket;
  lua_State          *state;
  qengine_t          *engine;
  qactor_t           *actor;

  UNUSED(flags);
  UNUSED(data);

  actor = (qactor_t*)data;
  actor->waiting_netio = 0;
  state = actor->state;
  engine = qactor_get_engine(actor->aid);

  socket = new_tcp_socket(fd, state, actor, &remote);
  if (!socket) {
    qnet_close(fd);
    lua_pushnil(state);
    lua_pushliteral(state, "create socket error");
    qlua_resume(state, 2);
    return;
  }
  socket->state = QINET_STATE_CONNECTED;

  error = 0;
  len = sizeof(error);
  getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
  if (error == -1) {
    qevent_del(&socket->event, socket->event.events);
    qnet_close(socket->event.fd);
  } else if (error == 0) {
    qevent_del(&socket->event, QEVENT_WRITE);
  }   
  
  lua_pushlightuserdata(state, socket);
  qlua_resume(state, 1);
  return;
}
Example #3
0
SOCKET make_tcp_connection(const char *host, unsigned short port, unsigned int *ip)
{
    struct sockaddr_in sin;
    SOCKET     f;

    memset(&sin, 0, sizeof(sin));
    sin.sin_port = htons(port);
    sin.sin_family = AF_INET;
    if((sin.sin_addr.s_addr = lookup_ip(host)) == 0)
        return INVALID_SOCKET;
    if(ip)
        *ip = sin.sin_addr.s_addr;
    if((f = new_tcp_socket(ON_NONBLOCKING)) == INVALID_SOCKET)
        return INVALID_SOCKET;

    /* if an interface was specify, bind to it before connecting */
    if(global.iface)
        bind_interface(f, global.iface, 0);

    /* turn on TCP/IP keepalive messages */
    set_keepalive(f, 1);
    log_message_level(LOG_LEVEL_DEBUG, "make_tcp_connection: connecting to %s:%hu", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
    if(connect(f, (struct sockaddr *) &sin, sizeof(sin)) < 0)
    {
        if(N_ERRNO != EINPROGRESS
#ifdef WIN32
            /* winsock returns EWOULDBLOCK even in nonblocking mode! ugh!!! */
            && N_ERRNO != EWOULDBLOCK
#endif
            )
        {
            nlogerr("make_tcp_connection", "connect");
            CLOSE(f);
            return INVALID_SOCKET;
        }
        log_message_level(LOG_LEVEL_SERVER, "make_tcp_connection: connection to %s in progress", host);
    }
    else
        log_message_level(LOG_LEVEL_SERVER, "make_tcp_connection: connection established to %s", host);
    return f;
}
Example #4
0
static int
qltcp_accept(lua_State *state) {
  int                 fd, error;
  int                 timeout;
  struct sockaddr_in  remote;
  socklen_t           n;
  qactor_t           *actor;
  qsocket_t          *socket;
  qengine_t          *engine;

  socket = (qsocket_t*)lua_touserdata(state, 1);
  n = sizeof(remote);
  actor = qlua_get_actor(state);
  timeout = (int)lua_tonumber(state, 2);
  UNUSED(timeout);

  if (socket == NULL) {
    lua_pushnil(state);
    lua_pushfstring(state, "socket nil");
    return 2;
  }

  if (!socket->accept) {
    lua_pushnil(state);
    lua_pushfstring(state, "not accept socket");
    return 2;
  }

  if (socket->state != QINET_STATE_LISTENING &&
      socket->state != QINET_STATE_ACCEPTING) {
    lua_pushnil(state);
    lua_pushfstring(state, "socket state %d error", socket->state);
    return 2;
  }

  fd = qnet_tcp_accept(socket->fd, (struct sockaddr*)&remote, &n, &error);
  if (fd == -1) {
    lua_pushnil(state);
    lua_pushfstring(state, "%s accept error:%s",
                    socket->peer, strerror(error));
    return 2;
  }
  if (fd == 0) {
    engine = qactor_get_engine(actor->aid);
    socket->state = QINET_STATE_ACCEPTING;
    socket->event.read = socket_accept;
    qevent_add(engine, &socket->event, QEVENT_READ);
    actor->waiting_netio = 1;
    return lua_yield(state, 0); 
  }

  socket = new_tcp_socket(fd, state, actor, &remote);
  if (!socket) {
    qnet_close(fd);
    lua_pushnil(state);
    lua_pushliteral(state, "create socket error");
    return 2;
  }

  lua_pushlightuserdata(state, socket);
  return 1;
}