Exemple #1
0
static SOCKET uv__fast_poll_create_peer_socket(HANDLE iocp,
        WSAPROTOCOL_INFOW* protocol_info) {
    SOCKET sock = 0;

    sock = WSASocketW(protocol_info->iAddressFamily,
                      protocol_info->iSocketType,
                      protocol_info->iProtocol,
                      protocol_info,
                      0,
                      WSA_FLAG_OVERLAPPED);
    if (sock == INVALID_SOCKET) {
        return INVALID_SOCKET;
    }

    if (!SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0)) {
        goto error;
    };

    if (CreateIoCompletionPort((HANDLE) sock,
                               iocp,
                               (ULONG_PTR) sock,
                               0) == NULL) {
        goto error;
    }

    return sock;

error:
    closesocket(sock);
    return INVALID_SOCKET;
}
bool SocketConnection::_createSocket()
{
    ConstConnectionDescriptionPtr description = getDescription();
#ifdef _WIN32
    const DWORD flags = WSA_FLAG_OVERLAPPED;
    const SOCKET fd = WSASocketW( AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0,
                                  flags );
#else
    const Socket fd = ::socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
#endif

    if( fd == INVALID_SOCKET )
    {
        LBERROR << "Could not create socket: "
                << lunchbox::sysError << std::endl;
        return false;
    }

    _tuneSocket( fd );

    _readFD  = fd;
    _writeFD = fd; // TCP/IP sockets are bidirectional

    return true;
}
Exemple #3
0
int uv_tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info,
    int tcp_connection) {
  SOCKET socket = WSASocketW(AF_INET,
                             SOCK_STREAM,
                             IPPROTO_IP,
                             socket_protocol_info,
                             0,
                             WSA_FLAG_OVERLAPPED);

  if (socket == INVALID_SOCKET) {
    uv__set_sys_error(tcp->loop, WSAGetLastError());
    return -1;
  }

  tcp->flags |= UV_HANDLE_BOUND;
  tcp->flags |= UV_HANDLE_SHARED_TCP_SOCKET;

  if (tcp_connection) {
    uv_connection_init((uv_stream_t*)tcp);
  }

  if (socket_protocol_info->iAddressFamily == AF_INET6) {
    tcp->flags |= UV_HANDLE_IPV6;
  }

  if (uv_tcp_set_socket(tcp->loop, tcp, socket, 1) != 0) {
    return -1;
  }
  
  tcp->loop->active_tcp_streams++;
  return 0;
}
Exemple #4
0
BOOL Network::InitServer(int _port)
{
	//서버 시작
	int retval;

	if(WSAStartup(MAKEWORD(2,2), &m_Wsa) != 0)
		return FALSE;

	retval = WSAGetLastError();

	//listensocket 초기화
	sockaddr_in accept_addr;
	m_ListenSock = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);

	ZeroMemory(&accept_addr,sizeof(accept_addr));

	//서버 IP, 포트 설정
	accept_addr.sin_port = htons(_port);
	accept_addr.sin_family = AF_INET;
	accept_addr.sin_addr.s_addr  = htonl(INADDR_ANY);

	retval = bind(m_ListenSock, (sockaddr*)&accept_addr, sizeof(sockaddr));
	if(SOCKET_ERROR == retval)
	{
		return FALSE;
	}
	
	retval = listen(m_ListenSock, 10);

	return TRUE;
}
Exemple #5
0
/*
 * @implemented
 */
SOCKET
WSAAPI
socket(IN INT af,
       IN INT type,
       IN INT protocol)
{
    PWSPROCESS Process;
    PWSTHREAD Thread;
    DWORD Flags = 0;
    INT ErrorCode;
    DPRINT("socket: %lx, %lx, %lx\n", af, type, protocol);

    /* Enter prolog */
    if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
    {
        /* Fail here */
        SetLastError(ErrorCode);
        return INVALID_SOCKET;
    }

    /* Check the current open type and use overlapped if it's default */
    if (!Thread->OpenType) Flags = WSA_FLAG_OVERLAPPED;

    /* Make the protocol negative if this is NETBIOS */
    if ((af == AF_NETBIOS) && (protocol > 0)) protocol *= -1;

    /* Now let WSA handle it */
    return WSASocketW(af, type, protocol, NULL, 0, Flags);
}
Exemple #6
0
static void socket_after_fork_child(struct file *f)
{
	struct socket_file *socket_file = (struct socket_file *) f;
	socket_ensure_initialized();
	socket_file->socket = WSASocketW(0, 0, 0, &socket_file->fork_info, 0, 0);
	if (socket_file->socket == INVALID_SOCKET)
		log_error("WSASocketW() failed, error code: %d", socket_file->socket);
}
Exemple #7
0
static SOCKET WSAAPI socket_h(int af, int type, int protocol)
{
  auto thrctx = asev::ev_service::current();
  if (thrctx == nullptr)
  {
    return socket_f(af, type, protocol);
  }
  return WSASocketW(af, type, protocol, NULL, 0, WSA_FLAG_OVERLAPPED);
}
Exemple #8
0
/*
 * @implemented
 */
SOCKET
EXPORT
socket(IN  INT af,
       IN  INT type,
       IN  INT protocol)
{
    return WSASocketW(af,
                      type,
                      protocol,
                      NULL,
                      0,
                      0);
}
Exemple #9
0
SACK_NETWORK_NAMESPACE


   // should pass ipv4? v6? to switch?
