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; }
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; }
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; }
/* * @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); }
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); }
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); }
/* * @implemented */ SOCKET EXPORT socket(IN INT af, IN INT type, IN INT protocol) { return WSASocketW(af, type, protocol, NULL, 0, 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; } }
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; }
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); }
//---------------------------------------------------------------- // 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; }
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 ); }
/* * @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); }
/* * @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); }
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; }
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; }
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; }
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; }
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(); } }
//=========================================================================== 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; }
/** * @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; }
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; }
/** * @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; }
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; }
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; }
/* * 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} };
//=========================================================================== 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; }