BOOL GetAddress(const WCHAR *name, INTERNET_PORT port, struct sockaddr *psa, int *sa_len, char *addr_str) { ADDRINFOW *res, hints; void *addr = NULL; int ret; TRACE("%s\n", debugstr_w(name)); memset( &hints, 0, sizeof(hints) ); /* Prefer IPv4 to IPv6 addresses, since some servers do not listen on * their IPv6 addresses even though they have IPv6 addresses in the DNS. */ hints.ai_family = AF_INET; ret = GetAddrInfoW(name, NULL, &hints, &res); if (ret != 0) { TRACE("failed to get IPv4 address of %s, retrying with IPv6\n", debugstr_w(name)); hints.ai_family = AF_INET6; ret = GetAddrInfoW(name, NULL, &hints, &res); } if (ret != 0) { TRACE("failed to get address of %s\n", debugstr_w(name)); return FALSE; } if (*sa_len < res->ai_addrlen) { WARN("address too small\n"); FreeAddrInfoW(res); return FALSE; } *sa_len = res->ai_addrlen; memcpy( psa, res->ai_addr, res->ai_addrlen ); /* Copy port */ switch (res->ai_family) { case AF_INET: addr = &((struct sockaddr_in *)psa)->sin_addr; ((struct sockaddr_in *)psa)->sin_port = htons(port); break; case AF_INET6: addr = &((struct sockaddr_in6 *)psa)->sin6_addr; ((struct sockaddr_in6 *)psa)->sin6_port = htons(port); break; } if(addr_str) inet_ntop(res->ai_family, addr, addr_str, INET6_ADDRSTRLEN); FreeAddrInfoW(res); return TRUE; }
DWORD SrvConOpen(PWCHAR Host, PWCHAR Port, PSRV_CON *pSrvCon) { SOCKET Socket; DWORD Err; ADDRINFOW Hints, *AddrInfo; PSRV_CON SrvCon; int OptVal; SrvCon = malloc(sizeof(*SrvCon)); if (!SrvCon) return FB_E_NO_MEMORY; memset(SrvCon, 0, sizeof(*SrvCon)); memset(&Hints, 0, sizeof(Hints)); Hints.ai_family = AF_INET; Hints.ai_socktype = SOCK_STREAM; Hints.ai_protocol = IPPROTO_TCP; Hints.ai_flags = AI_PASSIVE; if (GetAddrInfoW(Host, Port, &Hints, &AddrInfo)) { Err = WSAGetLastError(); printf("GetAddrInfoW failed Error %d\n", Err); free(SrvCon); return Err; } Socket = socket(AddrInfo->ai_family, AddrInfo->ai_socktype, AddrInfo->ai_protocol); if (Socket == INVALID_SOCKET) { Err = WSAGetLastError(); FreeAddrInfoW(AddrInfo); free(SrvCon); return Err; } OptVal = 1; if (setsockopt(Socket, SOL_SOCKET, SO_REUSEADDR, (char *) &OptVal, sizeof (OptVal))) { Err = WSAGetLastError(); printf("socket connect failed Error %d\n", Err); FreeAddrInfoW(AddrInfo); closesocket(Socket); free(SrvCon); return Err; } if (connect(Socket, AddrInfo->ai_addr, (int)AddrInfo->ai_addrlen)) { Err = WSAGetLastError(); printf("socket connect failed Error %d\n", Err); FreeAddrInfoW(AddrInfo); closesocket(Socket); free(SrvCon); return Err; } SrvCon->Socket = Socket; *pSrvCon = SrvCon; return 0; }
static void uv__getaddrinfo_work(struct uv__work* w) { uv_getaddrinfo_t* req; int err; req = container_of(w, uv_getaddrinfo_t, work_req); err = GetAddrInfoW(req->node, req->service, req->hints, &req->res); req->retcode = uv__getaddrinfo_translate_error(err); }
int make_serv_sock(SERVINFO *servinfo, int servinfonum) { ADDRINFOW aiwHints; ADDRINFOW *paiwResult; ADDRINFOW *paiw; int i; BOOL use = TRUE; ZeroMemory(&aiwHints, sizeof(aiwHints)); if(!serv_loopback) { aiwHints.ai_flags = AI_PASSIVE; } aiwHints.ai_family = AF_UNSPEC; aiwHints.ai_socktype = SOCK_STREAM; aiwHints.ai_protocol = IPPROTO_TCP; if(GetAddrInfoW(nullptr, serv_port, &aiwHints, &paiwResult) != 0) { return 0; } for(i = 0, paiw = paiwResult; i < servinfonum, paiw != nullptr; paiw = paiw->ai_next) { servinfo[i].sock = socket(paiw->ai_family, paiw->ai_socktype, paiw->ai_protocol); if(servinfo[i].sock == INVALID_SOCKET) { continue; } if(setsockopt(servinfo[i].sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&use, sizeof(use)) == SOCKET_ERROR) { disconnect(servinfo[i].sock); continue; } if(bind(servinfo[i].sock, paiw->ai_addr, (int)paiw->ai_addrlen) == SOCKET_ERROR) { disconnect(servinfo[i].sock); continue; } if(listen(servinfo[i].sock, 1) == SOCKET_ERROR) { disconnect(servinfo[i].sock); continue; } servinfo[i].live = TRUE; i++; } FreeAddrInfoW(paiwResult); return i; }
static BOOL ResolveTarget(PCWSTR target) { ADDRINFOW hints; int Status; ZeroMemory(&hints, sizeof(hints)); hints.ai_family = Family; hints.ai_flags = AI_NUMERICHOST; Status = GetAddrInfoW(target, NULL, &hints, &Target); if (Status != 0) { hints.ai_flags = AI_CANONNAME; Status = GetAddrInfoW(target, NULL, &hints, &Target); if (Status != 0) { ConResPrintf(StdOut, IDS_UNKNOWN_HOST, target); return FALSE; } wcsncpy(CanonName, Target->ai_canonname, wcslen(Target->ai_canonname)); } else if (ResolveAddress) { Status = GetNameInfoW(Target->ai_addr, Target->ai_addrlen, CanonName, _countof(CanonName), NULL, 0, NI_NAMEREQD); if (Status != 0) { DPRINT("GetNameInfoW failed: %d\n", WSAGetLastError()); } } Family = Target->ai_family; return TRUE; }
bool SimpleSocket::InitializeSocket(std::wstring server, std::wstring port) { //0 for success, 1 for error //Initialize the variables...Maybe not neccessary TheSocket = INVALID_SOCKET; ptr = NULL; result = NULL; int iResult; iResult = WSAStartup(MAKEWORD(2,2), &wsaData); if (iResult != 0) { onSysMsg(L"WSAStartup failed: %d", iResult); return 1; iStatus=SOCKET_CLOSED; } struct addrinfoW hints; ZeroMemory( &hints, sizeof(hints) ); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; iResult = GetAddrInfoW(server.c_str(), port.c_str(), &hints, &result); if (iResult != 0) { onSysMsg(L"GetAddrInfoW failed: %d", iResult); WSACleanup(); iStatus=SOCKET_CLOSED; return 1; } // Attempt to connect to the first address returned by // the call to GetAddrInfoW ptr=result; // Create a SOCKET for connecting to server TheSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); if (TheSocket == INVALID_SOCKET) { onSysMsg(L"Error at socket(): %d", WSAGetLastError()); FreeAddrInfoW(result); WSACleanup(); iStatus=SOCKET_CLOSED; return 1; } DWORD RCVTIMEO=15000; iResult = setsockopt(TheSocket, SOL_SOCKET, SO_RCVTIMEO, (char *) &RCVTIMEO, sizeof(DWORD)); iStatus=SOCKET_INITIALIZED; return 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 ); }
/* getaddrinfo worker thread implementation */ static DWORD WINAPI getaddrinfo_thread_proc(void* parameter) { uv_getaddrinfo_t* req = (uv_getaddrinfo_t*) parameter; uv_loop_t* loop = req->loop; int ret; assert(req != NULL); /* call OS function on this thread */ ret = GetAddrInfoW(req->node, req->service, req->hints, &req->res); req->retcode = ret; /* post getaddrinfo completed */ POST_COMPLETION_FOR_REQ(loop, req); return 0; }
//****************************************************************************** // Routine: // GetSockAddrFromString // // Arguments: // strAddress - Address in the String format // pSocketAddress - Pointer to SOCKADDR_STORAGE structure where the // address is returned // // Description: // Takes a string format address and returns a pointer to // SOCKADDR_STORAGE structure containing the address. // Only resolves numeric addresses //****************************************************************************** BOOL GetSockAddrFromString(const WCHAR *strAddress, PSOCKADDR_STORAGE pSocketAddress) { BOOL result = FALSE; ADDRINFOW *pAddress = NULL; int wsaResult = 0; ADDRINFOW hints; ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_flags = AI_NUMERICHOST; // Resolve the address wsaResult = GetAddrInfoW(strAddress, NULL, &hints, &pAddress); if (0 != wsaResult) { printf("Failed to resolve \"%S\". GetAddrInfoW() failed with 0x%x\n", strAddress, wsaResult); goto Exit; } // Make sure the address resolved to only one entry if (NULL != pAddress->ai_next) { printf("%S Resolved to more than one address. Please use a numeric Address\n", strAddress); goto Exit; } // Copy the address to the storage CopyMemory(pSocketAddress, pAddress->ai_addr, pAddress->ai_addrlen); result = TRUE; Exit: // Cleanup if (NULL != pAddress) { FreeAddrInfoW(pAddress); } return result; }
/* getaddrinfo worker thread implementation */ static DWORD WINAPI getaddrinfo_thread_proc(void* parameter) { uv_getaddrinfo_t* handle = (uv_getaddrinfo_t*) parameter; uv_loop_t* loop = handle->loop; int ret; assert(handle != NULL); if (handle != NULL) { /* call OS function on this thread */ ret = GetAddrInfoW(handle->node, handle->service, handle->hints, &handle->res); handle->retcode = ret; /* post getaddrinfo completed */ POST_COMPLETION_FOR_REQ(loop, &handle->getadddrinfo_req); } return 0; }
/*! * \brief * This function pings an IP-Address with a specified Time-To-Live-value. * * \param targetIP * The textual representation of the IP-Address to ping (both IPv4 and IPv6 are accepted) * * \param ttl * The Time-To-Live-value to perform the ping with * * \param out * The Buffer into which the result of the ping-command will be written * * \param outSize * The maximum number of characters that can be written into "out" * * \returns * True if the execution succeded and false otherwise. The following will be written in "out": "TARGET "+TargetIP if the target was reached, "HOP "+HopIP if an intermediate Host was reached or "NO_REPLY" if an execution error occurred. If an internal error occured, a message describing that error will be written. * * \remarks * Writing the "ping"-function in Javascript and calling the iphlpapi.dll (and others) using c-types turned out to be impossible. The reason for that is the fact that calling GetLastError() is not possible using c-types. Therefore it is implemented in c-code and compiled into the crossbear.dll. * */ extern "C" __declspec( dllexport ) bool ping(WCHAR * targetIP, int ttl, WCHAR * out, int outSize){ // Validate the Time-To-Live-Parameter: less than 1 is invalid and more than 255 doesn't make sense and might cause _itow problems if(ttl<1 || ttl>255){ outPutWstring(std::wstring(L"TTL Parameter invalid"),out,outSize); return false; } // Verify if targetIP is a valid address if yes convert it into a addrinfo-struct struct addrinfoW *ai; if(! (0==GetAddrInfoW(targetIP,NULL,NULL,&ai))){ outPutWstring(std::wstring(L"could not parse IP Address : ")+getFormatedLastError(),out,outSize); return false; } // Check if the IP-version of the targetIP is v6 ... if(ai->ai_family == AF_INET6){ // ... and if it is perform a ping using ICMPv4 return ping6(ai, ttl, out, outSize); } // Check if the IP-version of the targetIP is v4 ... else if(ai->ai_family == AF_INET){ // ... and if it is perform a ping using ICMPv6 return ping4(ai, ttl, out, outSize); } // In case the passed address is neither IPv4 nor IPv6: Return an error message outPutWstring(std::wstring(L"Unknown type of IPAddress"),out,outSize); FreeAddrInfoW(ai); return false; }
__declspec(dllexport) BOOL SoaronModuleFunc(void) { SQLHDBC hdbc; HSTMT hstmt; unsigned int NumOfLinks, LinkID; WSADATA wd; SQLRETURN sqlret; HANDLE hHeap; FTNAddr LinkAddr; wchar_t Ip[256]; lpLinksCheckInfo LinksTable; WSAEVENT * EventsTable; WSANETWORKEVENTS evt; unsigned int i, j; int res; ADDRINFOW *result = NULL; ADDRINFOW hints; wchar_t LogStr[255]; memset(&hints, 0, sizeof(hints)); LinkAddr.point = 0; NumOfLinks = 0; SQLAllocHandle(SQL_HANDLE_DBC, cfg.henv, &hdbc); sqlret = SQLDriverConnectW(hdbc, NULL, cfg.ConnectionString, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT); if (sqlret != SQL_SUCCESS && sqlret != SQL_SUCCESS_WITH_INFO) { SetEvent(cfg.hExitEvent); return FALSE;//fatal error } SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); AddLogEntry(L"Checking binkp links alive"); //get links info SQLExecDirectW(hstmt, L"update Links set DialOut=0 where datediff(minute,LastSessionTime,GetDate())>40 and LinkType=1", SQL_NTS); sqlret = SQLExecDirectW(hstmt, L"select count(*) from Links where dialout=0 and passivelink=0 and LinkType=1 and isnull(ip,'')<>''", SQL_NTS); if ((sqlret == SQL_SUCCESS) || (sqlret = SQL_SUCCESS_WITH_INFO)) { sqlret = SQLFetch(hstmt); if ((sqlret == SQL_SUCCESS) || (sqlret = SQL_SUCCESS_WITH_INFO)) { SQLGetData(hstmt, 1, SQL_C_ULONG, &NumOfLinks, 0, NULL); } } SQLCloseCursor(hstmt); if (NumOfLinks == 0) goto exit; hHeap = HeapCreate(HEAP_NO_SERIALIZE, 8192, 0); LinksTable = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, NumOfLinks*sizeof(LinksCheckInfo)); EventsTable = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(WSAEVENT)*NumOfLinks); i = 0; hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; WSAStartup(MAKEWORD(2, 2), &wd); sqlret = SQLExecDirectW(hstmt, L"select LinkID,Zone,Net,Node, Ip from Links where dialout=0 and passivelink=0 and LinkType=1 and isnull(ip,'')<>''", SQL_NTS); if ((sqlret == SQL_SUCCESS) || (sqlret = SQL_SUCCESS_WITH_INFO)) { SQLBindCol(hstmt, 1, SQL_C_ULONG, &LinkID, 0, NULL); SQLBindCol(hstmt, 2, SQL_C_USHORT, &(LinkAddr.zone), 0, NULL); SQLBindCol(hstmt, 3, SQL_C_USHORT, &(LinkAddr.net), 0, NULL); SQLBindCol(hstmt, 4, SQL_C_USHORT, &(LinkAddr.node), 0, NULL); SQLBindCol(hstmt, 5, SQL_C_WCHAR, Ip, 512, NULL); sqlret = SQLFetch(hstmt); while ((sqlret == SQL_SUCCESS) || (sqlret == SQL_SUCCESS_WITH_INFO)) { // res = GetAddrInfoW(Ip, L"24554", &hints, &result); if (res == 0) { memcpy(&(LinksTable[i].sa), result->ai_addr, sizeof(struct sockaddr_in)); // printf("%u %u %S %u.%u.%u.%u\n", i,LinkID, Ip, LinksTable[i].sa.sin_addr.S_un.S_un_b.s_b1, LinksTable[i].sa.sin_addr.S_un.S_un_b.s_b2, LinksTable[i].sa.sin_addr.S_un.S_un_b.s_b3, LinksTable[i].sa.sin_addr.S_un.S_un_b.s_b4); LinksTable[i].LinkID = LinkID; LinksTable[i].LinkAddr.FullAddr = LinkAddr.FullAddr; LinksTable[i].s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); EventsTable[i] = WSACreateEvent(); WSAEventSelect(LinksTable[i].s, EventsTable[i], FD_CONNECT); FreeAddrInfoW(result); ++i; } else { wsprintfW(LogStr,L"%u:%u/%u: Ip address %s cannot be resolved", LinkAddr.zone, LinkAddr.net, LinkAddr.node,Ip); AddLogEntry(LogStr); } sqlret = SQLFetch(hstmt); } } SQLCloseCursor(hstmt); SQLFreeStmt(hstmt, SQL_UNBIND); NumOfLinks = i; for (i = 0; i < NumOfLinks; i++) { connect(LinksTable[i].s, (struct sockaddr *)&(LinksTable[i].sa), sizeof(struct sockaddr_in)); } j = 0; SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 0, 0, &LinkID, 0, NULL); SQLPrepareW(hstmt, L"Update Links set DialOut=1 where LinkID=?", SQL_NTS); while (j < NumOfLinks) { res = WSAWaitForMultipleEvents(NumOfLinks, EventsTable, FALSE, WSA_INFINITE, FALSE); WSAEnumNetworkEvents(LinksTable[res].s, EventsTable[res], &evt); shutdown(LinksTable[res].s, SD_BOTH); closesocket(LinksTable[res].s); if (evt.iErrorCode[FD_CONNECT_BIT] == 0) { wsprintfW(LogStr, L"%u:%u/%u: OK", LinksTable[res].LinkAddr.zone, LinksTable[res].LinkAddr.net, LinksTable[res].LinkAddr.node); LinkID = LinksTable[res].LinkID; SQLExecute(hstmt); } else { switch (evt.iErrorCode[FD_CONNECT_BIT]) { case WSAECONNREFUSED: wsprintfW(LogStr, L"%u:%u/%u: Connection refused", LinksTable[res].LinkAddr.zone, LinksTable[res].LinkAddr.net, LinksTable[res].LinkAddr.node); break; case WSAETIMEDOUT: wsprintfW(LogStr, L"%u:%u/%u: Connection timed out", LinksTable[res].LinkAddr.zone, LinksTable[res].LinkAddr.net, LinksTable[res].LinkAddr.node); break; default:wsprintfW(LogStr, L"%u:%u/%u: Unknown connection error", LinksTable[res].LinkAddr.zone, LinksTable[res].LinkAddr.net, LinksTable[res].LinkAddr.node); } } AddLogEntry(LogStr); ++j; } // for (j = 0; j < NumOfLinks; j++) { WSACloseEvent(EventsTable[j]); } SQLFreeStmt(hstmt, SQL_RESET_PARAMS); // WSACleanup(); HeapDestroy(hHeap); exit: SQLFreeHandle(SQL_HANDLE_STMT, hstmt); SQLDisconnect(hdbc); SQLFreeHandle(SQL_HANDLE_DBC, hdbc); AddLogEntry(L"Links alive check done"); SetEvent(cfg.hLinksUpdateEvent); return TRUE; }
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; }
Socket *CreateClientSocket(const wchar_t *host, uint16_t port, int timeoutMS) { wchar_t portstr[7] = {0}; StringFormat::wsnprintf(portstr, 6, L"%d", port); addrinfoW hints; RDCEraseEl(hints); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; addrinfoW *result = NULL; GetAddrInfoW(host, portstr, &hints, &result); for(addrinfoW *ptr = result; ptr != NULL; ptr = ptr->ai_next) { SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(s == INVALID_SOCKET) return NULL; u_long enable = 1; ioctlsocket(s, FIONBIO, &enable); int result = connect(s, ptr->ai_addr, (int)ptr->ai_addrlen); if(result == SOCKET_ERROR) { fd_set set; FD_ZERO(&set); FD_SET(s, &set); int err = WSAGetLastError(); if(err == WSAEWOULDBLOCK) { timeval timeout; timeout.tv_sec = (timeoutMS/1000); timeout.tv_usec = (timeoutMS%1000)*1000; result = select(0, NULL, &set, NULL, &timeout); if(result <= 0) { RDCDEBUG("connect timed out"); closesocket(s); continue; } else { RDCDEBUG("connect before timeout"); } } else { RDCDEBUG("problem other than blocking"); closesocket(s); continue; } } else { RDCDEBUG("connected immediately"); } BOOL nodelay = TRUE; setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (const char *)&nodelay, sizeof(nodelay)); return new Socket((ptrdiff_t)s); } RDCWARN("Failed to connect to %ls:%d", host, port); return NULL; }
Socket *CreateClientSocket(const char *host, uint16_t port, int timeoutMS) { wchar_t portwstr[7] = {0}; { char buf[7] = {0}; int n = StringFormat::snprintf(buf, 6, "%d", port); for(int i=0; i < n && i < 6; i++) portwstr[i] = (wchar_t)buf[i]; } addrinfoW hints; RDCEraseEl(hints); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; std::wstring whost = StringFormat::UTF82Wide(string(host)); addrinfoW *addrResult = NULL; GetAddrInfoW(whost.c_str(), portwstr, &hints, &addrResult); for(addrinfoW *ptr = addrResult; ptr != NULL; ptr = ptr->ai_next) { SOCKET s = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_NO_HANDLE_INHERIT); if(s == INVALID_SOCKET) return NULL; u_long enable = 1; ioctlsocket(s, FIONBIO, &enable); int result = connect(s, ptr->ai_addr, (int)ptr->ai_addrlen); if(result == SOCKET_ERROR) { fd_set set; FD_ZERO(&set); // macro FD_SET contains the do { } while(0) idiom, which warns #pragma warning(push) #pragma warning(disable : 4127) // conditional expression is constant FD_SET(s, &set); #pragma warning(pop) int err = WSAGetLastError(); if(err == WSAEWOULDBLOCK) { timeval timeout; timeout.tv_sec = (timeoutMS/1000); timeout.tv_usec = (timeoutMS%1000)*1000; result = select(0, NULL, &set, NULL, &timeout); if(result <= 0) { RDCDEBUG("connect timed out"); closesocket(s); continue; } else { RDCDEBUG("connect before timeout"); } } else { RDCDEBUG("problem other than blocking"); closesocket(s); continue; } } else { RDCDEBUG("connected immediately"); } BOOL nodelay = TRUE; setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (const char *)&nodelay, sizeof(nodelay)); return new Socket((ptrdiff_t)s); } RDCWARN("Failed to connect to %s:%d", host, port); return NULL; }
void ConnectSKKServer() { ADDRINFOW *paiwResult; ADDRINFOW *paiw; u_long mode; timeval tv; fd_set fdw, fde; ADDRINFOW aiwHints = {}; aiwHints.ai_family = AF_UNSPEC; aiwHints.ai_socktype = SOCK_STREAM; aiwHints.ai_protocol = IPPROTO_TCP; if(GetAddrInfoW(host, port, &aiwHints, &paiwResult) != 0) { return; } for(paiw = paiwResult; paiw != nullptr; paiw = paiw->ai_next) { sock = socket(paiw->ai_family, paiw->ai_socktype, paiw->ai_protocol); if(sock == INVALID_SOCKET) { continue; } if(setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (const char*)&timeout, sizeof(timeout)) == SOCKET_ERROR) { closesocket(sock); sock = INVALID_SOCKET; continue; } if(setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout)) == SOCKET_ERROR) { closesocket(sock); sock = INVALID_SOCKET; continue; } mode = 1; ioctlsocket(sock, FIONBIO, &mode); if(connect(sock, paiw->ai_addr, (int)paiw->ai_addrlen) == SOCKET_ERROR) { if(WSAGetLastError() != WSAEWOULDBLOCK) { closesocket(sock); sock = INVALID_SOCKET; continue; } } mode = 0; ioctlsocket(sock, FIONBIO, &mode); tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; FD_ZERO(&fdw); FD_ZERO(&fde); FD_SET(sock, &fdw); FD_SET(sock, &fde); select(0, nullptr, &fdw, &fde, &tv); if(FD_ISSET(sock, &fdw)) { break; } DisconnectSKKServer(); } FreeAddrInfoW(paiwResult); }
int main (int argc, char **argv) { int ret; int r = 1; WSADATA wsd; GUID prov; GUID sc; wchar_t *cmdl; int wargc; wchar_t **wargv; if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) { fprintf (stderr, "WSAStartup() failed: %lu\n", GetLastError()); return 5; } cmdl = GetCommandLineW (); if (cmdl == NULL) { WSACleanup(); return 2; } wargv = CommandLineToArgvW (cmdl, &wargc); if (wargv == NULL) { WSACleanup(); return 3; } r = 4; if (wargc == 5) { if (wcscmp (wargv[1], L"A") == 0) sc = SVCID_DNS_TYPE_A; else if (wcscmp (wargv[1], L"AAAA") == 0) sc = SVCID_DNS_TYPE_AAAA; else if (wcscmp (wargv[1], L"name") == 0) sc = SVCID_HOSTNAME; else if (wcscmp (wargv[1], L"addr") == 0) sc = SVCID_INET_HOSTADDRBYNAME; else wargc -= 1; if (wcscmp (wargv[4], L"mswdns") == 0) prov = W32_DNS; else if (wcscmp (wargv[4], L"gnunetdns") == 0) prov = GNUNET_NAMESPACE_PROVIDER_DNS; else wargc -= 1; } else if (wargc == 3) { } else { fprintf (stderr, "Usage: %S <record type> <service name> <NSP library path> <NSP id>\n" "record type - one of the following: A | AAAA | name | addr\n" "service name - a string to resolve; \" \" (a space) means 'blank'\n" "NSP library path - path to libw32nsp\n" "NSP id - one of the following: mswdns | gnunetdns\n", wargv[0]); } if (wargc == 5) { HMODULE nsp; nsp = LoadLibraryW (wargv[3]); if (nsp == NULL) { fprintf (stderr, "Failed to load library `%S'\n", wargv[3]); } else { LPNSPSTARTUP startup = (LPNSPSTARTUP) GetProcAddress (nsp, "NSPStartup"); if (startup == NULL) startup = (LPNSPSTARTUP) GetProcAddress (nsp, "NSPStartup@8"); if (startup != NULL) { NSP_ROUTINE api; api.cbSize = sizeof (api); ret = startup (&prov, &api); if (NO_ERROR != ret) fprintf (stderr, "startup failed: %lu\n", GetLastError ()); else { HANDLE lookup; WSAQUERYSETW search; char buf[4096]; WSAQUERYSETW *result = (WSAQUERYSETW *) buf; DWORD resultsize; DWORD err; memset (&search, 0, sizeof (search)); search.dwSize = sizeof (search); search.lpszServiceInstanceName = (wcscmp (wargv[2], L" ") == 0) ? NULL : wargv[2]; search.lpServiceClassId = ≻ search.lpNSProviderId = &prov; search.dwNameSpace = NS_ALL; ret = api.NSPLookupServiceBegin (&prov, &search, NULL, LUP_RETURN_ALL, &lookup); if (ret != NO_ERROR) { fprintf (stderr, "lookup start failed\n"); } else { resultsize = 4096; ret = api.NSPLookupServiceNext (lookup, LUP_RETURN_ALL, &resultsize, result); err = GetLastError (); if (ret != NO_ERROR) { fprintf (stderr, "lookup next failed: %lu\n", err); } else { int i; printf ("Got result:\n"); printf (" lpszServiceInstanceName: %S\n", result->lpszServiceInstanceName ? result->lpszServiceInstanceName : L"NULL"); if (result->lpServiceClassId) printf (" lpServiceClassId: { 0x%08lX,0x%04X,0x%04X, { 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X } }\n", result->lpServiceClassId->Data1, result->lpServiceClassId->Data2, result->lpServiceClassId->Data3, result->lpServiceClassId->Data4[0], result->lpServiceClassId->Data4[1], result->lpServiceClassId->Data4[2], result->lpServiceClassId->Data4[3], result->lpServiceClassId->Data4[4], result->lpServiceClassId->Data4[5], result->lpServiceClassId->Data4[6], result->lpServiceClassId->Data4[7]); else printf (" lpServiceClassId: NULL\n"); if (result->lpVersion) printf (" lpVersion: 0x%08lX, %d\n", result->lpVersion->dwVersion, result->lpVersion->ecHow); else printf (" lpVersion: NULL\n"); printf (" lpszComment: %S\n", result->lpszComment ? result->lpszComment : L"NULL"); printf (" dwNameSpace: %lu\n", result->dwNameSpace); if (result->lpNSProviderId) printf (" lpNSProviderId: { 0x%08lX,0x%04X,0x%04X, { 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X } }\n", result->lpNSProviderId->Data1, result->lpNSProviderId->Data2, result->lpNSProviderId->Data3, result->lpNSProviderId->Data4[0], result->lpNSProviderId->Data4[1], result->lpNSProviderId->Data4[2], result->lpNSProviderId->Data4[3], result->lpNSProviderId->Data4[4], result->lpNSProviderId->Data4[5], result->lpNSProviderId->Data4[6], result->lpNSProviderId->Data4[7]); else printf (" lpNSProviderId: NULL\n"); printf (" lpszContext: %S\n", result->lpszContext ? result->lpszContext : L"NULL"); printf (" dwNumberOfProtocols: %lu\n", result->dwNumberOfProtocols); printf (" lpszQueryString: %S\n", result->lpszQueryString ? result->lpszQueryString : L"NULL"); printf (" dwNumberOfCsAddrs: %lu\n", result->dwNumberOfCsAddrs); for (i = 0; i < result->dwNumberOfCsAddrs; i++) { switch (result->lpcsaBuffer[i].iSocketType) { case SOCK_STREAM: printf (" %d: iSocketType = SOCK_STREAM\n", i); break; case SOCK_DGRAM: printf (" %d: iSocketType = SOCK_DGRAM\n", i); break; default: printf (" %d: iSocketType = %d\n", i, result->lpcsaBuffer[i].iSocketType); } switch (result->lpcsaBuffer[i].iProtocol) { case IPPROTO_TCP: printf (" %d: iProtocol = IPPROTO_TCP\n", i); break; case IPPROTO_UDP: printf (" %d: iProtocol = IPPROTO_UDP\n", i); break; default: printf (" %d: iProtocol = %d\n", i, result->lpcsaBuffer[i].iProtocol); } switch (result->lpcsaBuffer[i].LocalAddr.lpSockaddr->sa_family) { case AF_INET: printf (" %d: loc family = AF_INET\n", i); break; case AF_INET6: printf (" %d: loc family = AF_INET6\n", i); break; default: printf (" %d: loc family = %hu\n", i, result->lpcsaBuffer[i].LocalAddr.lpSockaddr->sa_family); } switch (result->lpcsaBuffer[i].RemoteAddr.lpSockaddr->sa_family) { case AF_INET: printf (" %d: rem family = AF_INET\n", i); break; case AF_INET6: printf (" %d: rem family = AF_INET6\n", i); break; default: printf (" %d: rem family = %hu\n", i, result->lpcsaBuffer[i].RemoteAddr.lpSockaddr->sa_family); } char buf[1024]; DWORD buflen = 1024; if (NO_ERROR == WSAAddressToStringA (result->lpcsaBuffer[i].LocalAddr.lpSockaddr, result->lpcsaBuffer[i].LocalAddr.iSockaddrLength, NULL, buf, &buflen)) printf("\tLocal Address #%d: %s\n", i, buf); else printf("\tLocal Address #%d: Can't convert: %lu\n", i, GetLastError ()); buflen = 1024; if (NO_ERROR == WSAAddressToStringA (result->lpcsaBuffer[i].RemoteAddr.lpSockaddr, result->lpcsaBuffer[i].RemoteAddr.iSockaddrLength, NULL, buf, &buflen)) printf("\tRemote Address #%d: %s\n", i, buf); else printf("\tRemote Address #%d: Can't convert: %lu\n", i, GetLastError ()); } printf (" dwOutputFlags: 0x%08lX\n", result->dwOutputFlags); printf (" lpBlob: 0x%p\n", result->lpBlob); if (result->lpBlob) { struct hostent *he = malloc (result->lpBlob->cbSize); if (he != NULL) { GNUNET_memcpy (he, result->lpBlob->pBlobData, result->lpBlob->cbSize); UnpackHostEnt (he); print_hostent (he); free (he); } } } ret = api.NSPLookupServiceEnd (lookup); if (ret != NO_ERROR) printf ("NSPLookupServiceEnd() failed: %lu\n", GetLastError ()); } api.NSPCleanup (&prov); } } FreeLibrary (nsp); } } else if (wargc == 3) { int s; ADDRINFOW hints; ADDRINFOW *result; ADDRINFOW *pos; memset (&hints, 0, sizeof (struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; if (0 != (s = GetAddrInfoW (wargv[2], NULL, &hints, &result))) { fprintf (stderr, "Cound not resolve `%S' using GetAddrInfoW: %lu\n", wargv[2], GetLastError ()); } else { for (pos = result; pos != NULL; pos = pos->ai_next) { wchar_t tmpbuf[1024]; DWORD buflen = 1024; if (0 == WSAAddressToStringW (pos->ai_addr, pos->ai_addrlen, NULL, tmpbuf, &buflen)) fprintf (stderr, "Result:\n" " flags: 0x%X\n" " family: 0x%X\n" " socktype: 0x%X\n" " protocol: 0x%X\n" " addrlen: %u\n" " addr: %S\n" " canonname: %S\n", pos->ai_flags, pos->ai_family, pos->ai_socktype, pos->ai_protocol, pos->ai_addrlen, tmpbuf, pos->ai_canonname); else fprintf (stderr, "Result:\n" " flags: 0x%X\n" " family: 0x%X\n" " socktype: 0x%X\n" " protocol: 0x%X\n" " addrlen: %u\n" " addr: %S\n" " canonname: %S\n", pos->ai_flags, pos->ai_family, pos->ai_socktype, pos->ai_protocol, pos->ai_addrlen, L"<can't stringify>", pos->ai_canonname); } if (NULL != result) FreeAddrInfoW (result); } } WSACleanup(); return r; }
/*! * \brief * This function pings an IPv6-Address with a specified Time-To-Live-value. * * \param ai * The AddrInfo-representation of the TargetIP * * \param ttl * The Time-To-Live-value to perform the ping with * * \param out * The Buffer into which the result of the ping-command will be written * * \param outSize * The maximum number of characters that can be written into "out" * * \returns * True if the execution succeded and false otherwise. The following will be written in "out": "TARGET "+TargetIP if the target was reached, "HOP "+HopIP if an intermediate Host was reached or "NO_REPLY" if an execution error occurred. If an internal error occured, a message describing that error will be written. * * \remarks * ai will be Freed */ bool ping6(struct addrinfoW *ai, int ttl, WCHAR * out, int outSize){ // Create a handle to a hIcmpFile (required by Icmp6SendEcho2) HANDLE hIcmpFile = Icmp6CreateFile(); if (hIcmpFile == INVALID_HANDLE_VALUE) { outPutWstring(std::wstring(L"Icmp6Createfile returned error: ")+getFormatedLastError(),out,outSize); // Free all allocated resources FreeAddrInfoW(ai); return false; } // A ICMP-request using IPv6 requires a source address: Get the system's IPv6 addresses ADDRINFOW hints; memset(&hints,0,sizeof(ADDRINFOW)); hints.ai_family = AF_INET6; struct addrinfoW *lai; if(! (0==GetAddrInfoW(L"",NULL,&hints,&lai))){ outPutWstring(std::wstring(L"Invalid Socket (Localhost) : ")+getFormatedLastError(),out,outSize); // Free all allocated resources FreeAddrInfoW(ai); IcmpCloseHandle(hIcmpFile); return false; } // Out of all of the system's IPv6-addresses: get a global IPv6 IP-Address for localhost struct addrinfoW *sourceGlobal = lai; while(sourceGlobal != NULL){ sockaddr_in6 * a = (sockaddr_in6 *)sourceGlobal->ai_addr; if(IN6_IS_ADDR_GLOBAL(&a->sin6_addr)) break; sourceGlobal = sourceGlobal->ai_next; } // If there is none then there is no way to perform an ICMP-request on a IPv6-address -> abbort! if(sourceGlobal == NULL){ outPutWstring(std::wstring(L"No global IPv6 interface found on localhost: ")+getFormatedLastError(),out,outSize); // Free all allocated resources FreeAddrInfoW(ai); FreeAddrInfoW(lai); IcmpCloseHandle(hIcmpFile); return false; } // Build the payload of the ICMP-request (mustn't be empty) char SendData[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"; // Allocate space for a single reply DWORD ReplySize = sizeof (ICMPV6_ECHO_REPLY) + sizeof (SendData) + 8 + sizeof(IO_STATUS_BLOCK); LPVOID ReplyBuffer = (VOID *) malloc(ReplySize); // Create a IP_OPTION_INFORMATION and set its TTL-field so Icmp6SendEcho2 will perform a ping with the correct TTL IP_OPTION_INFORMATION ipopts; memset(&ipopts,0,sizeof(ipopts)); ipopts.Ttl = (unsigned char)ttl; //Try to perform the actual ping DWORD dwRetVal = Icmp6SendEcho2(hIcmpFile, NULL, NULL, NULL,(sockaddr_in6 *)sourceGlobal->ai_addr, (sockaddr_in6 *)ai->ai_addr, SendData, sizeof (SendData), &ipopts, ReplyBuffer, ReplySize, 1000); if (dwRetVal == 0) { // In case it failed: Did it fail because of a timeout or because of a serious problem? bool success = false; DWORD lastError = GetLastError(); if(IP_REQ_TIMED_OUT == lastError || IP_DEST_NET_UNREACHABLE == lastError ){ // If it failed because of a Timeout return "NO_REPLY" outPutWstring(std::wstring(L"NO_REPLY"),out,outSize); success = true; } else{ // If it failed because of a serious problem return a detailed description about the failure outPutWstring(std::wstring(L"Call to Icmp6SendEcho2 failed: ")+getFormatedLastError(),out,outSize); } // Free all allocated resources FreeAddrInfoW(ai); FreeAddrInfoW(lai); free(ReplyBuffer); IcmpCloseHandle(hIcmpFile); return success; } // Parse the reply on the ICMP-request PICMPV6_ECHO_REPLY pEchoReply = (PICMPV6_ECHO_REPLY) ReplyBuffer; /* * Extract the address of the replying host */ // First: copy the reply data into a sockaddr_in6-struckture PIPV6_ADDRESS_EX pIP6Addr = &pEchoReply->Address;; sockaddr_in6 sock6; sock6.sin6_family = AF_INET6; sock6.sin6_flowinfo = pIP6Addr->sin6_flowinfo; sock6.sin6_port = pIP6Addr->sin6_port; sock6.sin6_scope_id = pIP6Addr->sin6_scope_id; memcpy(&sock6.sin6_addr, pIP6Addr->sin6_addr,sizeof(IN6_ADDR)); // Second: convert it into human readable version WCHAR ip6AddressString[256]; DWORD bufferLenght = 256; if(0 != WSAAddressToStringW((LPSOCKADDR)&sock6,sizeof(sockaddr_in6),NULL,ip6AddressString,&bufferLenght)){ outPutWstring(std::wstring(L"Call to WSAAddressToStringW failed: ")+getFormatedLastError(),out,outSize); // Free all allocated resources FreeAddrInfoW(ai); FreeAddrInfoW(lai); free(ReplyBuffer); IcmpCloseHandle(hIcmpFile); return false; } // Third: convert it into a wstring std::wstring hopName = std::wstring(ip6AddressString); /* * Switch according to status of reply */ ULONG status = pEchoReply->Status; if(status == IP_SUCCESS){ // Ping reached the target outPutWstring(std::wstring(L"TARGET ")+ hopName,out,outSize); } else if(status == IP_TTL_EXPIRED_TRANSIT || status == IP_TTL_EXPIRED_REASSEM){ // Ping got a reply from a hop on the way to target outPutWstring(std::wstring(L"HOP ")+ hopName,out,outSize); } else{ // Something didn't work outPutWstring(std::wstring(L"NO_REPLY"),out,outSize); } // Free all allocated resources free(ReplyBuffer); FreeAddrInfoW(ai); FreeAddrInfoW(lai); IcmpCloseHandle(hIcmpFile); return true; }