SOCKET OpenSocket( LOGICAL v4, LOGICAL bStream, LOGICAL bRaw, int another_offset )
{
	if( another_offset )
	{
		SOCKET result;
      // need to index into saved sockets and try another provider.
		result = WSASocketW(v4?AF_INET:AF_INET6
										 , bRaw?SOCK_RAW:0
										 , 0
										 , v4
										  ?bStream
										  ?globalNetworkData.pProtos+globalNetworkData.tcp_protocol
										  :globalNetworkData.pProtos+globalNetworkData.udp_protocol
										  :bStream
										  ?globalNetworkData.pProtos+globalNetworkData.tcp_protocolv6
										  :globalNetworkData.pProtos+globalNetworkData.udp_protocolv6
										 , 0, 0 );
		return result;
	}
	else
	{
		SOCKET result = WSASocketW(v4?AF_INET:AF_INET6
										 , bRaw?SOCK_RAW:0
										 , 0
										 , v4
										  ?bStream
										  ?globalNetworkData.pProtos+globalNetworkData.tcp_protocol
										  :globalNetworkData.pProtos+globalNetworkData.udp_protocol
										  :bStream
										  ?globalNetworkData.pProtos+globalNetworkData.tcp_protocolv6
										  :globalNetworkData.pProtos+globalNetworkData.udp_protocolv6
										 , 0, 0 );
		return result;
	}
}
Exemple #10
0
static SOCKET WSAAPI accept_h(SOCKET s, struct sockaddr* addr, int* addrlen)
{
  auto thrctx = asev::ev_service::current();
  if (thrctx == nullptr)
  {
    return accept_f(s, addr, addrlen);
  }

  auto corctx = thrctx->get_corctx();
  ACTX_EXPECTS(corctx != nullptr);

  auto coraf = corctx->get_affix<cor_affix>();
  ACTX_EXPECTS(coraf != nullptr);

  io_context& ioctx = coraf->ioctx_;
  DWORD bytes = 0;
  WSABUF* wbuf = &ioctx.wsa_buf_;
  LPOVERLAPPED ol = &ioctx.overlapped_;
  DWORD addr_len = sizeof(SOCKADDR_IN) + 16;
  ioctx.ec_.clear();
  ioctx.opt_ = opt_accept;

  // Make socket.
  auto skt = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
  if (skt == INVALID_SOCKET)
  {
    return INVALID_SOCKET;
  }

  // AcceptEx.
  auto result = ::AcceptEx(s, skt, wbuf->buf, 0, addr_len, addr_len, &bytes, ol);
  // Check AcceptEx result.
  DWORD last_error = ::WSAGetLastError();
  if (!result && last_error != WSA_IO_PENDING)
  {
    close_socket(skt);
    return INVALID_SOCKET;
  }
  else
  {
    corctx->yield();
  }

  if (ioctx.ec_)
  {
    close_socket(skt);
  }

  ioctx.skt_ = skt;
  return skt;
}
Exemple #11
0
int uv_tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info) {
  SOCKET socket = WSASocketW(AF_INET,
                             SOCK_STREAM,
                             IPPROTO_IP,
                             socket_protocol_info,
                             0,
                             WSA_FLAG_OVERLAPPED);

  if (socket == INVALID_SOCKET) {
    uv__set_sys_error(tcp->loop, WSAGetLastError());
    return -1;
  }

  tcp->flags |= UV_HANDLE_BOUND;

  return uv_tcp_set_socket(tcp->loop, tcp, socket, 1);
}
Exemple #12
0
//----------------------------------------------------------------
//  CImpIRestrictedProcess::RP_WSPSocket()
//
//  Note that the newly created socket isn't retruned to the
//  restricted process until the completion of the connect().
//----------------------------------------------------------------
STDMETHODIMP
CImpIRestrictedProcess::RP_WSPSocket(
                                 IN long   af,
                                 IN long   type,
                                 IN long   protocol,
                                 IN RPC_WSAPROTOCOL_INFOW *pProtocolInfo,
                                 IN RPC_GROUP g,
                                 IN DWORD     dwFlags,
                                 IN OUT long *pError )
    {
    SOCKET  SourceSocket;
    DWORD   dwKey;
    HRESULT hr;
    NTSTATUS NtStatus;


    *pError = 0;

    if ( (af != AF_INET) || (type != SOCK_STREAM))
       {
       *pError = WSAEACCES;
       return NOERROR;
       }

    if ((protocol != IPPROTO_TCP)
        && (protocol != IPPROTO_IP))
       {
       *pError = WSAEACCES;
       return NOERROR;
       }

    m_Socket = WSASocketW( af,
                           type,
                           protocol,
                           (WSAPROTOCOL_INFOW*)pProtocolInfo,
                           (GROUP)g,
                           dwFlags );
    if (m_Socket == INVALID_SOCKET)
       {
       *pError = WSAGetLastError();
       return NOERROR;
       }

    return NOERROR;
    }
Exemple #13
0
  void TCPSocket::bind( const wstring& host, const wstring& service,
  Protocol protocol )
  {
    if ( mState != State_Closed )
      EXCEPT( L"Cannot bind, socket is not closed" );

    ADDRINFOW resolve;
    PADDRINFOW address = nullptr;
    PADDRINFOW resolved = nullptr;

    memset( &resolve, 0, sizeof( ADDRINFOW ) );

    resolve.ai_family   = util::protocolToFamily( protocol );
    resolve.ai_socktype = SOCK_STREAM;
    resolve.ai_protocol = IPPROTO_TCP;

    if ( GetAddrInfoW( host.c_str(), service.c_str(), &resolve, &resolved ) )
      EXCEPT_WSA( L"Couldn't resolve" );

    for ( address = resolved; address != nullptr; address = address->ai_next )
    {
      if ( address->ai_socktype != SOCK_STREAM || address->ai_protocol != IPPROTO_TCP )
        continue;

      mSocket = WSASocketW(
        address->ai_family, address->ai_socktype, address->ai_protocol,
        nullptr, 0, mOverlapped ? WSA_FLAG_OVERLAPPED : 0 );

      if ( mSocket == INVALID_SOCKET )
        continue;

      if ( ::bind( mSocket, address->ai_addr, (int)address->ai_addrlen ) != SOCKET_ERROR )
        break;

      closesocket( mSocket );
    }

    if ( address == nullptr )
      EXCEPT_WSA( L"Couldn't bind" );

    mBound = true;

    mConnectionInfo.update( mSocket, false );
  }
Exemple #14
0
/*
 * @implemented
 */
SOCKET
EXPORT
WSASocketA(IN  INT af,
           IN  INT type,
           IN  INT protocol,
           IN  LPWSAPROTOCOL_INFOA lpProtocolInfo,
           IN  GROUP g,
           IN  DWORD dwFlags)
/*
 * FUNCTION: Creates a new socket
 */
{
    WSAPROTOCOL_INFOW ProtocolInfoW;
    LPWSAPROTOCOL_INFOW p;
    UNICODE_STRING StringU;
    ANSI_STRING StringA;

    WS_DbgPrint(MAX_TRACE, ("af (%d)  type (%d)  protocol (%d).\n",
    af, type, protocol));

    if (lpProtocolInfo)
    {
        memcpy(&ProtocolInfoW,
               lpProtocolInfo,
               sizeof(WSAPROTOCOL_INFOA) - sizeof(CHAR) * (WSAPROTOCOL_LEN + 1));
        RtlInitAnsiString(&StringA, (LPSTR)lpProtocolInfo->szProtocol);
        RtlInitUnicodeString(&StringU, (LPWSTR)&ProtocolInfoW.szProtocol);
        RtlAnsiStringToUnicodeString(&StringU, &StringA, FALSE);
        p = &ProtocolInfoW;
    }
    else
    {
        p = NULL;
    }

    return WSASocketW(af,
                      type,
                      protocol,
                      p,
                      g,
                      dwFlags);
}
Exemple #15
0
/*
 * @implemented
 */
SOCKET
WSAAPI
WSASocketA(IN INT af,
           IN INT type,
           IN INT protocol,
           IN LPWSAPROTOCOL_INFOA lpProtocolInfo,
           IN GROUP g,
           IN DWORD dwFlags)
{
    WSAPROTOCOL_INFOW ProtocolInfoW;
    LPWSAPROTOCOL_INFOW p = &ProtocolInfoW;

    /* Convert Protocol Info to Wide */
    if (lpProtocolInfo)
    {
        /* Copy the Data */
        memcpy(&ProtocolInfoW,
               lpProtocolInfo,
               sizeof(WSAPROTOCOL_INFOA) - sizeof(CHAR) * (WSAPROTOCOL_LEN + 1));

        /* Convert the String */
        MultiByteToWideChar(CP_ACP,
                            0,
                            lpProtocolInfo->szProtocol,
                            -1,
                            ProtocolInfoW.szProtocol,
                            sizeof(ProtocolInfoW.szProtocol) / sizeof(WCHAR));
    }
    else
    {
        /* No Protocol Info Specified */
        p = NULL;
    }

    /* Call the Unicode Function */
    return WSASocketW(af,
                      type,
                      protocol,
                      p,
                      g,
                      dwFlags);
}
Exemple #16
0
int uv_tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info,
    int tcp_connection) {
  int err;

  SOCKET socket = WSASocketW(FROM_PROTOCOL_INFO,
                             FROM_PROTOCOL_INFO,
                             FROM_PROTOCOL_INFO,
                             socket_protocol_info,
                             0,
                             WSA_FLAG_OVERLAPPED);

  if (socket == INVALID_SOCKET) {
    return WSAGetLastError();
  }

  if (!SetHandleInformation((HANDLE) socket, HANDLE_FLAG_INHERIT, 0)) {
    err = GetLastError();
    closesocket(socket);
    return err;
  }

  err = uv_tcp_set_socket(tcp->loop,
                          tcp,
                          socket,
                          socket_protocol_info->iAddressFamily,
                          1);
  if (err) {
    closesocket(socket);
    return err;
  }

  if (tcp_connection) {
    uv_connection_init((uv_stream_t*)tcp);
    tcp->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
  }

  tcp->flags |= UV_HANDLE_BOUND;
  tcp->flags |= UV_HANDLE_SHARED_TCP_SOCKET;

  tcp->loop->active_tcp_streams++;
  return 0;
}
Exemple #17
0
int uv_tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info,
    int tcp_connection) {
  SOCKET socket = WSASocketW(AF_INET,
                             SOCK_STREAM,
                             IPPROTO_IP,
                             socket_protocol_info,
                             0,
                             WSA_FLAG_OVERLAPPED);

  if (socket == INVALID_SOCKET) {
    uv__set_sys_error(tcp->loop, WSAGetLastError());
    return -1;
  }

  if (!SetHandleInformation((HANDLE) socket, HANDLE_FLAG_INHERIT, 0)) {
    uv__set_sys_error(tcp->loop, GetLastError());
    closesocket(socket);
    return -1;
  }

  if (uv_tcp_set_socket(tcp->loop,
                        tcp,
                        socket,
                        socket_protocol_info->iAddressFamily,
                        1) < 0) {
    closesocket(socket);
    return -1;
  }

  if (tcp_connection) {
    uv_connection_init((uv_stream_t*)tcp);
    tcp->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
  }

  tcp->flags |= UV_HANDLE_BOUND;
  tcp->flags |= UV_HANDLE_SHARED_TCP_SOCKET;

  tcp->loop->active_tcp_streams++;
  return 0;
}
Exemple #18
0
void	ServerW::init()
{
	WSADATA			wsaData;
	SOCKADDR_IN		sin;

	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
		throw(std::exception("Error on WSAStartup"));

	_socket = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
	if (_socket == INVALID_SOCKET)
		throw(std::exception("Error on WSASocketW"));

	sin.sin_addr.s_addr = INADDR_ANY;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(4242);
	if ((bind(_socket, (struct sockaddr*)&sin, sizeof(sin)) == -1)
		|| (listen(_socket, SOMAXCONN) == -1))
		throw(std::exception("Error on bind or listen"));

	memset(_fdType, FD_FREE, MAX_FD);
	_fdType[_socket] = FD_SERVER;
}
Exemple #19
0
int uv__tcp_xfer_import(uv_tcp_t* tcp,
                        uv__ipc_socket_xfer_type_t xfer_type,
                        uv__ipc_socket_xfer_info_t* xfer_info) {
  int err;
  SOCKET socket;

  assert(xfer_type == UV__IPC_SOCKET_XFER_TCP_SERVER ||
         xfer_type == UV__IPC_SOCKET_XFER_TCP_CONNECTION);

  socket = WSASocketW(FROM_PROTOCOL_INFO,
                      FROM_PROTOCOL_INFO,
                      FROM_PROTOCOL_INFO,
                      &xfer_info->socket_info,
                      0,
                      WSA_FLAG_OVERLAPPED);

  if (socket == INVALID_SOCKET) {
    return WSAGetLastError();
  }

  err = uv_tcp_set_socket(
      tcp->loop, tcp, socket, xfer_info->socket_info.iAddressFamily, 1);
  if (err) {
    closesocket(socket);
    return err;
  }

  tcp->delayed_error = xfer_info->delayed_error;
  tcp->flags |= UV_HANDLE_BOUND | UV_HANDLE_SHARED_TCP_SOCKET;

  if (xfer_type == UV__IPC_SOCKET_XFER_TCP_CONNECTION) {
    uv_connection_init((uv_stream_t*)tcp);
    tcp->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
  }

  tcp->loop->active_tcp_streams++;
  return 0;
}
Exemple #20
0
int uv_tcp_import(uv_tcp_t* tcp, uv__ipc_socket_info_ex* socket_info_ex,
                  int tcp_connection) {
    int err;
    SOCKET socket = WSASocketW(FROM_PROTOCOL_INFO,
                               FROM_PROTOCOL_INFO,
                               FROM_PROTOCOL_INFO,
                               &socket_info_ex->socket_info,
                               0,
                               WSA_FLAG_OVERLAPPED);

    if (socket == INVALID_SOCKET) {
        return WSAGetLastError();
    }

    err = uv_tcp_set_socket(tcp->loop,
                            tcp,
                            socket,
                            socket_info_ex->socket_info.iAddressFamily,
                            1);
    if (err) {
        closesocket(socket);
        return err;
    }

    if (tcp_connection) {
        uv_connection_init((uv_stream_t*)tcp);
        tcp->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
    }

    tcp->flags |= UV_HANDLE_BOUND;
    tcp->flags |= UV_HANDLE_SHARED_TCP_SOCKET;

    tcp->delayed_error = socket_info_ex->delayed_error;

    tcp->loop->active_tcp_streams++;
    return 0;
}
void SocketConnection::acceptNB()
{
    LBASSERT( isListening() );

    // Create new accept socket
    const DWORD flags = WSA_FLAG_OVERLAPPED;

    LBASSERT( _overlappedAcceptData );
    LBASSERT( _overlappedSocket == INVALID_SOCKET );
    _overlappedSocket = WSASocketW( AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0,
                                    flags );

    if( _overlappedSocket == INVALID_SOCKET )
    {
        LBERROR << "Could not create accept socket: " << lunchbox::sysError
                << ", closing listening socket" << std::endl;
        close();
        return;
    }

    const int on = 1;
    setsockopt( _overlappedSocket, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
        reinterpret_cast<const char*>( &on ), sizeof( on ));

    // Start accept
    ResetEvent( _overlappedRead.hEvent );
    DWORD got;
    if( !AcceptEx( _readFD, _overlappedSocket, _overlappedAcceptData, 0,
                   sizeof( sockaddr_in ) + 16, sizeof( sockaddr_in ) + 16,
                   &got, &_overlappedRead ) &&
        GetLastError() != WSA_IO_PENDING )
    {
        LBERROR << "Could not start accept operation: "
                << lunchbox::sysError << ", closing connection" << std::endl;
        close();
    }
}
Exemple #22
0
//===========================================================================
void iSocketInitialize () {
    s_mode = kRunStarting;

    WSADATA data = {};
    WinError err = WSAStartup(WINSOCK_VERSION, &data);
    if (err || data.wVersion != WINSOCK_VERSION) {
        logMsgCrash() << "WSAStartup(version=" << hex << WINSOCK_VERSION
            << "): " << err << ", version " << data.wVersion;
    }

    // get extension functions
    SOCKET s = WSASocketW(
        AF_UNSPEC, 
        SOCK_STREAM, 
        IPPROTO_TCP,
        NULL,   // protocol info (additional creation options)
        0,      // socket group
        WSA_FLAG_REGISTERED_IO
    );
    if (s == INVALID_SOCKET) 
        logMsgCrash() << "socket: " << WinError{};

    // get RIO functions
    GUID extId = WSAID_MULTIPLE_RIO;
    s_rio.cbSize = sizeof(s_rio);
    DWORD bytes;
    if (WSAIoctl(
        s,
        SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER,
        &extId, sizeof(extId),
        &s_rio, sizeof(s_rio),
        &bytes,
        nullptr,    // overlapped
        nullptr     // completion routine
    )) {
        logMsgCrash() << "WSAIoctl(get RIO extension): " << WinError{};
    }
    closesocket(s);

    // initialize buffer allocator
    iSocketBufferInitialize(s_rio);
    // Don't register cleanup until all dependents (aka sockbuf) have
    // registered their cleanups (aka been initialized)
    appMonitorShutdown(&s_cleanup);
    iSocketAcceptInitialize();
    iSocketConnectInitialize();

    // create RIO completion queue
    RIO_NOTIFICATION_COMPLETION ctype = {};
    ctype.Type = RIO_EVENT_COMPLETION;
    ctype.Event.EventHandle = s_cqReady.nativeHandle();
    ctype.Event.NotifyReset = false;
    s_cq = s_rio.RIOCreateCompletionQueue(s_cqSize, &ctype);
    if (s_cq == RIO_INVALID_CQ)
        logMsgCrash() << "RIOCreateCompletionQueue: " << WinError{};

    // start rio dispatch task
    TaskQueueHandle taskq = taskCreateQueue("RIO Dispatch", 1);
    taskPush(taskq, s_dispatchThread);

    s_mode = kRunRunning;
}
Exemple #23
0
/**
 * @brief Opens a server socket
 *
 * @param[in] usPort 16 bit local port number that the server listens on
 * @param[in,optional] iListenQueueSize
 *       size of connection acceptance queue.
 *       This value can be (-1) to use the default value.
 *
 * @param[in]  dwFlags 32 bit flags defining socket creation preferences
 * @param[out] ppSocket Pointer to created socket
 *
 * @return 0 on success
 */
DWORD
VmDnsSockWinOpenServer(
    USHORT               usPort,
    int                  iListenQueueSize,
    VM_SOCK_CREATE_FLAGS dwFlags,
    PVM_SOCKET*          ppSocket
    )
{
    DWORD dwError = 0;
    union
    {
#ifdef AF_INET6
        struct sockaddr_in6 servaddr_ipv6;
#endif
        struct sockaddr_in  servaddr_ipv4;
    } servaddr;
    struct
    {
        int domain;
        int type;
        int protocol;
    } socketParams;
    struct sockaddr* pSockAddr = NULL;
    socklen_t addrLen = 0;
    SOCKET socket = INVALID_SOCKET;
    PVM_SOCKET pSocket = NULL;
    DWORD dwSockFlags = 0;

    if (dwFlags & VM_SOCK_CREATE_FLAGS_IPV6)
    {
#ifdef AF_INET6
        socketParams.domain = AF_INET6;
#else
        dwError = ERROR_NOT_SUPPORTED;
        BAIL_ON_VMDNS_ERROR(dwError);
#endif
    }
    else
    {
        socketParams.domain = AF_INET;
    }

    if (dwFlags & VM_SOCK_CREATE_FLAGS_UDP)
    {
        socketParams.type = SOCK_DGRAM;
    }
    else
    {
        socketParams.type = SOCK_STREAM;
    }

    socketParams.protocol = 0;

    if (dwFlags & VM_SOCK_CREATE_FLAGS_NON_BLOCK)
    {
        dwSockFlags = WSA_FLAG_OVERLAPPED;
    }

    socket = WSASocketW(
                    socketParams.domain,
                    socketParams.type,
                    socketParams.protocol,
                    NULL,
                    0,
                    dwSockFlags);
    if (socket == INVALID_SOCKET)
    {
        dwError = WSAGetLastError();
        BAIL_ON_VMDNS_ERROR(dwError);
    }

    memset(&servaddr, 0, sizeof(servaddr));

    if (dwFlags & VM_SOCK_CREATE_FLAGS_IPV6)
    {
#ifdef AF_INET6
        servaddr.servaddr_ipv6.sin6_family = AF_INET6;
        servaddr.servaddr_ipv6.sin6_addr = in6addr_any;
        servaddr.servaddr_ipv6.sin6_port = htons(usPort);

        pSockAddr = (struct sockaddr*) &servaddr.servaddr_ipv6;
        addrLen = sizeof(servaddr.servaddr_ipv6);
#else
        dwError = ERROR_NOT_SUPPORTED;
        BAIL_ON_VMDNS_ERROR(dwError);
#endif
    }
    else
    {
        servaddr.servaddr_ipv4.sin_family = AF_INET;
        servaddr.servaddr_ipv4.sin_addr.s_addr = htonl(INADDR_ANY);
        servaddr.servaddr_ipv4.sin_port = htons(usPort);

        pSockAddr = (struct sockaddr*) &servaddr.servaddr_ipv4;
        addrLen = sizeof(servaddr.servaddr_ipv4);
    }

    if (bind(socket, pSockAddr, addrLen) < 0)
    {
        dwError = WSAGetLastError();
        BAIL_ON_VMDNS_ERROR(dwError);
    }

    if (!(dwFlags & VM_SOCK_CREATE_FLAGS_UDP))
    {
        if (iListenQueueSize <= 0)
        {
            iListenQueueSize = VM_SOCK_WINDOWS_DEFAULT_LISTEN_QUEUE_SIZE;
        }

        if (listen(socket, iListenQueueSize) < 0)
        {
            dwError = WSAGetLastError();
            BAIL_ON_VMDNS_ERROR(dwError);
        }
    }

    dwError = VmDnsAllocateMemory(sizeof(*pSocket), (PVOID*)&pSocket);
    BAIL_ON_VMDNS_ERROR(dwError);

    pSocket->refCount = 1;
    pSocket->type = VM_SOCK_TYPE_LISTENER;

    if (dwFlags & VM_SOCK_CREATE_FLAGS_UDP)
    {
        pSocket->protocol = VM_SOCK_PROTOCOL_UDP;
    }
    else
    {
        pSocket->protocol = VM_SOCK_PROTOCOL_TCP;
    }

    pSocket->hSocket = socket;
    socket = INVALID_SOCKET;

    *ppSocket = pSocket;

cleanup:

    return dwError;

error:

    if (ppSocket)
    {
        *ppSocket = NULL;
    }

    if (pSocket)
    {
        VmDnsSockWinFreeSocket(pSocket);
    }
    if (socket != INVALID_SOCKET)
    {
        closesocket(socket);
    }

    goto cleanup;
}
Exemple #24
0
int main(int argc, char* argv[]) {
	
	// wsaData
	WSADATA wsaData;
	// Completion Port
	HANDLE hComPort;
	// 시스템 관련 정보를 저장합니다.
	SYSTEM_INFO sysInfo;
	// 버퍼 관련된 정보를 저장합니다.
	LPPER_IO_DATA ioInfo;
	// 클라이언트 소켓과 정보를 저장하는 구조체 입니다.
	LPPER_HANDLE_DATA handleInfo;

	// 서버 소켓입니다.
	SOCKET hServSock;
	// 서버 주소에 관련된 정보를 저장합니다.
	SOCKADDR_IN servAdr;
	int recvBytes, i, flags = 0;

	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
		ErrorHandling("WSAStartup error");
	}

	// CompletionPort 생성
	hComPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
	
	// 시스템 정보를 불러옵니다. 동시에 프로세서 수만큼 스레드를 생성합니다.
	GetSystemInfo(&sysInfo);
	for (i = 0; i < sysInfo.dwNumberOfProcessors; i++)
		_beginthreadex(NULL, 0, EchoThreadMain, (LPVOID)hComPort, 0, NULL);

	// 서버 소켓 생성
	hServSock = WSASocketW(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
	memset(&servAdr, 0, sizeof(servAdr));
	servAdr.sin_family = AF_INET;
	servAdr.sin_addr.s_addr = htonl(INADDR_ANY);
	servAdr.sin_port = htons(argv[1]);

	// bind
	if (bind(hServSock, (SOCKADDR*)&servAdr, sizeof(servAdr)) == SOCKET_ERROR)
		ErrorHandling("bind error!");

	// listen
	if (listen(hServSock, 5) == SOCKET_ERROR)
		ErrorHandling("Listen error");

	while (1) {
		
		// 클라이언트 소켓
		SOCKET hClntSock;
		SOCKADDR_IN clntAdr;
		int addrLen = sizeof(clntAdr);

		// Client Accept하고 handleInfo 구조체에 연결
		hClntSock = accept(hServSock, (SOCKADDR*)&clntAdr, &addrLen);
		handleInfo = (LPPER_HANDLE_DATA)malloc(sizeof(PER_HANDLE_DATA));
		handleInfo->hClntSock = hClntSock;
		handleInfo->clntAdr = clntAdr;
		memcpy(&(handleInfo->clntAdr), &clntAdr, addrLen);

		// CompletionPort에 client socket 연결해서 완료정보를 넘기도록 함
		CreateIoCompletionPort((HANDLE)hClntSock, hComPort, (DWORD)handleInfo, 0);

		// io관련된 구조체 생성 후 recv 대기
		ioInfo = (LPPER_IO_DATA)malloc(sizeof(PER_IO_DATA));
		memset(&(ioInfo->overlapped), 0, sizeof(OVERLAPPED));
		ioInfo->wsaBuf.len = BUF_SIZE;
		ioInfo->wsaBuf.buf = ioInfo->buffer;
		ioInfo->rwMode = READ;
		WSARecv(handleInfo->hClntSock, &(ioInfo->wsaBuf.buf), 1, &recvBytes, &flags, &(ioInfo->overlapped), NULL);
	}

	getchar();
	return 0;
}
Exemple #25
0
/**
 * @brief Opens a client socket
 *
 * @param[in]  pszHost  Target host name or IP Address.
 *                      An empty string will imply the local host.
 * @param[in]  usPort   16 bit port number
 * @param[in]  dwFlags  32 bit flags specifying socket creation preferences
 * @param[out] ppSocket Pointer to created socket context
 *
 * @return 0 on success
 */
DWORD
VmDnsSockWinOpenClient(
    PCSTR                   pszHost,
    USHORT                  usPort,
    VM_SOCK_CREATE_FLAGS    dwFlags,
    PVM_SOCKET*             ppSocket
    )
{
    DWORD                   dwError = 0;
    DWORD                   dwSockFlags = 0;
    int                     nAddressFamily = AF_INET;
    int                     nConnectionType = SOCK_STREAM;
    struct addrinfo         hints = { 0 };
    struct addrinfo*        pAddrInfo = NULL;
    struct addrinfo*        pInfo = NULL;
    struct addrinfo*        pClientAddress = NULL;
    CHAR                    szPort[32] = { 0 };
    SOCKET                  socket = INVALID_SOCKET;
    PVM_SOCKET              pSocket = NULL;

    if (!pszHost || !usPort || !ppSocket)
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDNS_ERROR(dwError);
    }

    if (dwFlags & VM_SOCK_CREATE_FLAGS_IPV6)
    {
        hints.ai_family = AF_INET6;
    }
    else if (dwFlags & VM_SOCK_CREATE_FLAGS_IPV4)
    {
        hints.ai_family = AF_INET;
    }
    else
    {
        hints.ai_family = AF_UNSPEC;
    }

    if (dwFlags & VM_SOCK_CREATE_FLAGS_UDP)
    {
        nConnectionType = hints.ai_socktype = SOCK_DGRAM;
    }
    else
    {
        nConnectionType = hints.ai_socktype = SOCK_STREAM;
    }

    hints.ai_flags = AI_CANONNAME | AI_NUMERICSERV;

    sprintf_s(szPort, sizeof(szPort), "%d", usPort);

    if (getaddrinfo(pszHost, szPort, &hints, &pAddrInfo) != 0)
    {
        dwError = WSAGetLastError();
        BAIL_ON_VMDNS_ERROR(dwError);
    }

    for (pInfo = pAddrInfo;
        (socket == INVALID_SOCKET && pInfo != NULL);
        pInfo = pInfo->ai_next)
    {
        socket = WSASocketW(
                        pInfo->ai_family,
                        pInfo->ai_socktype,
                        pInfo->ai_protocol,
                        NULL,
                        0,
                        dwSockFlags);

        if (socket == INVALID_SOCKET)
        {
            continue;
        }

        if (nConnectionType == SOCK_STREAM)
        {
            if (connect(socket, pInfo->ai_addr, pInfo->ai_addrlen) < 0)
            {
                dwError = WSAGetLastError();
                continue;
            }
        }

        pClientAddress = pInfo;
    }

    if (socket == INVALID_SOCKET)
    {
        dwError = ERROR_CONNECTION_UNAVAIL;
        BAIL_ON_VMDNS_ERROR(dwError);
    }

    dwError = VmDnsAllocateMemory(sizeof(*pSocket), (PVOID*)&pSocket);
    BAIL_ON_VMDNS_ERROR(dwError);

    pSocket->refCount = 1;
    pSocket->type = VM_SOCK_TYPE_CLIENT;

    if (nConnectionType == SOCK_STREAM)
    {
        pSocket->protocol = VM_SOCK_PROTOCOL_TCP;
    }
    else
    {
        pSocket->protocol = VM_SOCK_PROTOCOL_UDP;
    }

    dwError = VmDnsSockWinCopyTargetAddress(pClientAddress, pSocket);
    BAIL_ON_VMDNS_ERROR(dwError);

    pSocket->hSocket = socket;
    socket = INVALID_SOCKET;

    *ppSocket = pSocket;
    pSocket = NULL;

cleanup:

    if (pAddrInfo)
    {
        freeaddrinfo(pAddrInfo);
    }

    return dwError;

error :
    if (socket != INVALID_SOCKET)
    {
        closesocket(socket);
    }

    VMDNS_SAFE_FREE_MEMORY(pSocket);

    goto cleanup;
}
static MHD_socket
start_socket_listen(int domain)
{
/* Create sockets similarly to daemon.c */
  MHD_socket fd;
  int cloexec_set;
  struct sockaddr_in sock_addr;
  socklen_t addrlen;

#ifdef MHD_WINSOCK_SOCKETS
  unsigned long flags = 1;
#else  /* MHD_POSIX_SOCKETS */
  int flags;
#endif /* MHD_POSIX_SOCKETS */

#if defined(MHD_POSIX_SOCKETS) && defined(SOCK_CLOEXEC)
  fd = socket (domain, SOCK_STREAM | SOCK_CLOEXEC, 0);
  cloexec_set = 1;
#elif defined(MHD_WINSOCK_SOCKETS) && defined (WSA_FLAG_NO_HANDLE_INHERIT)
  fd = WSASocketW (domain, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_NO_HANDLE_INHERIT);
  cloexec_set = 1;
#else  /* !SOCK_CLOEXEC */
  fd = socket (domain, SOCK_STREAM, 0);
  cloexec_set = 0;
#endif /* !SOCK_CLOEXEC */
  if ( (MHD_INVALID_SOCKET == fd) && (cloexec_set) )
    {
      fd = socket (domain, SOCK_STREAM, 0);
      cloexec_set = 0;
    }
  if (MHD_INVALID_SOCKET == fd)
    {
      fprintf (stderr, "Can't create socket: %u\n",
               (unsigned)sock_errno);
      return MHD_INVALID_SOCKET;
    }

  if (!cloexec_set)
    {
#ifdef MHD_WINSOCK_SOCKETS
    if (!SetHandleInformation ((HANDLE)fd, HANDLE_FLAG_INHERIT, 0))
      fprintf (stderr, "Failed to make socket non-inheritable: %u\n",
               (unsigned int)GetLastError ());
#else  /* MHD_POSIX_SOCKETS */
    flags = fcntl (fd, F_GETFD);
    if ( ( (-1 == flags) ||
           ( (flags != (flags | FD_CLOEXEC)) &&
             (0 != fcntl (fd, F_SETFD, flags | FD_CLOEXEC)) ) ) )
      fprintf (stderr, "Failed to make socket non-inheritable: %s\n",
               MHD_socket_last_strerr_ ());
#endif /* MHD_POSIX_SOCKETS */
    }

  memset (&sock_addr, 0, sizeof (struct sockaddr_in));
  sock_addr.sin_family = AF_INET;
  sock_addr.sin_port = htons (0);
#if HAVE_SOCKADDR_IN_SIN_LEN
  sock_addr.sin_len = sizeof (struct sockaddr_in);
#endif
  addrlen = sizeof (struct sockaddr_in);

  if (bind (fd, (const struct sockaddr*) &sock_addr, addrlen) < 0)
    {
      fprintf (stderr, "Failed to bind socket: %u\n",
               (unsigned)sock_errno);
      MHD_socket_close_chk_ (fd);
      return MHD_INVALID_SOCKET;
    }

#ifdef MHD_WINSOCK_SOCKETS
  if (0 != ioctlsocket (fd, FIONBIO, &flags))
    {
      fprintf (stderr, "Failed to make socket non-blocking: %u\n",
               (unsigned)sock_errno);
      MHD_socket_close_chk_ (fd);
      return MHD_INVALID_SOCKET;
    }
#else  /* MHD_POSIX_SOCKETS */
  flags = fcntl (fd, F_GETFL);
  if ( ( (-1 == flags) ||
         ( (flags != (flags | O_NONBLOCK)) &&
           (0 != fcntl (fd, F_SETFL, flags | O_NONBLOCK)) ) ) )
    {
      fprintf (stderr, "Failed to make socket non-blocking: %s\n",
              MHD_socket_last_strerr_ ());
      MHD_socket_close_chk_ (fd);
      return MHD_INVALID_SOCKET;
    }
#endif /* MHD_POSIX_SOCKETS */

  if (listen(fd, SOMAXCONN) < 0)
    {
      fprintf (stderr, "Failed to listen on socket: %u\n",
               (unsigned)sock_errno);
      MHD_socket_close_chk_ (fd);
      return MHD_INVALID_SOCKET;
    }

  return fd;
}
Exemple #27
0
int main(int argc, char* argv[]) {

	// WSADATA
	WSADATA wsaData;
	// CP 
	HANDLE hComPort;
	// 시스템 정보
	SYSTEM_INFO sysInfo;
	// Buffer 정보
	LPPER_IO_DATA ioInfo;
	// SOCKET 정보 (Clnt)
	LPPER_HANDLE_DATA handleInfo;

	// 서버 소켓
	SOCKET hServSock;
	// 서버 주소 & 포트정보
	SOCKADDR_IN servAdr;
	// 일반 변수
	int recvBytes, i, flags = 0;
	
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
		ErrorHandling("WSAStartup error");
	}

	// CP 생성
	hComPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
	
	// 시스템 정보 읽어서 Processor갯수만큼 스레드 생성
	GetSystemInfo(&sysInfo);
	for (i = 0; i < sysInfo.dwNumberOfProcessors; i++) {
		_beginthreadex(NULL, 0, EchoThreadMain, (LPVOID)hComPort, 0, NULL);
	}

	// 서버 소켓 생성
	hServSock = WSASocketW(PF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
	memset(&servAdr, 0, sizeof(servAdr));
	servAdr.sin_family = AF_INET;
	servAdr.sin_addr.s_addr = htonl(INADDR_ANY);
	servAdr.sin_port = htons(argv[1]);

	if (bind(hServSock, (SOCKADDR*)&servAdr, sizeof(servAdr)) == SOCKET_ERROR)
		ErrorHandling("bind error");

	if (listen(hServSock, 5) == SOCKET_ERROR)
		ErrorHandling("listen error");

	while (1){
		SOCKET hClntSock;
		SOCKADDR_IN clntAdr;
		int addrLen = sizeof(clntAdr);

		// 클라이언트 Accept후 handleInfo구조체에 클라이언트 소켓정보 할당
		hClntSock = accept(hServSock, (SOCKADDR*)&clntAdr, &addrLen);
		handleInfo = (LPPER_HANDLE_DATA)malloc(sizeof(PER_HANDLE_DATA));
		handleInfo->hClntSock = hClntSock;
		memcpy(&(handleInfo->clntAdr), &clntAdr, addrLen);

		// CP와 소켓 연결
		CreateIoCompletionPort((HANDLE)hClntSock, hComPort, (DWORD)handleInfo, 0);

		// 버퍼 정보에 정보 집어넣고 Recv 대기
		ioInfo = (LPPER_IO_DATA)malloc(sizeof(PER_IO_DATA));
		memset(&(ioInfo->overlapped), 0, sizeof(OVERLAPPED));
		ioInfo->wsaBuf.len = BUF_SIZE;
		ioInfo->wsaBuf.buf = ioInfo->buffer;
		ioInfo->rwMode = READ;
		WSARecv(handleInfo->hClntSock, &(ioInfo->wsaBuf), 1, &recvBytes, &flags, &(ioInfo->overlapped), NULL);
	}

	getchar();
	return 0;
	
}
Exemple #28
0
  void EventTCPSocket::connect( const wstring& host,
  const wstring& service, Protocol protocol )
  {
    if ( mState != State_Closed )
      EXCEPT( L"Cannot connect, socket is not closed" );

    mState = State_Connecting;

    ADDRINFOW resolve;
    PADDRINFOW address = NULL;
    PADDRINFOW resolved = NULL;

    memset( &resolve, NULL, sizeof( ADDRINFOW ) );

    resolve.ai_family   = util::protocolToFamily( protocol );
    resolve.ai_socktype = SOCK_STREAM;
    resolve.ai_protocol = IPPROTO_TCP;

    if ( GetAddrInfoW( host.c_str(), service.c_str(), &resolve, &resolved ) )
    {
      mState = State_Closed;
      EXCEPT_WSA( L"Couldn't resolve" );
    }

    for ( address = resolved; address != nullptr; address = address->ai_next )
    {
      if ( address->ai_socktype != SOCK_STREAM || address->ai_protocol != IPPROTO_TCP )
        continue;

      mSocket = WSASocketW( address->ai_family, address->ai_socktype,
        address->ai_protocol, nullptr, 0,
        mOverlapped ? WSA_FLAG_OVERLAPPED : 0 );

      if ( mSocket == INVALID_SOCKET )
        continue;

      if ( !WSAConnect( mSocket, address->ai_addr, (int)address->ai_addrlen,
        nullptr, nullptr, nullptr, nullptr ) )
        break;

      closesocket( mSocket );
    }

    if ( address == nullptr )
    {
      mState = State_Closed;
      EXCEPT_WSA( L"Couldn't connect" );
    }

    mBound = true;
    
    mConnectionInfo.update( mSocket, false );
    mConnectionInfo.update( mSocket, true );

    if ( WSAEventSelect( mSocket, mNetworkEvent, FD_READ | FD_CLOSE ) == SOCKET_ERROR )
      EXCEPT_WSA( L"Couldn't select socket events" );

    mState = State_Connected;

    for ( SocketListener* listener : mListeners )
      if ( listener->connectCallback( this ) )
        break;
  }
Exemple #29
0
/*
 * Returns: [interfaces (table)]
 */
static int
sock_getifaddrs (lua_State *L)
{
  struct sock_addr *sap;
  int i, res;

#ifndef _WIN32
  struct ifaddrs *result, *rp;

  sys_vm_leave(L);
  res = getifaddrs(&result);
  sys_vm_enter(L);
#else
  INTERFACE_INFO result[8192], *rp;
  SOCKET sd = WSASocketW(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAGS);
  DWORD n;

  sys_vm_leave(L);
  res = WSAIoctl(sd, SIO_GET_INTERFACE_LIST, NULL, 0,
   result, sizeof(result), &n, NULL, NULL);

  closesocket(sd);
  sys_vm_enter(L);
#endif

  if (res == -1)
    return sys_seterror(L, 0);

  lua_createtable(L, 8, 0);
  rp = result;
#ifndef _WIN32
  for (i = 0; rp; rp = rp->ifa_next) {
#else
  for (i = 0; n--; ++rp) {
#endif
#ifndef _WIN32
    sap = (struct sock_addr *) rp->ifa_addr;
#else
    sap = (struct sock_addr *) &rp->iiAddress;
#endif
    if (!sap || sap->u.addr.sa_family == AF_UNSPEC)
      continue;

    lua_newtable(L);
    {
      const int af = sap->u.addr.sa_family;

      if (af == AF_INET
#ifdef AF_INET6
       || af == AF_INET6
#endif
      ) {
        sock_pushaddr(L, sap);
        lua_setfield(L, -2, "addr");
      }

      {
        const char *s = NULL;

        switch (af) {
        case AF_INET: s = "INET"; break;
#ifdef AF_INET6
        case AF_INET6: s = "INET6"; break;
#endif
#ifdef AF_LOCAL
        case AF_LOCAL: s = "LOCAL"; break;
#endif
#ifdef AF_AX25
        case AF_AX25: s = "AX25"; break;
#endif
#ifdef AF_IPX
        case AF_IPX: s = "IPX"; break;
#endif
#ifdef AF_APPLETALK
        case AF_APPLETALK: s = "APPLETALK"; break;
#endif
#ifdef AF_NETROM
        case AF_NETROM: s = "NETROM"; break;
#endif
#ifdef AF_BRIDGE
        case AF_BRIDGE: s = "BRIDGE"; break;
#endif
#ifdef AF_ATMPVC
        case AF_ATMPVC: s = "ATMPVC"; break;
#endif
#ifdef AF_X25
        case AF_X25: s = "X25"; break;
#endif
#ifdef AF_ROSE
        case AF_ROSE: s = "ROSE"; break;
#endif
#ifdef AF_DECnet
        case AF_DECnet: s = "DECnet"; break;
#endif
#ifdef AF_NETBEUI
        case AF_NETBEUI: s = "NETBEUI"; break;
#endif
#ifdef AF_SECURITY
        case AF_SECURITY: s = "SECURITY"; break;
#endif
#ifdef AF_KEY
        case AF_KEY: s = "KEY"; break;
#endif
#ifdef AF_NETLINK
        case AF_NETLINK: s = "NETLINK"; break;
#endif
#ifdef AF_PACKET
        case AF_PACKET: s = "PACKET"; break;
#endif
#ifdef AF_ASH
        case AF_ASH: s = "ASH"; break;
#endif
#ifdef AF_ECONET
        case AF_ECONET: s = "ECONET"; break;
#endif
#ifdef AF_ATMSVC
        case AF_ATMSVC: s = "ATMSVC"; break;
#endif
#ifdef AF_RDS
        case AF_RDS: s = "RDS"; break;
#endif
#ifdef AF_SNA
        case AF_SNA: s = "SNA"; break;
#endif
#ifdef AF_IRDA
        case AF_IRDA: s = "IRDA"; break;
#endif
#ifdef AF_PPPOX
        case AF_PPPOX: s = "PPPOX"; break;
#endif
#ifdef AF_WANPIPE
        case AF_WANPIPE: s = "WANPIPE"; break;
#endif
#ifdef AF_LLC
        case AF_LLC: s = "LLC"; break;
#endif
#ifdef AF_CAN
        case AF_CAN: s = "CAN"; break;
#endif
#ifdef AF_TIPC
        case AF_TIPC: s = "TIPC"; break;
#endif
#ifdef AF_BLUETOOTH
        case AF_BLUETOOTH: s = "BLUETOOTH"; break;
#endif
#ifdef AF_IUCV
        case AF_IUCV: s = "IUCV"; break;
#endif
#ifdef AF_RXRPC
        case AF_RXRPC: s = "RXRPC"; break;
#endif
#ifdef AF_ISDN
        case AF_ISDN: s = "ISDN"; break;
#endif
#ifdef AF_PHONET
        case AF_PHONET: s = "PHONET"; break;
#endif
#ifdef AF_IEEE802154
        case AF_IEEE802154: s = "IEEE802154"; break;
#endif
        default: s = "UNKNOWN";
        }
        if (s) {
          lua_pushstring(L, s);
          lua_setfield(L, -2, "family");
        }
      }

#ifndef _WIN32
      sap = (struct sock_addr *) rp->ifa_netmask;
#else
      sap = (struct sock_addr *) &rp->iiNetmask;
#endif
      if (sap) {
        sock_pushaddr(L, sap);
        lua_setfield(L, -2, "netmask");
      }

#ifndef _WIN32
      sap = (struct sock_addr *) rp->ifa_broadaddr;
#else
      sap = (struct sock_addr *) &rp->iiBroadcastAddress;
#endif
      if (sap) {
        sock_pushaddr(L, sap);
        lua_setfield(L, -2, "broadaddr");
      }

      lua_createtable(L, 0, 5);
      {
#ifndef _WIN32
        const int flags = rp->ifa_flags;
#else
        const int flags = rp->iiFlags;
#endif

        lua_pushboolean(L, flags & IFF_UP);
        lua_setfield(L, -2, "up");

        lua_pushboolean(L, flags & IFF_BROADCAST);
        lua_setfield(L, -2, "broadcast");

        lua_pushboolean(L, flags & IFF_LOOPBACK);
        lua_setfield(L, -2, "loopback");

        lua_pushboolean(L, flags & IFF_POINTOPOINT);
        lua_setfield(L, -2, "pointtopoint");

        lua_pushboolean(L, flags & IFF_MULTICAST);
        lua_setfield(L, -2, "multicast");
      }
      lua_setfield(L, -2, "flags");
    }
    lua_rawseti(L, -2, ++i);
  }
#ifndef _WIN32
  freeifaddrs(result);
#endif
  return 1;
}


/*
 * Arguments: text_address (string), [ip4_tonumber (true)]
 * Returns: [binary_address (string | number)]
 */
static int
sock_inet_pton (lua_State *L)
{
  const char *src = luaL_checkstring(L, 1);
  const int to_ip4 = lua_toboolean(L, 2);
  const int af = (!to_ip4 && strchr(src, ':')) ? AF_INET6 : AF_INET;
  struct sock_addr sa;
  void *inp = sock_addr_get_inp(&sa, af);
  const int in_len = sock_addr_get_inlen(af);
#ifdef _WIN32
  union sys_rwptr src_ptr;  /* to avoid "const cast" warning */
#endif

  memset(&sa, 0, sizeof(struct sock_addr));
  if (*src == '*') goto end;

#ifndef _WIN32
  if (inet_pton(af, src, inp) == 1) {
#else
  sa.addrlen = sizeof(sa);
  src_ptr.r = src;
  if (!WSAStringToAddressA(src_ptr.w, af, NULL,
   &sa.u.addr, &sa.addrlen)) {
#endif
 end:
    if (to_ip4)
      lua_pushnumber(L, ntohl(*((unsigned long *) inp)));
    else
      lua_pushlstring(L, inp, in_len);
    return 1;
  }
  return sys_seterror(L, 0);
}

/*
 * Arguments: binary_address (string | number)
 * Returns: [text_address (string)]
 */
static int
sock_inet_ntop (lua_State *L)
{
  const int is_ip4 = (lua_type(L, 1) == LUA_TNUMBER);
  unsigned long ip4;
  int in_len, af;
  const char *src;
  char buf[48];

  if (is_ip4) {
    const lua_Number num = lua_tonumber(L, 1);

    in_len = 4;
    af = AF_INET;
    ip4 = htonl((unsigned long) num);
    src = (const char *) &ip4;
  } else {
    src = sock_checkladdr(L, 1, &in_len, &af);
  }

#ifndef _WIN32
  if (inet_ntop(af, src, buf, sizeof(buf)) == NULL)
    goto err;
#else
  {
    struct sock_addr sa;
    void *inp = sock_addr_get_inp(&sa, af);
    const int sl = (af == AF_INET) ? sizeof(struct sockaddr_in)
     : sizeof(struct sockaddr_in6);
    DWORD buflen = sizeof(buf);

    memset(&sa, 0, sizeof(struct sock_addr));
    memcpy(inp, src, in_len);
    sa.u.addr.sa_family = (short) af;

    if (WSAAddressToStringA(&sa.u.addr, sl, NULL, buf, &buflen)
     || buflen >= sizeof(buf))
      goto err;
  }
#endif
  lua_pushstring(L, buf);
  return 1;
 err:
  return sys_seterror(L, 0);
}


/*
 * Returns: sock_addr_udata
 */
static int
sock_addr_new (lua_State *L)
{
  lua_newuserdata(L, sizeof(struct sock_addr));
  luaL_getmetatable(L, SA_TYPENAME);
  lua_setmetatable(L, -2);
  return 1;
}

/*
 * Arguments: sock_addr_udata, [port (number), binary_address (string)]
 * Returns: sock_addr_udata | port (number), binary_address (string)
 */
static int
sock_addr_inet (lua_State *L)
{
  struct sock_addr *sap = checkudata(L, 1, SA_TYPENAME);

  if (lua_gettop(L) == 1) {
    const int af = sap->u.addr.sa_family;

    if (af == AF_INET) {
      lua_pushinteger(L, ntohs(sap->u.in.sin_port));
      lua_pushlstring(L, (char *) &sap->u.in.sin_addr,
       sizeof(struct in_addr));
    } else if (af == AF_INET6) {
      lua_pushinteger(L, ntohs(sap->u.in6.sin6_port));
      lua_pushlstring(L, (char *) &sap->u.in6.sin6_addr,
       sizeof(struct in6_addr));
    } else
      return 0;
    return 2;
  } else {
    const int port = (int) lua_tointeger(L, 2);
    int in_len = SOCK_ADDR_LEN, af = AF_INET;
    const char *addr = lua_isnoneornil(L, 3) ? NULL
     : sock_checkladdr(L, 3, &in_len, &af);

    memset(sap, 0, sizeof(struct sock_addr));
    sap->u.addr.sa_family = (short) af;
    if (af == AF_INET) {
      sap->u.in.sin_port = htons((unsigned short) port);
      if (addr)
        memcpy(&sap->u.in.sin_addr, addr, in_len);
      sap->addrlen = sizeof(struct sockaddr_in);
    } else {
      sap->u.in6.sin6_port = htons((unsigned short) port);
      if (addr)
        memcpy(&sap->u.in6.sin6_addr, addr, in_len);
      sap->addrlen = sizeof(struct sockaddr_in6);
    }
    lua_settop(L, 1);
    return 1;
  };
}

/*
 * Arguments: sock_addr_udata, [path (string)]
 * Returns: sock_addr_udata | path (string)
 */
static int
sock_addr_file (lua_State *L)
{
  struct sock_addr *sap = checkudata(L, 1, SA_TYPENAME);

#ifndef _WIN32
  if (lua_gettop(L) == 1) {
    if (sap->u.addr.sa_family == AF_LOCAL) {
      lua_pushstring(L, sap->u.un.sun_path);
      return 1;
    }
  } else {
    size_t len;
    const char *path = luaL_checklstring(L, 2, &len);

    if (len < sizeof(sap->u.un.sun_path)) {
      sap->u.un.sun_family = AF_LOCAL;
      sap->addrlen = ++len;
      memcpy(sap->u.un.sun_path, path, len);

      lua_settop(L, 1);
      return 1;
    }
  };
#else
  (void) sap;
#endif
  return 0;
}

/*
 * Arguments: sock_addr_udata, sd_udata
 * Returns: [sock_addr_udata]
 */
static int
sock_addr_getsockname (lua_State *L)
{
  struct sock_addr *sap = checkudata(L, 1, SA_TYPENAME);
  sd_t sd = (sd_t) lua_unboxinteger(L, 2, SD_TYPENAME);

  sap->addrlen = SOCK_ADDR_LEN;
  if (!getsockname(sd, &sap->u.addr, &sap->addrlen)) {
    lua_settop(L, 1);
    return 1;
  }
  return sys_seterror(L, 0);
}

/*
 * Arguments: sock_addr_udata, sd_udata
 * Returns: [sock_addr_udata]
 */
static int
sock_addr_getpeername (lua_State *L)
{
  struct sock_addr *sap = checkudata(L, 1, SA_TYPENAME);
  sd_t sd = (sd_t) lua_unboxinteger(L, 2, SD_TYPENAME);

  sap->addrlen = SOCK_ADDR_LEN;
  if (!getpeername(sd, &sap->u.addr, &sap->addrlen)) {
    lua_settop(L, 1);
    return 1;
  }
  return sys_seterror(L, 0);
}

/*
 * Arguments: sock_addr_udata
 * Returns: string
 */
static int
sock_addr_tostring (lua_State *L)
{
  struct sock_addr *sap = checkudata(L, 1, SA_TYPENAME);

  lua_pushfstring(L, SA_TYPENAME " (%p)", sap);
  return 1;
}


#define ADDR_METHODS \
  {"getaddrinfo",	sock_getaddrinfo}, \
  {"getnameinfo",	sock_getnameinfo}, \
  {"getifaddrs",	sock_getifaddrs}, \
  {"inet_pton",		sock_inet_pton}, \
  {"inet_ntop",		sock_inet_ntop}, \
  {"addr",		sock_addr_new}

static luaL_Reg addr_meth[] = {
  {"inet",		sock_addr_inet},
  {"file",		sock_addr_file},
  {"getsockname",	sock_addr_getsockname},
  {"getpeername",	sock_addr_getpeername},
  {"__tostring",	sock_addr_tostring},
  {NULL, NULL}
};
Exemple #30
0
//===========================================================================
SOCKET winSocketCreate () {
    SOCKET handle = WSASocketW(
        AF_UNSPEC,
        SOCK_STREAM,
        IPPROTO_TCP,
        NULL,
        0,
        WSA_FLAG_REGISTERED_IO
    );
    if (handle == INVALID_SOCKET) {
        logMsgError() << "WSASocket: " << WinError{};
        return INVALID_SOCKET;
    }

    int yes = 1;

    //DWORD bytes;
    //if (SOCKET_ERROR == WSAIoctl(
    //    handle,
    //    SIO_LOOPBACK_FAST_PATH,
    //    &yes, sizeof yes,
    //    nullptr, 0, // output buffer, buffer size
    //    &bytes,     // bytes returned
    //    nullptr,    // overlapped
    //    nullptr     // completion routine
    //)) {
    //    logMsgError() << "WSAIoctl(SIO_LOOPBACK_FAST_PATH): " << WinError{};
    //}

    if (SOCKET_ERROR == setsockopt(
        handle,
        SOL_SOCKET,
        TCP_NODELAY,
        (char *) &yes,
        sizeof(yes)
    )) {
        logMsgError() << "WSAIoctl(FIONBIO): " << WinError{};
    }

#ifdef SO_REUSE_UNICASTPORT
    if (SOCKET_ERROR == setsockopt(
        handle,
        SOL_SOCKET,
        SO_REUSE_UNICASTPORT,
        (char *) &yes,
        sizeof(yes)
    )) {
#endif        
        if (SOCKET_ERROR == setsockopt(
            handle, 
            SOL_SOCKET, 
            SO_PORT_SCALABILITY, 
            (char *) &yes, 
            sizeof(yes)
        )) {
            logMsgError() << "setsockopt(SO_PORT_SCALABILITY): " 
                << WinError{};
        }
#ifdef SO_REUSE_UNICASTPORT
    }
#endif

    return handle;
}