// ---------------- MAIN PROGRAM ----------------- // Simple usage: client IP port, or client IP (use default port) int main(int argc, char *argv[]) { //******************************************************************** // WSSTARTUP //******************************************************************** #if defined _WIN32 if (WSAStartup(WSVERS, &wsadata) != 0) { WSACleanup(); printf("WSAStartup failed\n"); } #endif //******************************************************************* // Initialization //******************************************************************* //My own int SN_Base = 0; int SN_Next = 0; timer.count = 0; timer.enabled = 1; char sendpacket[12] [BUFFERSIZE]; memset(&localaddr, 0, sizeof(localaddr));//clean up int localPort=1234; localaddr.sin_family = AF_INET; localaddr.sin_addr.s_addr = INADDR_ANY;//server address should be local localaddr.sin_port = htons(localPort); memset(&remoteaddr, 0, sizeof(remoteaddr));//clean up //localaddr.sin_addr.s_addr = inet_addr(localIP); //char localIP[INET_ADDRSTRLEN]="127.0.0.1"; randominit(); //******************************************************************** #if defined __unix__ || defined __APPLE__ int s; #elif defined _WIN32 SOCKET s; #endif char send_buffer[BUFFERSIZE],receive_buffer[BUFFERSIZE]; remoteaddr.sin_family = AF_INET; //******************************************************************* // Dealing with user's arguments //******************************************************************* if (argc != 5) { printf("2011 code USAGE: client remote_IP-address port lossesbit(0 or 1) damagebit(0 or 1)\n"); exit(1); } remoteaddr.sin_addr.s_addr = inet_addr(argv[1]);//IP address remoteaddr.sin_port = htons((u_short)atoi(argv[2]));//always get the port number packets_lostbit=atoi(argv[3]); packets_damagedbit=atoi(argv[4]); if (packets_damagedbit<0 || packets_damagedbit>1 || packets_lostbit<0 || packets_lostbit>1){ printf("2011 code USAGE: client remote_IP-address port lossesbit(0 or 1) damagebit(0 or 1)\n"); exit(0); } //******************************************************************* //CREATE CLIENT'S SOCKET //******************************************************************* s = socket(AF_INET, SOCK_DGRAM, 0);//this is a UDP socket if (s < 0) { printf("socket failed\n"); exit(1); } //*************************************************************** //NONBLOCKING OPTION for Windows //*************************************************************** #if defined _WIN32 u_long iMode=1; ioctlsocket(s,FIONBIO,&iMode); #endif //******************************************************************* //SEND A TEXT FILE //******************************************************************* #if defined __unix__ || defined __APPLE__ FILE *fin=fopen("file1.txt","r"); #elif defined _WIN32 FILE *fin=fopen("file1_Windows.txt","r"); #endif if(fin==NULL) { printf("cannot open file\n"); exit(0); } while (1) { //Run the timer if enabled if(timer.enabled) { timer.count++; } //-------- memset(send_buffer, 0, sizeof(send_buffer));//clean up the send_buffer before reading the next line if(SN_Next < (SN_Base + N_GBN)) { //Error checking fgets(send_buffer,SEGMENTSIZE,fin); } if (!feof(fin)) { //Send normally if(SN_Next < (SN_Base + N_GBN)) { build_packet(send_buffer, SN_Next, sendpacket[SN_Next]); //Build it send_unreliably(s, sendpacket[SN_Next], remoteaddr); //Send it if(SN_Base == SN_Next) { timer.enabled = 1; //enable the timer } SN_Next++; } //if timedout, send all packets as not acknowledged if(timer.count > TIMER_LIMIT) { timer.enabled = 1; // enable the timer int i; for(i = SN_Base; i < SN_Next; i++) { send_unreliably(s, sendpacket[i], remoteaddr); #if defined __unix__ || defined __APPLE__ sleep(1); #elif defined _WIN32 Sleep(1); #endif } } #if defined __unix__ || defined __APPLE__ sleep(1); #elif defined _WIN32 Sleep(1000); #endif //******************************************************************** //RECEIVE //******************************************************************** memset(receive_buffer, 0, sizeof(receive_buffer)); recv_nonblocking(s,receive_buffer, remoteaddr);//you can replace this, but use MSG_DONTWAIT to get non-blocking recv printf("RECEIVE --> %s \n",receive_buffer); //when CRC check is passed if(CRC_check(receive_buffer)) { if(ACK_SN(receive_buffer) > -1) { SN_Base = ACK_SN(receive_buffer) + 1; } //Stop the timer if(SN_Base == SN_Next) { timer.enabled = 0; timer.count = 0; } //Start the timer; else { timer.enabled = 1; } } #if defined __unix__ || defined __APPLE__ sleep(1);//wait for a bit before trying the next packet #elif defined _WIN32 Sleep(1000); #endif } else { printf("end of the file \n"); memset(send_buffer, 0, sizeof(send_buffer)); sprintf(send_buffer,"CLOSE \r\n"); send_unreliably(s,send_buffer,remoteaddr);//we actually send this reliably, read UDP_supporting_functions_2016.c break; } } //******************************************************************* //CLOSESOCKET //******************************************************************* printf("closing everything on the client's side ... \n"); fclose(fin); #if defined __unix__ || defined __APPLE__ close(s); #elif defined _WIN32 closesocket(s); #endif exit(0); }
int main(int argc, char **argv) { SOCKET ListenSocket; SOCKET AcceptSocket; SOCKADDR_IN InternetAddr; WSADATA wsaData; INT Ret; FD_SET WriteSet; FD_SET ReadSet; DWORD i; DWORD Total; ULONG NonBlock; DWORD Flags; DWORD SendBytes; DWORD RecvBytes; if ((Ret = WSAStartup(0x0202, &wsaData)) != 0) { printf("WSAStartup() failed with error %d\n", Ret); WSACleanup(); return 1; } else printf("WSAStartup() is fine!\n"); // Prepare a socket to listen for connections if ((ListenSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET) { printf("WSASocket() failed with error %d\n", WSAGetLastError()); return 1; } else printf("WSASocket() is OK!\n"); InternetAddr.sin_family = AF_INET; InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY); InternetAddr.sin_port = htons(PORT); if (bind(ListenSocket, (PSOCKADDR)&InternetAddr, sizeof(InternetAddr)) == SOCKET_ERROR) { printf("bind() failed with error %d\n", WSAGetLastError()); return 1; } else printf("bind() is OK!\n"); if (listen(ListenSocket, 5)) { printf("listen() failed with error %d\n", WSAGetLastError()); return 1; } else printf("listen() is OK!\n"); // Change the socket mode on the listening socket from blocking to // non-block so the application will not block waiting for requests NonBlock = 1; if (ioctlsocket(ListenSocket, FIONBIO, &NonBlock) == SOCKET_ERROR) { printf("ioctlsocket() failed with error %d\n", WSAGetLastError()); return 1; } else printf("ioctlsocket() is OK!\n"); while (TRUE) { // Prepare the Read and Write socket sets for network I/O notification FD_ZERO(&ReadSet); FD_ZERO(&WriteSet); // Always look for connection attempts FD_SET(ListenSocket, &ReadSet); // Set Read and Write notification for each socket based on the // current state the buffer. If there is data remaining in the // buffer then set the Write set otherwise the Read set for (i = 0; i < TotalSockets; i++) if (SocketArray[i]->BytesRECV > SocketArray[i]->BytesSEND) FD_SET(SocketArray[i]->Socket, &WriteSet); else FD_SET(SocketArray[i]->Socket, &ReadSet); if ((Total = select(0, &ReadSet, &WriteSet, NULL, NULL)) == SOCKET_ERROR) { printf("select() returned with error %d\n", WSAGetLastError()); return 1; } else printf("select() is OK!\n"); // Check for arriving connections on the listening socket. if (FD_ISSET(ListenSocket, &ReadSet)) { Total--; if ((AcceptSocket = accept(ListenSocket, NULL, NULL)) != INVALID_SOCKET) { // Set the accepted socket to non-blocking mode so the server will // not get caught in a blocked condition on WSASends NonBlock = 1; if (ioctlsocket(AcceptSocket, FIONBIO, &NonBlock) == SOCKET_ERROR) { printf("ioctlsocket(FIONBIO) failed with error %d\n", WSAGetLastError()); return 1; } else printf("ioctlsocket(FIONBIO) is OK!\n"); if (CreateSocketInformation(AcceptSocket) == FALSE) { printf("CreateSocketInformation(AcceptSocket) failed!\n"); return 1; } else printf("CreateSocketInformation() is OK!\n"); } else { if (WSAGetLastError() != WSAEWOULDBLOCK) { printf("accept() failed with error %d\n", WSAGetLastError()); return 1; } else printf("accept() is fine!\n"); } } // Check each socket for Read and Write notification until the number // of sockets in Total is satisfied for (i = 0; Total > 0 && i < TotalSockets; i++) { LPSOCKET_INFORMATION SocketInfo = SocketArray[i]; // If the ReadSet is marked for this socket then this means data // is available to be read on the socket if (FD_ISSET(SocketInfo->Socket, &ReadSet)) { Total--; SocketInfo->DataBuf.buf = SocketInfo->Buffer; SocketInfo->DataBuf.len = DATA_BUFSIZE; Flags = 0; if (WSARecv(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &RecvBytes, &Flags, NULL, NULL) == SOCKET_ERROR) { if (WSAGetLastError() != WSAEWOULDBLOCK) { printf("WSARecv() failed with error %d\n", WSAGetLastError()); FreeSocketInformation(i); } else printf("WSARecv() is OK!\n"); continue; } else { SocketInfo->BytesRECV = RecvBytes; // If zero bytes are received, this indicates the peer closed the connection. if (RecvBytes == 0) { FreeSocketInformation(i); continue; } } } // If the WriteSet is marked on this socket then this means the internal // data buffers are available for more data if (FD_ISSET(SocketInfo->Socket, &WriteSet)) { Total--; SocketInfo->DataBuf.buf = SocketInfo->Buffer + SocketInfo->BytesSEND; SocketInfo->DataBuf.len = SocketInfo->BytesRECV - SocketInfo->BytesSEND; if (WSASend(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &SendBytes, 0, NULL, NULL) == SOCKET_ERROR) { if (WSAGetLastError() != WSAEWOULDBLOCK) { printf("WSASend() failed with error %d\n", WSAGetLastError()); FreeSocketInformation(i); } else printf("WSASend() is OK!\n"); continue; } else { SocketInfo->BytesSEND += SendBytes; if (SocketInfo->BytesSEND == SocketInfo->BytesRECV) { SocketInfo->BytesSEND = 0; SocketInfo->BytesRECV = 0; } } } } } }
static int httpTransact(char* szUrl, char* szResult, int resSize, char* szActionName, ReqType reqtype) { // Parse URL char szHost[256], szPath[256], szRes[16]; int sz = 0, res = 0; unsigned short sPort; bool needClose = false; const char* szPostHdr = soap_post_hdr; char* szData = (char*)mir_alloc(4096); char* szReq = NULL; parseURL(szUrl, szHost, &sPort, szPath); if (sPort != sConnPort || _stricmp(szHost, szConnHost)) closeRouterConnection(); else validateSocket(); while(true) { retryCount = 0; switch(reqtype) { case DeviceGetReq: sz = mir_snprintf (szData, 4096, xml_get_hdr, szPath, szHost, sPort); break; case ControlAction: { char szData1[1024]; szReq = mir_strdup(szResult); sz = mir_snprintf (szData1, SIZEOF(szData1), soap_action, szActionName, szDev, szReq, szActionName); sz = mir_snprintf (szData, 4096, szPostHdr, szPath, szHost, sPort, sz, szDev, szActionName, szData1); } break; case ControlQuery: { char szData1[1024]; sz = mir_snprintf (szData1, SIZEOF(szData1), soap_query, szActionName); sz = mir_snprintf (szData, 4096, szPostHdr, szPath, szHost, sPort, sz, "urn:schemas-upnp-org:control-1-0", "QueryStateVariable", szData1); } break; } szResult[0] = 0; { static const TIMEVAL tv = { 6, 0 }; static unsigned ttl = 4; static u_long mode = 1; fd_set rfd, wfd, efd; SOCKADDR_IN enetaddr; retrycon: if (sock == INVALID_SOCKET) { sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); enetaddr.sin_family = AF_INET; enetaddr.sin_port = htons(sPort); enetaddr.sin_addr.s_addr = inet_addr(szHost); // Resolve host name if needed if (enetaddr.sin_addr.s_addr == INADDR_NONE) { PHOSTENT he = gethostbyname(szHost); if (he) enetaddr.sin_addr.s_addr = *(unsigned*)he->h_addr_list[0]; } NetlibLogf(NULL, "UPnP HTTP connection Host: %s Port: %u", szHost, sPort); FD_ZERO(&rfd); FD_ZERO(&wfd); FD_ZERO(&efd); FD_SET(sock, &rfd); FD_SET(sock, &wfd); FD_SET(sock, &efd); // Limit the scope of the connection (does not work for setsockopt(sock, IPPROTO_IP, IP_TTL, (char *)&ttl, sizeof(unsigned)); // Put socket into non-blocking mode for timeout on connect ioctlsocket(sock, FIONBIO, &mode); // Connect to the remote host if (connect(sock, (SOCKADDR*)&enetaddr, sizeof(enetaddr)) == SOCKET_ERROR) { int err = WSAGetLastError(); // Socket connection failed if (err != WSAEWOULDBLOCK) { closeRouterConnection(); NetlibLogf(NULL, "UPnP connect failed %d", err); break; } // Wait for socket to connect else if (select(1, &rfd, &wfd, &efd, &tv) != 1) { closeRouterConnection(); NetlibLogf(NULL, "UPnP connect timeout"); break; } else if (!FD_ISSET(sock, &wfd)) { closeRouterConnection(); NetlibLogf(NULL, "UPnP connect failed"); break; } } strcpy(szConnHost, szHost); sConnPort = sPort; } if (send(sock, szData, sz, 0) != SOCKET_ERROR) { char *hdrend = NULL; int acksz = 0, pktsz = 0; if (szActionName == NULL) { int len = sizeof(locIP); getsockname(sock, (SOCKADDR*)&locIP, &len); if (locIP.sin_addr.S_un.S_addr == 0x0100007f) { struct hostent *he; gethostname(szPath, sizeof(szPath)); he = gethostbyname(szPath); if (he != NULL) locIP.sin_addr.S_un.S_addr = *(PDWORD)he->h_addr_list[0]; } } LongLog(szData); sz = 0; while(true) { int bytesRecv; FD_ZERO(&rfd); FD_SET(sock, &rfd); // Wait for the next packet if (select(1, &rfd, NULL, NULL, &tv) != 1) { closeRouterConnection(); NetlibLogf(NULL, "UPnP recieve timeout"); break; } // bytesRecv = recv(sock, &szResult[sz], resSize-sz, 0); // Connection closed or aborted, all data received if (bytesRecv == 0 || bytesRecv == SOCKET_ERROR) { closeRouterConnection(); if ((bytesRecv == SOCKET_ERROR || sz == 0) && retryCount < 2) { ++retryCount; goto retrycon; } break; } sz += bytesRecv; // Insert null terminator to use string functions if (sz >= (resSize-1)) { szResult[resSize-1] = 0; break; } else szResult[sz] = 0; // HTTP header found? if (hdrend == NULL) { // Find HTTP header end hdrend = strstr(szResult, "\r\n\r\n"); if (hdrend == NULL) { hdrend = strstr(szResult, "\n\n"); if (hdrend) hdrend += 2; } else hdrend += 4; if (hdrend != NULL) { // Get packet size if provided if (txtParseParam(szResult, NULL, "Content-Length:", "\n", szRes, sizeof(szRes)) || txtParseParam(szResult, NULL, "CONTENT-LENGTH:", "\n", szRes, sizeof(szRes))) { // Add size of HTTP header to the packet size to compute full transmission size pktsz = atol(ltrimp(szRes)) + (hdrend - szResult); } // Get encoding type if provided else if (txtParseParam(szResult, NULL, "Transfer-Encoding:", "\n", szRes, sizeof(szRes))) { if (_stricmp(lrtrimp(szRes), "Chunked") == 0) acksz = hdrend - szResult; } if (txtParseParam(szResult, NULL, "Connection:", "\n", szRes, sizeof(szRes))) { needClose = (_stricmp(lrtrimp(szRes), "close") == 0); } } } // Content-Length bytes reached, all data received if (sz >= pktsz && pktsz != 0) { szResult[pktsz] = 0; break; } // Chunked encoding processing if (sz > acksz && acksz != 0) { retry: // Parse out chunk size char* data = szResult + acksz; char* peol1 = data == hdrend ? data - 1 : strchr(data, '\n'); if (peol1 != NULL) { char *peol2 = strchr(++peol1, '\n'); if (peol2 != NULL) { // Get chunk size int chunkBytes = strtol(peol1, NULL, 16); acksz += chunkBytes; peol2++; memmove(data, peol2, strlen(peol2) + 1); sz -= peol2 - data; // Last chunk, all data received if (chunkBytes == 0) break; if (sz > acksz) goto retry; } } } } LongLog(szResult); } else { if (retryCount < 2) { closeRouterConnection(); ++retryCount; goto retrycon; } else NetlibLogf(NULL, "UPnP send failed %d", WSAGetLastError()); } } txtParseParam(szResult, "HTTP", " ", " ", szRes, sizeof(szRes)); res = atol(szRes); if (szActionName != NULL && res == 405 && szPostHdr == soap_post_hdr) szPostHdr = soap_post_hdr_m; else break; } if (needClose) closeRouterConnection(); mir_free(szData); mir_free(szReq); return res; }
/** * @brief * A thread safe way to connect to hostaddr at port * * @param[in] host - destination host machine * @param[in] port - port number * * @return int * @retval 0 : success * @retval -1 : error and errno will be set. */ int create_socket_and_connect(char *host, unsigned int port) { struct sockaddr_in remote; int sock; int ret; int non_block = 1; fd_set writeset; struct timeval tv; struct in_addr haddr; unsigned long hostaddr; struct hostent *hp; hp = gethostbyname(host); if (hp == NULL) { errno = WSAGetLastError(); return (-1); } memcpy((void *)&haddr, (void *)hp->h_addr_list[0], hp->h_length); hostaddr = ntohl(haddr.s_addr); /* get socket */ sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { errno = WSAGetLastError(); return (-1); } /* If local privilege port requested, bind to one */ /* Must be root privileged to do this */ /* connect to specified server host and port */ remote.sin_addr.s_addr = htonl(hostaddr); remote.sin_port = htons((unsigned short)port); remote.sin_family = AF_INET; /* force socket to be non-blocking so we can timeout wait on it */ if (ioctlsocket(sock, FIONBIO, &non_block) == SOCKET_ERROR) { errno = WSAGetLastError(); return (-1); } FD_ZERO(&writeset); FD_SET((unsigned int)sock, &writeset); tv.tv_sec = 20; /* connect timeout */ tv.tv_usec = 0; if (connect(sock, (struct sockaddr *)&remote, sizeof(remote)) < 0) { errno = WSAGetLastError(); switch (errno) { case WSAEINTR: case WSAEADDRINUSE: case WSAETIMEDOUT: case WSAECONNREFUSED: closesocket(sock); return (-1); case WSAEWOULDBLOCK: ret = select(1, NULL, &writeset, NULL, &tv); if (ret <= 0) { return (-1); } /* reset to blocking */ non_block = 0; if (ioctlsocket(sock, FIONBIO, &non_block) == SOCKET_ERROR) { errno = WSAGetLastError(); return (-1); } return (sock); default: closesocket(sock); return (-1); } } else { return (sock); } }
/* ==================== NET_IP6Socket ==================== */ int NET_IP6Socket(char *net_interface, int port, struct sockaddr_in6 *bindto, int *err) { SOCKET newsocket; struct sockaddr_in6 address; u_long _true = 1; *err = 0; if (net_interface) { // Print the name in brackets if there is a colon: if (Q_CountChar(net_interface, ':')) { Com_Printf("Opening IP6 socket: [%s]:%i\n", net_interface, port); } else { Com_Printf("Opening IP6 socket: %s:%i\n", net_interface, port); } } else { Com_Printf("Opening IP6 socket: [::]:%i\n", port); } if ((newsocket = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) { *err = socketError; Com_Printf("WARNING: NET_IP6Socket: socket: %s\n", NET_ErrorString()); return newsocket; } // make it non-blocking if (ioctlsocket(newsocket, FIONBIO, &_true) == SOCKET_ERROR) { Com_Printf("WARNING: NET_IP6Socket: ioctl FIONBIO: %s\n", NET_ErrorString()); *err = socketError; closesocket(newsocket); return INVALID_SOCKET; } #ifdef IPV6_V6ONLY { int i = 1; // ipv4 addresses should not be allowed to connect via this socket. if (setsockopt(newsocket, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &i, sizeof(i)) == SOCKET_ERROR) { // win32 systems don't seem to support this anyways. Com_DPrintf("WARNING: NET_IP6Socket: setsockopt IPV6_V6ONLY: %s\n", NET_ErrorString()); } } #endif if (!net_interface || !net_interface[0]) { address.sin6_family = AF_INET6; address.sin6_addr = in6addr_any; } else { if (!Sys_StringToSockaddr(net_interface, (struct sockaddr *)&address, sizeof(address), AF_INET6)) { closesocket(newsocket); return INVALID_SOCKET; } } if (port == PORT_ANY) { address.sin6_port = 0; } else { address.sin6_port = htons((short)port); } if (bind(newsocket, (void *)&address, sizeof(address)) == SOCKET_ERROR) { Com_Printf("WARNING: NET_IP6Socket: bind: %s\n", NET_ErrorString()); *err = socketError; closesocket(newsocket); return INVALID_SOCKET; } if (bindto) { *bindto = address; } return newsocket; }
//nTimeOut 单位S int Connect( SOCKET sk, char* remote, int port, int nTimeOut ) { //设置非阻塞方式连接 unsigned long ul = 1; //“无符号长整形“非零值, 启用非锁定模式 //ioctlsocket 控制套接口的模式。 FIONBIO:允许或禁止套接口的非阻塞模式。 if ( ioctlsocket(sk, FIONBIO, (unsigned long*)&ul) == SOCKET_ERROR ) return SOCKET_ERROR; //SOCKADDR_IN dvr; //dvr.sin_family = AF_INET; //dvr.sin_port = htons((unsigned short)port); //dvr.sin_addr.s_addr = inet_addr(addr); SOCKADDR_IN saServer; memset( &saServer, 0x00, sizeof(saServer) ); saServer.sin_family = AF_INET; LONG lIPAddress = 0; if( isalpha(remote[0]) ) { hostent *hostEnt = gethostbyname( remote ); if( hostEnt != NULL ) { lIPAddress = ((in_addr*)hostEnt->h_addr)->s_addr; saServer.sin_addr.s_addr = lIPAddress; } } else { saServer.sin_addr.s_addr = inet_addr( remote ); } saServer.sin_port = htons((unsigned short)port); if ( connect( sk, (SOCKADDR*)&saServer, sizeof( saServer ) ) == SOCKET_ERROR ) { DWORD dwError = WSAGetLastError(); if ( dwError != WSAEWOULDBLOCK ) return SOCKET_ERROR; } //检索套接字是否接受到数据.若无,则ret<=0,即自动在fdconn中删除了该套接字 struct timeval tv ; fd_set fdconn; FD_ZERO(&fdconn); //初始化为空集合 FD_SET(sk, &fdconn); //将套接字句柄传入fdconn tv.tv_sec = nTimeOut; //等待时间, 秒 tv.tv_usec = 0; //毫秒 int ret = select(0, 0, &fdconn, 0, &tv); if ( ret <= 0 ) { //closesocket(sk); return SOCKET_ERROR; } //设回阻塞模式 ul = 0 ; //0为阻塞模式 ret = ioctlsocket( sk, FIONBIO, (unsigned long*) & ul ); if ( ret == SOCKET_ERROR ) { closesocket(sk); return SOCKET_ERROR; } return 0; }
udp::udp(char* const host, char* const port) { m_instance = ++m_last_instance; #ifdef _DEBUG printf("\n\n\n"); printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); printf("udp::udp creating connectionless socket HOST=%s : PORT=%s (instance %d)\n\n",host,port,m_instance); #endif // reset(); load_winsock(); // struct hostent *hp; struct servent *sp; int salen = sizeof(m_socka); size_t bytessent = 0L; // m_ping.QuadPart = 0; m_start_of_ping.QuadPart = 0; //preparations follow that set up socket structures if ((hp = gethostbyname(host)) == NULL) { log.AddLog(_T(__FILE__), __LINE__, L"udp::udp", L"No such host? (%S).", host); return; } // copy needed info out of hp before issuing any other winsock functions memmove((char *) &m_socka.sin_addr, (char *) hp->h_addr,hp->h_length); m_socka.sin_family = hp->h_addrtype; // m_socka.sin_port = ntohs(atoi(port)); if (m_socka.sin_port == 0) { if ((sp = getservbyname(port, "udp")) == NULL) { log.AddLog(_T(__FILE__), __LINE__, L"udp::udp", L"No such well-known service (%S). Valid examples: whois, ftp, etc.", port); return; } else m_socka.sin_port = sp->s_port; } // if ((m_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) { // log.AddLog(_T(__FILE__), __LINE__, L"udp::udp", L"Socket error while requesting a free UDP/SOCK_DGRAM socket handle: (%d) (%s)", WSAGetLastError(), CErrorStringWSA::ErrorString(WSAGetLastError())); return; } // memset(&m_locala, 0, sizeof(struct sockaddr_in)); m_locala.sin_family = AF_INET; m_locala.sin_addr.s_addr = htonl(INADDR_ANY); m_locala.sin_port = htons(0); int const nbind = bind(m_sock, (struct sockaddr*) &m_locala, sizeof(m_locala)); if (nbind == SOCKET_ERROR) { log.AddLog(_T(__FILE__), __LINE__, L"udp::udp", L"Bind failure: (%d) (%s)", WSAGetLastError(), CErrorStringWSA::ErrorString(WSAGetLastError())); return; } //connect to the server. or try to... if (connect(m_sock, (const struct sockaddr*) &m_socka, sizeof(m_socka)) != 0) { log.AddLog(_T(__FILE__), __LINE__, L"udp::udp", L"Connect error: socket=%d host=%S port=%S (%d) (%s)", m_sock, host, port, WSAGetLastError(), CErrorStringWSA::ErrorString(WSAGetLastError())); return; } //setup non-blocking async mode unsigned long argp1 = 1; if (ioctlsocket(m_sock, FIONBIO, &argp1) == SOCKET_ERROR) { log.AddLog(_T(__FILE__), __LINE__, L"udp::udp", L"Async/Non-blocking mode could not be enabled: (%d) (%s)", WSAGetLastError(), CErrorStringWSA::ErrorString(WSAGetLastError())); return; } // struct sockaddr_in sa; // int gsn; salen = sizeof(sa); if ((gsn = getsockname(m_sock, (struct sockaddr*) &sa, &salen)) != 0) { log.AddLog(_T(__FILE__), __LINE__, L"udp::udp", L"getsockname (local address) error: socket=%d.", m_sock); strcpy(m_localname, "0.0.0.0"); m_localport = 0; } else { sprintf(m_localname, "%d.%d.%d.%d", sa.sin_addr.S_un.S_un_b.s_b1, sa.sin_addr.S_un.S_un_b.s_b2, sa.sin_addr.S_un.S_un_b.s_b3, sa.sin_addr.S_un.S_un_b.s_b4); m_localport = ntohs(sa.sin_port); } // int gpn; salen = sizeof(sa); if ((gpn = getpeername(m_sock, (struct sockaddr*) &sa, &salen)) != 0) { log.AddLog(_T(__FILE__), __LINE__, L"udp::udp", L"getpeername (peer address) error: socket=%d.", m_sock); strcpy(m_remotename, "0.0.0.0"); m_remoteport = 0; } else { sprintf(m_remotename, "%d.%d.%d.%d", sa.sin_addr.S_un.S_un_b.s_b1, sa.sin_addr.S_un.S_un_b.s_b2, sa.sin_addr.S_un.S_un_b.s_b3, sa.sin_addr.S_un.S_un_b.s_b4); m_remoteport = ntohs(sa.sin_port); } #ifdef _DEBUG printf("udp::udp connected. sock=%d\n\n",m_sock); #endif // m_connected = true; // initialize frequency constant if (!QueryPerformanceFrequency(&m_frequency)) { log.AddLog(_T(__FILE__), __LINE__, L"udp::udp", L"QueryPerformanceFrequency failed. Timing functions will be inaccurate."); } }
int dsresult(int sockd, const struct optstruct *opts) { ULONG iMode = 1; FD_SET Reader; int inq = 1, received = 0, idx = 0, len; int infected = 0; struct timeval timeout; char buffer[8192], line[1024]; char filename[1024]; char *found, *pt; if ((ioctlsocket(sockd, FIONBIO, &iMode) == SOCKET_ERROR)) { logg("!Cannot set socked in non/block mode\n"); return -1; } FD_ZERO(&Reader); FD_SET(sockd, &Reader); timeout.tv_sec = 1; timeout.tv_usec = 0; while ((inq = select(0, &Reader, NULL, NULL, &timeout) != SOCKET_ERROR)) { if ((inq > 0) && FD_ISSET(sockd, &Reader)) { assert((received >= 0) && (received < sizeof(buffer) - 1)); if (!((received >= 0) && (received < sizeof(buffer) - 1))) { logg("!Internal error, please report: received = %d\n", received); return -1; } received = recv(sockd, buffer + received, (sizeof(buffer) - received - 1), 0); if (received == SOCKET_ERROR) { logg("!Error in while receiving data from clamd, %s\n", strerror(errno)); return -1; } if (!received) break; /* Done */ buffer[received] = 0; while ((received > 0) && (found = strchr(buffer, '\n'))) { len = (int) (found - buffer); received -= len; len++; /* \0 */ if (len >= sizeof(line)) { logg("!Oversized line received from clamd\n"); return -1; } memcpy(line, buffer, len); line[len] = 0; found++; received--; /* move the remaining buffer data back */ if (received) memmove(buffer, found, received); buffer[received] = 0; if(strstr(line, "FOUND\n")) { if (!(pt = strrchr(line, ':'))) { logg("!Invalid clamd reply\n"); return -1; } logg("%s", line); infected++; strncpy(filename, line, pt - line); filename[pt - line] = 0; if (optget(opts, "remove")->enabled) cw_unlink(filename); else cw_moveinfected(filename, optget(opts, "move")->enabled, optget(opts, "move")->strarg, optget(opts, "copy")->strarg, ¬moved, ¬removed); } } } FD_ZERO(&Reader); FD_SET(sockd, &Reader); timeout.tv_sec = 1; timeout.tv_usec = 0; } return infected; }
/*=================================================================================================*/ E_SERVER_FSM_RESULT ssl_server_entry(SSL_SERVER_PARS parameters) { /* server parameters */ uint8_t echo = parameters.echo; char * pc_filename = parameters.pc_filename; char * pc_ciphersuites = parameters.pc_ciphersuites; uint16_t u_port = parameters.u_port; e_sslVer_t versmin = parameters.versmin; e_sslVer_t versmax = parameters.versmax; char * key = parameters.key; e_sslKeyType_t keyType = parameters.keyType; char * keyParameters = parameters.keyParameters; char ** certs = parameters.ppc_certs; char ** CAcerts = parameters.ppc_CAcerts; e_sslAuthLevel_t authlevel = parameters.authlevel; char c_filebuf[SSL_WRITE_BLOCK_LEN]; size_t n; char c_mode = 1; en_gciResult_t err; /* Check the state of the server */ switch (i_state) { case SSL_SERVER_INIT: /*============================================================================*/ /* * General SSL Initialisation */ /*============================================================================*/ /* Initialises the SSL module */ SSL_init(); /* Initialises the crypto */ //TODO sw - where to become the user name + password ?? err = gciInit(NULL, 0, NULL, 0); //OLD-CW: cw_crypto_init(); // { // /* // * Use some "random" bytes to init the PRNG // */ // uint8_t c_rand[] = { 0x42, 0x72, 0x75, 0x63, 0x65, 0x20, 0x53, 0x63, 0x68, //TODO sw - this step in gci_init // 0x6E, 0x65, 0x69, 0x65, 0x72, 0x21, 0x0D, 0x0A, 0x00 }; // cw_prng_init(c_rand, sizeof(c_rand)); // } /* * Initialisation of keymanager for DHE and DHE private key generation */ km_dhe_init(); /*============================================================================*/ /* * Initialization of the SSL settings for the demonstration SSL context */ /*============================================================================*/ /* Initialises the SSL context */ sslSoc_initSett(&s_sslSett, keyType); /* * Init the time-function pointer implicit to NULL, this will disable * checking of the validity of the used certificates * (To enable 'getCurrentTime' function should be used) */ sslSoc_setTimeFunc(&s_sslSett, NULL); /* Setting up the SSL version */ sslSoc_setVer(&s_sslSett, versmin, versmax); /* Setting up the SSL timeout value */ sslSoc_setSessTimeout(&s_sslSett, 600); /* Setting up the SSL authentification behavior */ sslSoc_setAuthLvl(&s_sslSett, authlevel); /* Setting up read and write fonctions */ sslSoc_setReadWrite(&s_sslSett, sslTarget_read, sslTarget_write); /* Initialize server CA certificates */ if (CAcerts != NULL) { init_server_CA_certs(CAcerts); } /* ===== Initialize Server Certificates and private key ===== */ s_cdbCert_t cdb_tmp; s_sslCertList_t * list_head = sslSoc_getCertChainList(&s_sslSett); if (certs != NULL) { int i = 0; while (certs[i] != NULL) { /* printf("certs[%i] = '%s'\n", i, certs[i]); */ cdb_initCert_linear(&server_cdb_certs[i], certs[i]); list_head = sslCert_addToList(list_head, &server_cert_list[i], NULL, &server_cdb_certs[i]); i++; } } else { /* use static pre-defined certificates if * no external certificate has been provided */ /* int i; for (i = 0; i < SSL_SERVERCERTS_NUM; ++i) { cdb_initCert_linear(&server_cdb_certs[i], server_certificates_[i]); list_head = SSL_cert_list_add(list_head, &server_cert_list[i], NULL, &server_cdb_certs[i]); } */ } sslSoc_setCertChainList (&s_sslSett, list_head); if (key != NULL) { cdb_initCert_linear(&cdb_tmp, key); } else { /*cdb_initCert_linear(&cdb_tmp, ServerPrivateKey);*/ } switch(keyType) { case E_SSL_KEY_EC: if (sslSoc_setECCPrivKey(&s_sslSett, &cdb_tmp) != E_SSL_OK) { printf(DBG_STRING "Import of ECC private key failed", __FILE__, __LINE__); return (E_SERVER_FSM_ERROR); } /* if */ break; case E_SSL_KEY_RSA: if (sslSoc_setRsaPrivKey(&s_sslSett, &cdb_tmp) != E_SSL_OK) { printf(DBG_STRING "Import of RSA private key failed", __FILE__, __LINE__); return (E_SERVER_FSM_ERROR); } /* if */ break; default: return (E_SERVER_FSM_ERROR); break; } /* switch */ case SSL_SERVER_REINIT: /*============================================================================*/ /* * Initialize socket specific features */ /*============================================================================*/ /* Creates a socket */ #ifdef _WIN32 if((srv_socdesc = socket(AF_INET , SOCK_STREAM , 0 )) == INVALID_SOCKET) { printf("Could not create socket : %s\n" , WSAGetLastError()); WSACleanup(); return (E_SERVER_FSM_ERROR); } #elif __linux if((srv_socdesc = socket(AF_INET , SOCK_STREAM , 0 )) < 0) { printf("Could not create socket : %s\n" , strerror(errno)); return (E_SERVER_FSM_ERROR); } #endif setsockopt(srv_socdesc, SOL_SOCKET, SO_REUSEADDR, &c_mode, sizeof(int)); printf("\n\rSocket created.\n"); /* Binding */ server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = htons(u_port); #ifdef _WIN32 if( bind(srv_socdesc ,(struct sockaddr *)&server , sizeof(server)) == INVALID_SOCKET) { printf("Bind failed with error code : %s\n" , WSAGetLastError()); WSACleanup(); return (E_SERVER_FSM_ERROR); } #elif __linux if( bind(srv_socdesc ,(struct sockaddr *)&server , sizeof(server)) < 0) { printf("Bind failed with error code : %s\n" , strerror(errno)); return (E_SERVER_FSM_ERROR); } #endif puts("Bind done"); /* Listening */ listen(srv_socdesc , 3); puts("Waiting for incoming connections..."); i_state = SSL_SERVER_LISTEN; break; /* SSL_SERVER_INIT */ case SSL_SERVER_LISTEN: i_addr_len = sizeof(struct sockaddr_in); cli_socdesc = accept(srv_socdesc , (struct sockaddr *)&client, &i_addr_len); if (cli_socdesc == INVALID_SOCKET) { break; } /* Nonblocking mode */ #ifdef _WIN32 ioctlsocket(cli_socdesc, FIONBIO, (u_long *)&c_mode); #elif __linux fcntl(cli_socdesc, F_SETFL, O_NONBLOCK); #endif printf("\n\rConnection accepted\n"); /* Checks if a SSL context is available */ if ((ps_sslCtx = sslSoc_new ( &s_sslSett )) == NULL) { /* Not available */ i_state = SSL_SERVER_CLOSE_ERR; } else { /* Available */ sslSoc_setCtxFd(ps_sslCtx, cli_socdesc); /* set supported ciphersuites if list is provided */ if (strlen(pc_ciphersuites) > 0) { sslSoc_setCtxCipList(ps_sslCtx, pc_ciphersuites); } int i=0; switch(keyType) { case E_SSL_KEY_EC: //loop all cipher suites provided //Remove all non-ECDSA cipher suites, as certificate cannot handle non-ECDSA for(i=0; i<SSL_CIPSPEC_COUNT; i++) { if( //remove every ECDHE curve ps_sslCtx->s_sslGut.ae_cipSpecs[i] != TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA && ps_sslCtx->s_sslGut.ae_cipSpecs[i] != TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA && ps_sslCtx->s_sslGut.ae_cipSpecs[i] != TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA ) { ps_sslCtx->s_sslGut.ae_cipSpecs[i] = TLS_NULL_WITH_NULL_NULL; } } break; case E_SSL_KEY_RSA: case E_SSL_KEY_UNDEFINED: //vpy: should be handled properly //Remove all ECDSA cipher suites, as certificate cannot handle ECDSA //loop all cipher suites provided for(i=0; i<SSL_CIPSPEC_COUNT; i++) { if( //remove every ECDHE curve ps_sslCtx->s_sslGut.ae_cipSpecs[i] == TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA || ps_sslCtx->s_sslGut.ae_cipSpecs[i] == TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA || ps_sslCtx->s_sslGut.ae_cipSpecs[i] == TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA ) { ps_sslCtx->s_sslGut.ae_cipSpecs[i] = TLS_NULL_WITH_NULL_NULL; } } break; } i_state = SSL_SERVER_ACCEPT; LOG_OK("Accept"); } /* if ... else */ break; /* SSL_SERVER_LISTEN */ case SSL_SERVER_ACCEPT: /* Operates the SSL Handshake */ switch(sslSoc_accept (ps_sslCtx)) { case E_SSL_AGAIN: break; case E_SSL_OK: /* print some connection specifics */ printf("\n>INFO::Ciphers: RX = 0x%.4X, TX = 0x%.4X\n", ps_sslCtx->s_sslGut.e_rxCipSpec, ps_sslCtx->s_sslGut.e_txCipSpec); printf("\n>INFO::Version: 0x%.4X\n", ps_sslCtx->e_ver); i_state = SSL_SERVER_READ; /* Reads the current system time */ l_timeStart = fp_getCurTime(); l_Start = l_timeStart; l_bytesRead = 0; break; case E_SSL_ERROR: default: LOG_ERR("sslSoc_accept error"); i_state = SSL_SERVER_CLOSE_ERR; ps_sslCtx->e_socState = E_SSL_SOCKET_UNUSED; break; } /* switch */ break; /* SSL_SERVER_ACCEPT */ case SSL_SERVER_READ: l_bytes = 0; /* Just read and show on console. */ /* Read */ memset(c_readBuf, 0, sizeof(c_readBuf)); /* read from SSL socket */ l_bytes = sslSoc_read(ps_sslCtx, c_readBuf, sizeof(c_readBuf)); if (l_bytes > 0) { if (echo != 0) { /* server echo: transmit received byte string */ memcpy(c_writeBuf, c_readBuf, l_bytes); l_bytesWrite = l_bytes; i_state = SSL_SERVER_WRITE; } else if (strncmp(c_readBuf, "GET / HTTP/1.1\r\n\r\n", 16) == 0) { /* open file to transmit */ fp = fopen(pc_filename, "rb"); if (fp == NULL) { /* could not open file => send an error message */ l_bytesWrite = sprintf(c_writeBuf, "HTTP/1.1 404 Not Found\r\n\r\n"); i_state = SSL_SERVER_WRITE; } else { /* determine the number of bytes in the file to put * that piece of information into the HTTP header */ n = 0; while (fgetc(fp) != EOF) { n++; } rewind(fp); printf("Transmitting file: '%s'\n", pc_filename); /* prepare HTTP header */ l_bytesWrite = sprintf(c_writeBuf, "HTTP/1.1 200 OK\r\n"\ "Content-Type: application/octet-stream\r\n"\ "Content-Length: %d\r\n\r\n", n); /* next step: read first chunk of bytes from file */ i_state = SSL_SERVER_READ_FILE; } } break; } else if (l_bytes < 0) { switch(l_bytes) { case E_SSL_ERROR: i_state = SSL_SERVER_CLOSING; break; case E_SSL_WANT_WRITE: i_state = SSL_SERVER_FLUSH; break; default: break; } } else if (l_bytes == E_SSL_AGAIN) { break; } i_state = SSL_SERVER_CLOSE; break; /* SSL_SERVER_READ */ case SSL_SERVER_READ_FILE: n = 0; if (fp != NULL) { /* read chunk of bytes from file and copy to write buffer */ n = fread(c_filebuf, 1, SSL_WRITE_BLOCK_LEN - l_bytesWrite - 100, fp); } memcpy(&(c_writeBuf[l_bytesWrite]), c_filebuf, n); l_bytesWrite += n; if (n > 0) { /* next step: send data just read from file to peer */ i_state = SSL_SERVER_WRITE; } else { /* we have reached the end of the file: close file and connection */ if (fp != NULL) { fclose(fp); } i_state = SSL_SERVER_CLOSING; } break; /* case SSL_SERVER_READ_FILE */ case SSL_SERVER_WRITE: /* send data to peer */ l_bytes = sslSoc_write(ps_sslCtx, (char*)c_writeBuf, l_bytesWrite); if (l_bytes > 0) { i_state = SSL_SERVER_FLUSH; } else { switch(l_bytes) { case E_SSL_ERROR: printf(DBG_STRING " sslSoc_write error %s", __FILE__, __LINE__, sslDiag_getError(ps_sslCtx)); i_state = SSL_SERVER_CLOSING; break; case E_SSL_WANT_AGAIN: i_state = SSL_SERVER_READ; break; default: break; } } /* need to reset l_bytesWrite to zero because otherwise step * SSL_SERVER_READ_FILE would *append* new data (thinking * previous chunk of bytes from file is the HTTP header) */ l_bytesWrite = 0; break; /* case SSL_SERVER_WRITE */ case SSL_SERVER_FLUSH: { switch(sslSoc_flush(ps_sslCtx)) { case E_SSL_OK: if (echo != 0) { /* in echo mode: start listening again */ i_state = SSL_SERVER_READ; } else { /* in normal mode: read next chunk of bytes from file */ i_state = SSL_SERVER_READ_FILE; } break; /* * It is not, so we can fall thru */ case E_SSL_WANT_AGAIN: i_state = SSL_SERVER_READ; break; case E_SSL_AGAIN: break; case E_SSL_ERROR: default: i_state = SSL_SERVER_CLOSING; break; } }/* SSL_SERVER_FLUSH */ break; case SSL_SERVER_CLOSING: case SSL_SERVER_CLOSING_ERR: LOG_RAW("Shutting down SSL connection..."); do { l_bytes = sslSoc_shutdown(ps_sslCtx); printf("sslSoc_shutdown(...) returned: %d\n", l_bytes); if (l_bytes == E_SSL_OK && i_state == SSL_SERVER_CLOSING) { /* connection successfully closed (passive close) */ i_state = SSL_SERVER_CLOSE; } else if (l_bytes != E_SSL_AGAIN) { /* connection successfully closed (error case) */ i_state = SSL_SERVER_CLOSE_ERR; } } while (l_bytes != E_SSL_OK && l_bytes != E_SSL_ERROR); printf("done!\n"); break; case SSL_SERVER_CLOSE: case SSL_SERVER_CLOSE_ERR: sslSoc_free(ps_sslCtx); close(srv_socdesc); puts("Socket closed"); E_SERVER_FSM_RESULT retval = (i_state == SSL_SERVER_CLOSE_ERR) ? E_SERVER_FSM_ERROR : E_SERVER_FSM_DONE; i_state = SSL_SERVER_REINIT; return retval; break; } /* switch */ /* server FSM would like to be re-entered again */ return E_SERVER_FSM_AGAIN; }
void AsyncSMTPSocketAccept(SOCKET sock,int event,int error) { SOCKET new_sock; SOCKADDR_IN acc_sin; /* Accept socket address - internet style */ int acc_sin_len; /* Accept socket address length */ struct sockaddr peer_info; int peer_len; struct in_addr peer_addr; unsigned long blocked; smtp_node *smtp; if (event != FD_ACCEPT) { eprintf("AsyncSMTPSocketAccept got non-accept %i\n",event); return; } if (error != 0) { eprintf("AsyncSMTPSocketAccept got error %i\n",error); return; } acc_sin_len = sizeof acc_sin; new_sock = accept(sock,(struct sockaddr *) &acc_sin,&acc_sin_len); if (new_sock == SOCKET_ERROR) { eprintf("AcceptSMTPSocketConnections accept failed, error %i\n", GetLastError()); return; } peer_len = sizeof peer_info; if (getpeername(new_sock,&peer_info,&peer_len) < 0) { eprintf("AcceptSMTPSocketConnections getpeername failed error %i\n", GetLastError()); return; } if (WSAAsyncSelect(new_sock,hwndMain,0,0) != 0) { eprintf("AcceptSMTPSocketConnection can't undo Async Select\n"); closesocket(new_sock); return; } blocked = 0; if (ioctlsocket(new_sock,FIONBIO,&blocked) == SOCKET_ERROR) { eprintf("AcceptSMTPSocketConnection can't make socket blocking, %i\n",WSAGetLastError()); closesocket(new_sock); return; } smtp = (smtp_node *) AllocateMemory(MALLOC_ID_SMTP,sizeof(smtp_node)); // this seems to be the right thing to do ! memcpy(&peer_addr,(long *)&(acc_sin.sin_addr),sizeof(struct in_addr)); strcpy(smtp->source_name,inet_ntoa(peer_addr)); smtp->sock = new_sock; smtp->forward_path = NULL; smtp->reverse_path = NULL; smtp->data = NULL; smtp->len_buf = 0; smtp->state = SMTP_READY; /* this kicks off a thread to handle everything */ HandleSMTPConnection(smtp); }
static void enumerator_select(RETRANSLATOR *pRetranslator, void *ctx) { unsigned long status; char port[12]; struct addrinfo sHints, *psAddrInfo, *p; ENUMCONTEXT *pContext = (ENUMCONTEXT *)ctx; time_t now = time(NULL); switch (pRetranslator->connection_status) { case RETRANSLATOR_STATUS_INIT: memset(&sHints, 0, sizeof(struct addrinfo)); sHints.ai_family = PF_UNSPEC; sHints.ai_socktype = SOCK_STREAM; sHints.ai_protocol = IPPROTO_TCP; sHints.ai_flags = AI_PASSIVE; sprintf(port, "%u", pRetranslator->port); status = getaddrinfo(pRetranslator->host.c_str(), port, &sHints, &psAddrInfo); if (status != 0) { api_log_printf("[DORTRANS] getaddrinfo failed for %s:%u\r\n", pRetranslator->host.c_str(), pRetranslator->port); break; } for (p = psAddrInfo; p; p = p->ai_next) { pRetranslator->sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol); if (pRetranslator->sock < 0) { api_log_printf("[DORTRANS] errno #%d on creating socket\r\n", errno); continue; } status = 1; #ifdef _MSC_VER ioctlsocket(pRetranslator->sock, FIONBIO, &status); #else fcntl(pRetranslator->sock, F_SETFL, O_NONBLOCK); #endif api_log_printf("[DORTRANS] socket #%d connecting to %s:%u\r\n", pRetranslator->sock, pRetranslator->host.c_str(), pRetranslator->port); status = connect(pRetranslator->sock, p->ai_addr, p->ai_addrlen); if (status == 0) { pRetranslator->connection_status = RETRANSLATOR_STATUS_CONNECTED; pRetranslator->timeout = 0; pRetranslator->status = DORTRANS_STATUS_AUTH; api_log_printf("[DORTRANS] socket #%d connected immidiatly\r\n"); break; } else { int error; #ifdef _MSC_VER error = WSAGetLastError(); if (error == WSAEWOULDBLOCK) pRetranslator->connection_status = RETRANSLATOR_STATUS_CONNECTING; #else error = errno; if (error == EINPROGRESS) pRetranslator->connection_status = RETRANSLATOR_STATUS_CONNECTING; #endif if (pRetranslator->connection_status != RETRANSLATOR_STATUS_CONNECTING) { api_log_printf("[DORTRANS] error #%d on connecting to %s:%u\r\n", error, pRetranslator->host.c_str(), pRetranslator->port); closesocket(pRetranslator->sock); pRetranslator->sock = -1; } else { pRetranslator->timeout = now + 60; } break; } } freeaddrinfo(psAddrInfo); break; case RETRANSLATOR_STATUS_CONNECTING: if (pRetranslator->timeout <= now) { api_log_printf("[DORTRANS] socket #%d connect timeout, closing\r\n", pRetranslator->sock); pRetranslator->connection_status = RETRANSLATOR_STATUS_INIT; closesocket(pRetranslator->sock); pRetranslator->sock = -1; break; } FD_SET(pRetranslator->sock, &pContext->fdReadSet); FD_SET(pRetranslator->sock, &pContext->fdWriteSet); if (pRetranslator->sock > pContext->max_fd) pContext->max_fd = pRetranslator->sock; break; case RETRANSLATOR_STATUS_CONNECTED: FD_SET(pRetranslator->sock, &pContext->fdReadSet); switch (pRetranslator->status) { case DORTRANS_STATUS_WAITACK: if ((pRetranslator->timeout != 0)&&(pRetranslator->timeout <= now)) { api_log_printf("[DORTRANS] socket #%d ack timeout, closing\r\n", pRetranslator->sock); pRetranslator->connection_status = RETRANSLATOR_STATUS_INIT; closesocket(pRetranslator->sock); pRetranslator->sock = -1; break; } if (pRetranslator->sock > pContext->max_fd) pContext->max_fd = pRetranslator->sock; break; case DORTRANS_STATUS_ONLINE: spinlock_lock(&pRetranslator->spinlock); if (!pRetranslator->records_list.empty()) { FD_SET(pRetranslator->sock, &pContext->fdWriteSet); } spinlock_unlock(&pRetranslator->spinlock); if (pRetranslator->sock > pContext->max_fd) pContext->max_fd = pRetranslator->sock; if (pRetranslator->last_send + 120 < now) { DORTRANSPING dp; memset(&dp, 0, sizeof(dp)); dp.frame_tag[0] = '~'; dp.frame_tag[1] = '~'; dp.frame_len = sizeof(DORTRANSPING); dp.pack_len = sizeof(dp.pack_len) + sizeof(dp.pack_num) + sizeof(dp.pack_type) + sizeof(dp.pack_reserved); dp.pack_num = pRetranslator->pack_num++; dp.pack_type = 10; unsigned char *uptr = (unsigned char *)&dp; dp.frame_crc = 0x00; for (int j = 0; j < sizeof(dp) - 1; j++) dp.frame_crc ^= *uptr++; api_log_printf("[DORTRANS] Send ping packet, socket #%d\r\n", pRetranslator->sock); send(pRetranslator->sock, (char *)&dp, sizeof(dp), 0); pRetranslator->last_send = now; } break; } } }
int R_SockConnect(int port, char *host, int timeout) { SOCKET s; fd_set wfd, rfd; struct timeval tv; int status = 0; double used = 0.0; struct sockaddr_in server; struct hostent *hp; check_init(); s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (s == -1) return -1; #ifdef Win32 { u_long one = 1; status = ioctlsocket(s, FIONBIO, &one) == SOCKET_ERROR ? -1 : 0; } #else #ifdef HAVE_FCNTL if ((status = fcntl(s, F_GETFL, 0)) != -1) { #ifdef O_NONBLOCK status |= O_NONBLOCK; #else /* O_NONBLOCK */ #ifdef F_NDELAY status |= F_NDELAY; #endif /* F_NDELAY */ #endif /* !O_NONBLOCK */ status = fcntl(s, F_SETFL, status); } #endif if (status < 0) { closesocket(s); return(-1); } #endif if (! (hp = gethostbyname(host))) return -1; memcpy((char *)&server.sin_addr, hp->h_addr_list[0], hp->h_length); server.sin_port = htons((short)port); server.sin_family = AF_INET; if ((connect(s, (struct sockaddr *) &server, sizeof(server)) == -1)) { switch (socket_errno()) { case EINPROGRESS: case EWOULDBLOCK: break; default: closesocket(s); return(-1); } } while(1) { int maxfd = 0; R_ProcessEvents(); #ifdef Unix if(R_wait_usec > 0) { R_PolledEvents(); tv.tv_sec = 0; tv.tv_usec = R_wait_usec; } else { tv.tv_sec = timeout; tv.tv_usec = 0; } #elif defined(Win32) tv.tv_sec = 0; tv.tv_usec = 2e5; #else tv.tv_sec = timeout; tv.tv_usec = 0; #endif #ifdef Unix maxfd = setSelectMask(R_InputHandlers, &rfd); #else FD_ZERO(&rfd); #endif FD_ZERO(&wfd); FD_SET(s, &wfd); if(maxfd < s) maxfd = s; switch(R_SelectEx(maxfd+1, &rfd, &wfd, NULL, &tv, NULL)) { case 0: /* Time out */ used += tv.tv_sec + 1e-6 * tv.tv_usec; if(used < timeout) continue; closesocket(s); return(-1); case -1: /* Ermm.. ?? */ closesocket(s); return(-1); } if ( FD_ISSET(s, &wfd) ) { R_SOCKLEN_T len; len = sizeof(status); if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*)&status, &len) < 0){ /* Solaris error code */ return (-1); } if ( status ) { closesocket(s); errno = status; return (-1); } else return(s); #ifdef Unix } else { /* some other handler needed */ InputHandler *what; what = getSelectedHandler(R_InputHandlers, &rfd); if(what != NULL) what->handler((void*) NULL); continue; #endif } } /* not reached return(-1); */ }
int CSocket::connect() { // Make sure the socket is disconnected. if (properties.state != SOCKET_STATE_DISCONNECTED) return SOCKET_ALREADY_CONNECTED; // Flag the socket as connecting. properties.state = SOCKET_STATE_CONNECTING; // Create socket. if (properties.protocol == SOCKET_PROTOCOL_TCP) properties.handle = socket(AF_INET, SOCK_STREAM, 0); else properties.handle = socket(AF_INET, SOCK_DGRAM, 0); // Make sure the socket was created correctly. if (properties.handle == INVALID_SOCKET) { SLOG("[CSocket::connect] socket() returned INVALID_SOCKET.\n"); properties.state = SOCKET_STATE_DISCONNECTED; return SOCKET_INVALID; } // Bind the socket if it is a server-type socket. if (properties.type == SOCKET_TYPE_SERVER) { // Let us reuse the address. Freaking bind. int value = 1; setsockopt(properties.handle, SOL_SOCKET, SO_REUSEADDR, (char*)&value, sizeof(value)); // Bind the socket. if (::bind(properties.handle, (struct sockaddr *)&properties.address, sizeof(properties.address)) == SOCKET_ERROR) { SLOG("[CSocket::connect] bind() returned error: %s\n", errorMessage(identifyError())); disconnect(); return SOCKET_BIND_ERROR; } } // Connect the socket. if (properties.type != SOCKET_TYPE_SERVER) { if (::connect(properties.handle, (struct sockaddr *)&properties.address, sizeof(properties.address)) == SOCKET_ERROR) { SLOG("[CSocket::connect] connect() returned error: %s\n", errorMessage(identifyError())); disconnect(); return SOCKET_CONNECT_ERROR; } } // Disable the nagle algorithm. if (properties.protocol == SOCKET_PROTOCOL_TCP) { int nagle = 1; setsockopt(properties.handle, IPPROTO_TCP, TCP_NODELAY, (char*)&nagle, sizeof(nagle)); } // Set as non-blocking. #if defined(_WIN32) || defined(_WIN64) u_long flags = 1; ioctlsocket(properties.handle, FIONBIO, &flags); #else int flags = fcntl(properties.handle, F_GETFL, 0); fcntl(properties.handle, F_SETFL, flags | O_NONBLOCK); #endif // Socket connected! properties.state = SOCKET_STATE_CONNECTED; // Listening sockets. if (properties.type == SOCKET_TYPE_SERVER) { if (properties.protocol == SOCKET_PROTOCOL_UDP) properties.state = SOCKET_STATE_LISTENING; else if (properties.protocol == SOCKET_PROTOCOL_TCP) { if (::listen(properties.handle, SOMAXCONN) == SOCKET_ERROR) { SLOG("[CSocket::connect] listen() returned error: %s\n", errorMessage(identifyError())); disconnect(); return SOCKET_CONNECT_ERROR; } properties.state = SOCKET_STATE_LISTENING; } } return SOCKET_OK; }
static int do_connect(char *host, int port) { int sock; struct sockaddr_in addr, check_connect; fd_set rset, wset; struct timeval timeout; // start unconnected int connected = 0; #ifdef WIN32 WORD version; WSADATA wsaData; int size, error; u_long no = 0; const char yes = 1; version = MAKEWORD(2,2); error = WSAStartup(version, &wsaData); if (error != 0) { return 0; } // create socket sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock == INVALID_SOCKET) { return 0; } #else uint size; int yes = 1; // create socket if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { croak("couldn't create socket: %s\n", strerror(errno)); return -1; } #endif // timeout timeout.tv_sec = 20; timeout.tv_usec = 0; // get addresses if (!mongo_link_sockaddr(&addr, host, port)) { return -1; } setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &yes, INT_32); setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &yes, INT_32); #ifdef WIN32 ioctlsocket(sock, FIONBIO, (u_long*)&yes); #else fcntl(sock, F_SETFL, O_NONBLOCK); #endif FD_ZERO(&rset); FD_SET(sock, &rset); FD_ZERO(&wset); FD_SET(sock, &wset); // connect if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) { #ifdef WIN32 errno = WSAGetLastError(); if (errno != WSAEINPROGRESS && errno != WSAEWOULDBLOCK) #else if (errno != EINPROGRESS) #endif { return -1; } if (!select(sock+1, &rset, &wset, 0, &timeout)) { return -1; } size = sizeof(check_connect); connected = getpeername(sock, (struct sockaddr*)&addr, &size); if (connected == -1) { return -1; } } // reset flags #ifdef WIN32 ioctlsocket(sock, FIONBIO, &no); #else fcntl(sock, F_SETFL, 0); #endif return sock; }
static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle, SOCKET socket, int family) { DWORD yes = 1; WSAPROTOCOL_INFOW info; int opt_len; if (handle->socket != INVALID_SOCKET) return UV_EBUSY; /* Set the socket to nonblocking mode */ if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) { return WSAGetLastError(); } /* Make the socket non-inheritable */ if (!SetHandleInformation((HANDLE)socket, HANDLE_FLAG_INHERIT, 0)) { return GetLastError(); } /* Associate it with the I/O completion port. Use uv_handle_t pointer as * completion key. */ if (CreateIoCompletionPort((HANDLE)socket, loop->iocp, (ULONG_PTR)socket, 0) == NULL) { return GetLastError(); } /* All known Windows that support SetFileCompletionNotificationModes have a * bug that makes it impossible to use this function in conjunction with * datagram sockets. We can work around that but only if the user is using * the default UDP driver (AFD) and has no other. LSPs stacked on top. Here * we check whether that is the case. */ opt_len = (int) sizeof info; if (getsockopt( socket, SOL_SOCKET, SO_PROTOCOL_INFOW, (char*) &info, &opt_len) == SOCKET_ERROR) { return GetLastError(); } if (info.ProtocolChain.ChainLen == 1) { if (SetFileCompletionNotificationModes( (HANDLE) socket, FILE_SKIP_SET_EVENT_ON_HANDLE | FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) { handle->flags |= UV_HANDLE_SYNC_BYPASS_IOCP; handle->func_wsarecv = uv_wsarecv_workaround; handle->func_wsarecvfrom = uv_wsarecvfrom_workaround; } else if (GetLastError() != ERROR_INVALID_FUNCTION) { return GetLastError(); } } handle->socket = socket; if (family == AF_INET6) { handle->flags |= UV_HANDLE_IPV6; } else { assert(!(handle->flags & UV_HANDLE_IPV6)); } return 0; }
void Run() { break_ = false; // prepare the window events which we use to wake up on incoming data // we use this instead of select() primarily to support the AsyncBreak() // mechanism. std::vector<HANDLE> events( socketListeners_.size() + 1, 0 ); int j=0; for( std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i = socketListeners_.begin(); i != socketListeners_.end(); ++i, ++j ){ HANDLE event = CreateEvent( NULL, FALSE, FALSE, NULL ); WSAEventSelect( i->second->impl_->Socket(), event, FD_READ ); // note that this makes the socket non-blocking which is why we can safely call RecieveFrom() on all sockets below events[j] = event; } events[ socketListeners_.size() ] = breakEvent_; // last event in the collection is the break event // configure the timer queue double currentTimeMs = GetCurrentTimeMs(); // expiry time ms, listener std::vector< std::pair< double, AttachedTimerListener > > timerQueue_; for( std::vector< AttachedTimerListener >::iterator i = timerListeners_.begin(); i != timerListeners_.end(); ++i ) timerQueue_.push_back( std::make_pair( currentTimeMs + i->initialDelayMs, *i ) ); std::sort( timerQueue_.begin(), timerQueue_.end(), CompareScheduledTimerCalls ); const int MAX_BUFFER_SIZE = 4098; char *data = new char[ MAX_BUFFER_SIZE ]; IpEndpointName remoteEndpoint; while( !break_ ){ double currentTimeMs = GetCurrentTimeMs(); DWORD waitTime = INFINITE; if( !timerQueue_.empty() ){ waitTime = (DWORD)( timerQueue_.front().first >= currentTimeMs ? timerQueue_.front().first - currentTimeMs : 0 ); } DWORD waitResult = WaitForMultipleObjects( (DWORD)socketListeners_.size() + 1, &events[0], FALSE, waitTime ); if( break_ ) break; if( waitResult != WAIT_TIMEOUT ){ for( int i = waitResult - WAIT_OBJECT_0; i < (int)socketListeners_.size(); ++i ){ std::size_t size = socketListeners_[i].second->ReceiveFrom( remoteEndpoint, data, MAX_BUFFER_SIZE ); if( size > 0 ){ socketListeners_[i].first->ProcessPacket( data, (int)size, remoteEndpoint ); if( break_ ) break; } } } // execute any expired timers currentTimeMs = GetCurrentTimeMs(); bool resort = false; for( std::vector< std::pair< double, AttachedTimerListener > >::iterator i = timerQueue_.begin(); i != timerQueue_.end() && i->first <= currentTimeMs; ++i ){ i->second.listener->TimerExpired(); if( break_ ) break; i->first += i->second.periodMs; resort = true; } if( resort ) std::sort( timerQueue_.begin(), timerQueue_.end(), CompareScheduledTimerCalls ); } delete [] data; // free events j = 0; for( std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i = socketListeners_.begin(); i != socketListeners_.end(); ++i, ++j ){ WSAEventSelect( i->second->impl_->Socket(), events[j], 0 ); // remove association between socket and event CloseHandle( events[j] ); unsigned long enableNonblocking = 0; ioctlsocket( i->second->impl_->Socket(), FIONBIO, &enableNonblocking ); // make the socket blocking again } }
void BaseTCPServer::ListenNewConnections() { SOCKET tmpsock; struct sockaddr_in from; struct in_addr in; unsigned int fromlen; unsigned short port; from.sin_family = AF_INET; fromlen = sizeof(from); LockMutex lock(&MSock); #ifndef DARWIN // Corysia - On OSX, 0 is a valid fd. if (!sock) { return; } #else if (sock == -1) { return; } #endif // Check for pending connects #ifdef _WINDOWS unsigned long nonblocking = 1; while ((tmpsock = accept(sock, (struct sockaddr*) &from, (int *) &fromlen)) != INVALID_SOCKET) { ioctlsocket (tmpsock, FIONBIO, &nonblocking); #else #ifdef __CYGWIN__ while ((tmpsock = accept(sock, (struct sockaddr *) &from, (int *) &fromlen)) != INVALID_SOCKET) { #else while ((tmpsock = accept(sock, (struct sockaddr*) &from, &fromlen)) != INVALID_SOCKET) { #endif fcntl(tmpsock, F_SETFL, O_NONBLOCK); #endif int bufsize = 64 * 1024; // 64kbyte receive buffer, up from default of 8k setsockopt(tmpsock, SOL_SOCKET, SO_RCVBUF, (char*) &bufsize, sizeof(bufsize)); port = from.sin_port; in.s_addr = from.sin_addr.s_addr; // New TCP connection, this must consume the socket. CreateNewConnection(GetNextID(), tmpsock, in.s_addr, ntohs(from.sin_port)); } } bool BaseTCPServer::Open(uint16 in_port, char* errbuf) { if (errbuf) { errbuf[0] = 0; } LockMutex lock(&MSock); if (sock != 0) { if (errbuf) { snprintf(errbuf, TCPServer_ErrorBufferSize, "Listening socket already open"); } return false; } if (in_port != 0) { pPort = in_port; } #ifdef _WINDOWS SOCKADDR_IN address; unsigned long nonblocking = 1; #else struct sockaddr_in address; #endif int reuse_addr = 1; // Setup internet address information. // This is used with the bind() call memset((char *) &address, 0, sizeof(address)); address.sin_family = AF_INET; address.sin_port = htons(pPort); address.sin_addr.s_addr = htonl(INADDR_ANY); // Setting up TCP port for new TCP connections sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) { if (errbuf) { snprintf(errbuf, TCPServer_ErrorBufferSize, "socket(): INVALID_SOCKET"); } return false; } // Quag: don't think following is good stuff for TCP, good for UDP // Mis: SO_REUSEADDR shouldn't be a problem for tcp--allows you to restart // without waiting for conns in TIME_WAIT to die setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse_addr, sizeof(reuse_addr)); if (bind(sock, (struct sockaddr *) &address, sizeof(address)) < 0) { #ifdef _WINDOWS closesocket(sock); #else close(sock); #endif sock = 0; if (errbuf) { sprintf(errbuf, "bind(): <0"); } return false; } int bufsize = 64 * 1024; // 64kbyte receive buffer, up from default of 8k setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char*) &bufsize, sizeof(bufsize)); #ifdef _WINDOWS ioctlsocket (sock, FIONBIO, &nonblocking); #else fcntl(sock, F_SETFL, O_NONBLOCK); #endif if (listen(sock, SOMAXCONN) == SOCKET_ERROR) { #ifdef _WINDOWS closesocket(sock); if (errbuf) { snprintf(errbuf, TCPServer_ErrorBufferSize, "listen() failed, Error: %d", WSAGetLastError()); } #else close(sock); if (errbuf) { snprintf(errbuf, TCPServer_ErrorBufferSize, "listen() failed, Error: %s", strerror(errno)); } #endif sock = 0; return false; } return true; } void BaseTCPServer::Close() { StopLoopAndWait(); LockMutex lock(&MSock); if (sock) { #ifdef _WINDOWS closesocket(sock); #else close(sock); #endif } sock = 0; } bool BaseTCPServer::IsOpen() { MSock.lock(); bool ret = (bool) (sock != 0); MSock.unlock(); return ret; }
/* ======================== NET_IPSocket ======================== */ int NET_IPSocket( const char* bind_ip, int port, netadr_t* bound_to ) { SOCKET newsocket; sockaddr_in address; if( port != PORT_ANY ) { if( bind_ip ) { idLib::Printf( "Opening IP socket: %s:%i\n", bind_ip, port ); } else { idLib::Printf( "Opening IP socket: localhost:%i\n", port ); } } if( ( newsocket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ) ) == INVALID_SOCKET ) { idLib::Printf( "WARNING: UDP_OpenSocket: socket: %s\n", NET_ErrorString() ); return 0; } // make it non-blocking #ifdef _WIN32 // which has no fcntl() unsigned long _true = 1; if( ioctlsocket( newsocket, FIONBIO, &_true ) == SOCKET_ERROR ) { idLib::Printf( "WARNING: UDP_OpenSocket: ioctl FIONBIO: %s\n", NET_ErrorString() ); closesocket( newsocket ); return 0; } #else int flags = fcntl( newsocket, F_GETFL, 0 ); if( flags < 0 ) { idLib::Printf( "WARNING: UDP_OpenSocket: fcntl F_GETFL: %s\n", NET_ErrorString() ); closesocket( newsocket ); return 0; } flags |= O_NONBLOCK; if( fcntl( newsocket, F_SETFL, flags ) < 0 ) { idLib::Printf( "WARNING: UDP_OpenSocket: fcntl F_SETFL with O_NONBLOCK: %s\n", NET_ErrorString() ); closesocket( newsocket ); return 0; } #endif // make it broadcast capable int i = 1; if( setsockopt( newsocket, SOL_SOCKET, SO_BROADCAST, ( char* )&i, sizeof( i ) ) == SOCKET_ERROR ) { idLib::Printf( "WARNING: UDP_OpenSocket: setsockopt SO_BROADCAST: %s\n", NET_ErrorString() ); closesocket( newsocket ); return 0; } if( !bind_ip || !bind_ip[0] || !idStr::Icmp( bind_ip, "localhost" ) ) { address.sin_addr.s_addr = INADDR_ANY; } else { Net_StringToSockaddr( bind_ip, &address, true ); } if( port == PORT_ANY ) { address.sin_port = 0; } else { address.sin_port = htons( ( short )port ); } address.sin_family = AF_INET; if( bind( newsocket, ( const sockaddr* )&address, sizeof( address ) ) == SOCKET_ERROR ) { idLib::Printf( "WARNING: UDP_OpenSocket: bind: %s\n", NET_ErrorString() ); closesocket( newsocket ); return 0; } // if the port was PORT_ANY, we need to query again to know the real port we got bound to // ( this used to be in idUDP::InitForPort ) if( bound_to ) { socklen_t len = sizeof( address ); if( getsockname( newsocket, ( struct sockaddr* )&address, &len ) == SOCKET_ERROR ) { common->Printf( "ERROR: IPSocket: getsockname: %s\n", NET_ErrorString() ); closesocket( newsocket ); return 0; } Net_SockadrToNetadr( &address, bound_to ); } return newsocket; }
/*..........................................................................*/ uint8_t QS_onStartup(void const *arg) { static uint8_t qsBuf[1024]; /* buffer for QS output */ static uint8_t qsRxBuf[100]; /* buffer for QS receive channel */ static WSADATA wsaData; char hostName[64]; char const *src; char *dst; USHORT port = 6601; /* default QSPY server port */ ULONG ioctl_opt = 1; struct sockaddr_in sockAddr; struct hostent *server; QS_initBuf(qsBuf, sizeof(qsBuf)); QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); /* initialize Windows sockets */ if (WSAStartup(MAKEWORD(2,0), &wsaData) == SOCKET_ERROR) { printf("Windows Sockets cannot be initialized."); return (uint8_t)0; } src = (arg != (void const *)0) ? (char const *)arg : "localhost"; dst = hostName; while ((*src != '\0') && (*src != ':') && (dst < &hostName[sizeof(hostName)])) { *dst++ = *src++; } *dst = '\0'; if (*src == ':') { port = (USHORT)strtoul(src + 1, NULL, 10); } l_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); /* TCP socket */ if (l_sock == INVALID_SOCKET){ printf("Socket cannot be created; error 0x%08X\n", WSAGetLastError()); return (uint8_t)0; /* failure */ } server = gethostbyname(hostName); if (server == NULL) { printf("QSpy host name %s cannot be resolved; error 0x%08X\n", hostName, WSAGetLastError()); return (uint8_t)0; } memset(&sockAddr, 0, sizeof(sockAddr)); sockAddr.sin_family = AF_INET; memcpy(&sockAddr.sin_addr, server->h_addr, server->h_length); sockAddr.sin_port = htons(port); if (connect(l_sock, (struct sockaddr *)&sockAddr, sizeof(sockAddr)) == SOCKET_ERROR) { printf("Cannot connect to the QSPY server; error 0x%08X\n", WSAGetLastError()); QS_EXIT(); return (uint8_t)0; /* failure */ } /* Set the socket to non-blocking mode. */ if (ioctlsocket(l_sock, FIONBIO, &ioctl_opt) == SOCKET_ERROR) { printf("Socket configuration failed.\n" "Windows socket error 0x%08X.", WSAGetLastError()); QS_EXIT(); return (uint8_t)0; /* failure */ } /* set up the QS filters... */ QS_FILTER_ON(QS_QEP_STATE_ENTRY); QS_FILTER_ON(QS_QEP_STATE_EXIT); QS_FILTER_ON(QS_QEP_STATE_INIT); QS_FILTER_ON(QS_QEP_INIT_TRAN); QS_FILTER_ON(QS_QEP_INTERN_TRAN); QS_FILTER_ON(QS_QEP_TRAN); QS_FILTER_ON(QS_QEP_IGNORED); QS_FILTER_ON(QS_QEP_DISPATCH); QS_FILTER_ON(QS_QEP_UNHANDLED); QS_FILTER_ON(QS_QF_ACTIVE_POST_FIFO); QS_FILTER_ON(QS_QF_ACTIVE_POST_LIFO); QS_FILTER_ON(QS_QF_PUBLISH); QS_FILTER_ON(PHILO_STAT); QS_FILTER_ON(COMMAND_STAT); /* return the status of creating the idle thread */ return (CreateThread(NULL, 1024, &idleThread, (void *)0, 0, NULL) != (HANDLE)0) ? (uint8_t)1 : (uint8_t)0; }
void socket_set_nonblock(int fd) { unsigned long opt = 1; ioctlsocket(fd, FIONBIO, &opt); }
client_t *server_accept(int fd, const char *address) { client_t *client = clients; for (int i = 0; i < MAXCLIENTS; i++, client++) { if (!CLIENT_USED(client)) goto found; } // write(fd, "no free slot\r\n", 14); fprintf(stderr, "cannot accept() new incoming connection: no free slot\n"); return NULL; found: memset(client, 0, sizeof(client_t)); client->fd = fd; // File Writer wird leicht unterschiedlich behandelt client->is_file_writer = strstr(address, "special:file") == address; // Non Blocking setzen #ifdef WIN32 DWORD notblock = 1; ioctlsocket(client->fd, FIONBIO, ¬block); #else if (fcntl(client->fd, F_SETFL, O_NONBLOCK) < 0) { fprintf(stderr, "cannot set accept()ed socket nonblocking: %s\n", strerror(errno)); return NULL; } #endif // Soll Verbindung angenommen werden? lua_pushliteral(L, "on_new_client"); lua_rawget(L, LUA_GLOBALSINDEX); lua_pushstring(L, address); if (lua_pcall(L, 1, 2, 0) != 0) { fprintf(stderr, "error calling on_new_client: %s\n", lua_tostring(L, -1)); lua_pop(L, 1); return NULL; } if (!lua_toboolean(L, -2)) { size_t len; const char *msg = lua_tolstring(L, -1, &len); write(client->fd, msg, len); lua_pop(L, 2); return NULL; } lua_pop(L, 2); // Libevent aktivieren event_set(&client->rd_event, client->fd, EV_READ | EV_PERSIST, server_readable, client); event_set(&client->wr_event, client->fd, EV_WRITE , server_writable, client); client->in_buf = evbuffer_new(); client->out_buf = evbuffer_new(); client->compress = 0; client->kill_me = NULL; client->player = NULL; client->next = NULL; client->prev = NULL; client->is_gui_client = 0; client->next_gui = NULL; client->prev_gui = NULL; num_clients++; // Annehmen lua_pushliteral(L, "on_client_accepted"); lua_rawget(L, LUA_GLOBALSINDEX); lua_pushnumber(L, client_num(client)); lua_pushstring(L, address); if (lua_pcall(L, 2, 0, 0) != 0) { fprintf(stderr, "error calling on_client_accepted: %s\n", lua_tostring(L, -1)); lua_pop(L, 1); } if (!client->is_file_writer) event_add(&client->rd_event, NULL); return client; }
main(int argc,char *argv[]) #endif { int listener_fd, new_fd; int remotelen; int port = 0; int c, on; struct sockaddr_in local_sin, remote_sin; static fd_set fdset, fdset_saved; struct conn_stat *rconn, *wconn; #ifdef STE_WINDOWS u_long param = 0; /* FIONBIO コマンドのパラメータ Non-Blocking ON*/ int nRtn; WSADATA wsaData; stehubstat_t stehubstat[1]; nRtn = WSAStartup(MAKEWORD(1, 1), &wsaData); #endif while ((c = getopt(argc, argv, "p:d:")) != EOF){ switch (c) { case 'p': port = atoi(optarg); break; case 'd': debuglevel = atoi(optarg); break; default: print_usage(argv[0]); } } conn_stat_head->next = NULL; conn_stat_head->fd = 0; if(( listener_fd = socket( AF_INET, SOCK_STREAM,0 )) < 0 ) { SET_ERRNO(); print_err(LOG_ERR,"socket: %s (%d)\n", strerror(errno), errno); exit(1); } on = 1; if((setsockopt(listener_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on))) <0){ SET_ERRNO(); print_err(LOG_ERR,"setsockopt:%s\n", strerror(errno)); exit(1); } if(port == 0) port = PORT_NO; memset((char *)&remote_sin, 0x0, sizeof(struct sockaddr_in)); memset((char *)&local_sin, 0x0, sizeof(struct sockaddr_in)); local_sin.sin_port = htons((short)port); local_sin.sin_family = AF_INET; local_sin.sin_addr.s_addr = htonl(INADDR_ANY); if(bind(listener_fd,(struct sockaddr *)&local_sin,sizeof(struct sockaddr_in)) < 0 ){ SET_ERRNO(); print_err(LOG_ERR,"bind:%s\n", strerror(errno)); exit(1); } /* * accept() でブロックされるのを防ぐため、non-blocking mode に設定 */ #ifndef STE_WINDOWS if( fcntl (listener_fd, F_SETFL, O_NONBLOCK) < 0) { #else if( ioctlsocket(listener_fd, FIONBIO, ¶m) < 0){ #endif SET_ERRNO(); print_err(LOG_ERR, "Failed to set nonblock: %s (%d)\n",strerror(errno), errno); exit(1); } if(listen(listener_fd, 5) < 0) { SET_ERRNO(); print_err(LOG_ERR,"listen:%s\n", strerror(errno)); exit(1); } FD_ZERO(&fdset_saved); FD_SET(listener_fd, &fdset_saved); /* * syslog のための設定。Facility は LOG_USER とする * Windows の場合はログファイルをオープンする。 */ #ifdef STE_WINDOWS hStedLog = CreateFile(STEHUB_LOG_FILE, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ| FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); SetFilePointer(hStedLog, 0, NULL, FILE_END); if(isTerminal == FALSE){ /* サービスとして呼ばれている(コマンドプロンプトから呼ばれていない)場合 */ stehubServiceStatus.dwServiceType = SERVICE_WIN32; stehubServiceStatus.dwCurrentState = SERVICE_START_PENDING; stehubServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; stehubServiceStatus.dwWin32ExitCode = 0; stehubServiceStatus.dwServiceSpecificExitCode = 0; stehubServiceStatus.dwCheckPoint = 0; stehubServiceStatus.dwWaitHint = 0; /* サービスコントロールハンドラーを登録 */ stehubServiceStatusHandle = RegisterServiceCtrlHandlerEx( "Stehub", //LPCTSTR stehub_svc_ctrl_handler, //LPHANDLER_FUNCTION_EX (LPVOID)stehubstat //LPVOID ); if (stehubServiceStatusHandle == (SERVICE_STATUS_HANDLE)0){ return; } stehubServiceStatus.dwCurrentState = SERVICE_RUNNING; stehubServiceStatus.dwCheckPoint = 0; stehubServiceStatus.dwWaitHint = 0; if (!SetServiceStatus (stehubServiceStatusHandle, &stehubServiceStatus)){ // SetServiceStatus が失敗した場合の処理・・ print_err(LOG_ERR, "SetServiceStatus Failed\n"); } } #else openlog(basename(argv[0]),LOG_PID,LOG_USER); #endif /* * ここまではとりあえず、フォアグラウンドで実行。 * ここからは、デバッグレベル 0 (デフォルト)なら、バックグラウンド * で実行し、そうでなければフォアグラウンド続行。 * Windows の場合は、いづれにしてもフォアグラウンドで実行 * し、デバッグレベル 1 以上の場合はログをファイルに書く。 */ if (debuglevel == 0){ #ifndef STE_WINDOWS print_err(LOG_NOTICE,"Going to background mode\n"); if(become_daemon() != 0){ print_err(LOG_ERR,"can't become daemon\n"); print_err(LOG_ERR,"Exit\n"); exit(1); } #else use_log = 1; #endif } print_err(LOG_NOTICE,"Started\n"); /* * メインループ * 仮想 NIC デーモンからの接続要求を待ち、接続後は仮想 NIC デーモン * からのデータを待つ。1つの仮想デーモンからのデータを他方に転送する。 */ for(;;){ fdset = fdset_saved; if( select(FD_SETSIZE, &fdset, NULL, NULL, NULL) < 0){ SET_ERRNO(); print_err(LOG_ERR,"select:%s\n", strerror(errno)); } if(FD_ISSET(listener_fd, &fdset)){ remotelen = sizeof(struct sockaddr_in); if((new_fd = accept(listener_fd,(struct sockaddr *)&remote_sin, &remotelen)) < 0){ SET_ERRNO(); if(errno == EINTR || errno == EWOULDBLOCK || errno == ECONNABORTED){ print_err(LOG_NOTICE, "accept: %s\n", strerror(errno)); continue; } else { print_err(LOG_ERR, "accept: %s\n", strerror(errno)); return(-1); } } FD_SET(new_fd, &fdset_saved); print_err(LOG_NOTICE,"fd%d: connection from %s\n",new_fd, inet_ntoa(remote_sin.sin_addr)); add_conn_stat(new_fd, remote_sin.sin_addr); /* * recv() でブロックされるのを防ぐため、non-blocking mode に設定 */ #ifndef STE_WINDOWS if (fcntl(new_fd, F_SETFL, O_NONBLOCK) < 0 ) { #else if(ioctlsocket(new_fd, FIONBIO, ¶m) < 0){ #endif SET_ERRNO(); print_err(LOG_ERR, "fd%d: Failed to set nonblock: %s (%d)\n", new_fd,strerror(errno),errno); return(-1); } continue; } for( rconn = conn_stat_head->next ; rconn != NULL ; rconn = rconn->next){ int rfd, wfd; rfd = rconn->fd; if (FD_ISSET(rfd, &fdset)){ int rsize; char databuf[SOCKBUFSIZE]; char *bufp; int datalen; bufp = (char *)databuf; rsize = recv(rfd, bufp, SOCKBUFSIZE,0); if(rsize == 0){ /* * コネクションが切断されたようだ。 * socket を close してループを抜ける */ print_err(LOG_ERR,"fd%d: Connection closed by %s\n", rfd, inet_ntoa(rconn->addr)); CLOSE(rfd); print_err(LOG_ERR,"fd%d: closed\n", rfd); FD_CLR(rfd, &fdset_saved); delete_conn_stat(rfd); break; } if(rsize < 0){ SET_ERRNO(); /* * 致命的でない error の場合は無視してループを継続 */ if(errno == EINTR || errno == EWOULDBLOCK){ print_err(LOG_NOTICE, "fd%d: recv: %s\n", rfd, strerror(errno)); continue; } /* * エラーが発生したようだ。 * socket を close して forループを抜ける */ print_err(LOG_ERR,"fd%d: recv: %s\n", rfd,strerror(errno)); CLOSE(rfd); print_err(LOG_ERR,"fd%d: closed\n", rfd); FD_CLR(rfd, &fdset_saved); delete_conn_stat(rfd); break; } /* * 他の仮想 NIC にパケットを転送する。 * 「待ち」が発生すると、パフォーマンスに影響があるので、EWOULDBLOCK * の場合は配送をあきらめる。 */ for(wconn = conn_stat_head->next ; wconn != NULL ; wconn = wconn->next){ wfd = wconn->fd; if (rfd == wfd) continue; if( debuglevel > 1){ print_err(LOG_ERR,"fd%d(%s) ==> ", rfd, inet_ntoa(rconn->addr)); print_err(LOG_ERR,"fd%d(%s)\n", wfd,inet_ntoa(wconn->addr)); } if ( send(wfd, bufp, rsize, 0) < 0){ SET_ERRNO(); if(errno == EINTR || errno == EWOULDBLOCK ){ print_err(LOG_NOTICE,"fd%d: send: %s\n", wfd ,strerror(errno)); continue; } else { print_err(LOG_ERR,"fd%d: send: %s (%d)\n",wfd,strerror(errno), errno); CLOSE(wfd); print_err(LOG_ERR,"fd%d: closed\n", wfd); FD_CLR(wfd, &fdset_saved); delete_conn_stat(wfd); break; } } } /* End of loop for send()ing */ } } /* End of loop for each connection */ } /* End of main loop */ } #ifdef STE_WINDOWS /************************************************************************** * Windows の場合の main() * * 引数が -I もしくは -U だった場合には本プログラム(仮想 HUB デーモン) * を Windows のサービスとして登録/登録解除する。 * それ以外の引数が渡された場合には ste_svc_main() を直接呼び出し、引数も * そのまま ste_svc_main() に渡す。 * * 引数(argvとして): * * -I : サービスとして登録。 * -U : 登録解除 * **************************************************************************/ int WINAPIV main(int argc, char *argv[]) { int c; SERVICE_TABLE_ENTRY DispatchTable[] = { { "Stehub", stehub_svc_main}, { NULL, NULL } }; isTerminal = _isatty(_fileno(stdout))? TRUE:FALSE; // // 引数が無ない場合。 // コマンドプロンプトから呼ばれた時は stehub_svc_main() を呼び、 // そうでなければ StartServiceCtlDispatcher() を呼ぶ。 // if(argc == 1 ){ if(isTerminal == TRUE){ stehub_svc_main(argc, argv); return(0); } else { StartServiceCtrlDispatcher(DispatchTable); return(0); } } while((c = getopt(argc, argv, "IU")) != EOF ){ switch(c){ case 'I': // stehub.exe をサービスとして登録 if(stehub_install_svc()) printf("Service Installed Sucessfully\n"); else printf("Error Installing Service\n"); break; case 'U': // stehub.exe のサービスとして登録を解除 if(stehub_delete_svc()) printf("Service UnInstalled Sucessfully\n"); else printf("Error UnInstalling Service\n"); break; default : // // 引数が -U、-I でなければコマンドプロンプト内で // stehub.exe を起動したいのだと判断し、引数を全て // stehub_svc_main() に渡して呼び出す。 // stehub_svc_main(argc, argv); return(0); } } return(0); } /**************************************** * Windows サービス登録ルーチン * ****************************************/ BOOL stehub_install_svc() { LPCTSTR lpszBinaryPathName; TCHAR strDir[1024]; HANDLE schSCManager,schService; GetCurrentDirectory(1024, strDir); strcat((char *)strDir, "\\stehub.exe"); schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS); if (schSCManager == NULL) return FALSE; lpszBinaryPathName=strDir; schService = CreateService(schSCManager,"Stehub", "Stehub Virtual HUB daemon", // 表示用サービス名 SERVICE_ALL_ACCESS, // アクセス SERVICE_WIN32_OWN_PROCESS, // サービスタイプ SERVICE_DEMAND_START, // スタートタイプ SERVICE_ERROR_NORMAL, // エラーコントロールタイプ lpszBinaryPathName, // バイナリへのパス NULL, // No load ordering group NULL, // No tag identifier NULL, // No dependencies NULL, // LocalSystem account NULL);// No password if (schService == NULL) return FALSE; CloseServiceHandle(schService); return TRUE; } /**************************************** * Windows サービス登録解除ルーチン * ****************************************/ BOOL stehub_delete_svc() { HANDLE schSCManager; SC_HANDLE hService; schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS); if (schSCManager == NULL) return FALSE; hService=OpenService(schSCManager, "Stehub", SERVICE_ALL_ACCESS); if (hService == NULL) return FALSE; if(DeleteService(hService)==0) return FALSE; if(CloseServiceHandle(hService)==0) return FALSE; return TRUE; } /****************************************************************************** * stehub_svc_ctrl_handler() * * サービスステータスハンドラー * DEVICEEVENT を拾うためには Handler ではなく、HandlerEx じゃないといけないらしい。 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/handlerex.asp * * まったく呼ばれていないような・・? ******************************************************************************/ DWORD WINAPI stehub_svc_ctrl_handler( DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext ) { PDEV_BROADCAST_HDR p = (PDEV_BROADCAST_HDR) lpEventData; WPARAM wParam = (WPARAM) dwEventType; stehubstat_t *stehubstat = NULL; stehubstat = (stehubstat_t *)lpContext; if(debuglevel > 1){ print_err(LOG_DEBUG, "Service Status Handler stehub_svc_ctrl_handler called\n"); } switch(dwControl){ case SERVICE_CONTROL_DEVICEEVENT: break; case SERVICE_CONTROL_PAUSE: stehubServiceStatus.dwCurrentState = SERVICE_PAUSED; break; case SERVICE_CONTROL_CONTINUE: stehubServiceStatus.dwCurrentState = SERVICE_RUNNING; break; case SERVICE_CONTROL_STOP: stehubServiceStatus.dwWin32ExitCode = 0; stehubServiceStatus.dwCurrentState = SERVICE_STOPPED; stehubServiceStatus.dwCheckPoint = 0; stehubServiceStatus.dwWaitHint = 0; SetServiceStatus (stehubServiceStatusHandle,&stehubServiceStatus); break; case SERVICE_CONTROL_INTERROGATE: break; } return NO_ERROR; }
/* ==================== NET_IPSocket ==================== */ int NET_IPSocket(char *net_interface, int port, int *err) { SOCKET newsocket; struct sockaddr_in address; #ifdef __AROS__ char _true = 1; #else u_long _true = 1; #endif int i = 1; *err = 0; if (net_interface) { Com_Printf("Opening IP socket: %s:%i\n", net_interface, port); } else { Com_Printf("Opening IP socket: 0.0.0.0:%i\n", port); } if ((newsocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) { *err = socketError; Com_Printf("WARNING NET_IPSocket: socket: %s\n", NET_ErrorString()); return newsocket; } // make it non-blocking if (ioctlsocket(newsocket, FIONBIO, &_true) == SOCKET_ERROR) { Com_Printf("WARNING NET_IPSocket: ioctl FIONBIO: %s\n", NET_ErrorString()); *err = socketError; closesocket(newsocket); return INVALID_SOCKET; } // make it broadcast capable if (setsockopt(newsocket, SOL_SOCKET, SO_BROADCAST, (char *) &i, sizeof(i)) == SOCKET_ERROR) { Com_Printf("WARNING NET_IPSocket: setsockopt SO_BROADCAST: %s\n", NET_ErrorString()); } if (!net_interface || !net_interface[0]) { address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; } else { if (!Sys_StringToSockaddr(net_interface, (struct sockaddr *)&address, sizeof(address), AF_INET)) { closesocket(newsocket); return INVALID_SOCKET; } } if (port == PORT_ANY) { address.sin_port = 0; } else { address.sin_port = htons((short)port); } if (bind(newsocket, (void *)&address, sizeof(address)) == SOCKET_ERROR) { Com_Printf("WARNING NET_IPSocket: bind: %s\n", NET_ErrorString()); *err = socketError; closesocket(newsocket); return INVALID_SOCKET; } return newsocket; }
/* DWORD PALAPI Thread_Client(LPVOID lpParam) This is a client thread started by the main process. It simulate a client connecting to a remote server. */ void PALAPI Thread_Client(LPVOID lpParam) { int i; int err; struct sockaddr_in mySockaddr; /* Sockets descriptor */ const int numSockets = 1; /* number of sockets used in this test */ SOCKET testSockets[1]; /* Variables for WSASend */ WSABUF wsaSendBuf; DWORD dwNbrOfByteSent; DWORD dwNbrOfBuf = 1; DWORD dwSendFlags = 0; unsigned char sendBuffer[255]; int byteCounter; WSAOVERLAPPED wsaOverlapped; /* variable for iocltsocket */ u_long argp; /* Variables needed for select */ struct timeval waitTime; fd_set writeFds; int socketFds; HANDLE hWriteEvent; DWORD waitResult; threadExitCode=THREAD_UNDEFINED; /* Sockets initialization to INVALID_SOCKET */ for( i = 0; i < numSockets; i++ ) { testSockets[i] = INVALID_SOCKET; } /* create an overlapped stream socket in AF_INET domain */ testSockets[0] = WSASocketA( AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED ); if( testSockets[0] == INVALID_SOCKET ) { Trace("Client error: Unexpected failure: " "WSASocketA" "(AF_INET,SOCK_STREAM,IPPROTO_TCP,NULL,0,WSA_FLAG_OVERLAPPED) " " returned %u\n", GetLastError()); threadExitCode=THREAD_FAIL; ExitThread(0); } /* enable non blocking socket */ argp=1; err = ioctlsocket(testSockets[0], FIONBIO, (u_long FAR *)&argp); if (err==SOCKET_ERROR ) { Trace("ERROR: Unexpected failure: " "ioctlsocket(.., FIONBIO, ..) " "returned %u\n", GetLastError() ); /* Do some cleanup */ CloseSocket( testSockets, numSockets ); threadExitCode=THREAD_FAIL; ExitThread(0); } /* prepare the sockaddr_in structure */ mySockaddr.sin_family = AF_INET; mySockaddr.sin_port = getRotorTestPort(); mySockaddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); memset( &(mySockaddr.sin_zero), 0, 8); /* wait for the server to be prepared */ Sleep(1000); /* connect to a server */ err = connect( testSockets[0], (struct sockaddr *)&mySockaddr, sizeof(struct sockaddr)); if( err == SOCKET_ERROR ) { err = GetLastError(); if ( err != WSAEWOULDBLOCK ) { Trace("ERROR: Unexpected failure: " "connect() socket with local server " "returned %u, expected WSAEWOULDBLOCK\n", GetLastError()); /* Do some cleanup */ CloseSocket( testSockets, numSockets ); threadExitCode=THREAD_FAIL; ExitThread(0); } /* set the server waiting time as 10 seconds */ waitTime.tv_sec = 10L; waitTime.tv_usec = 0L; /* initialize the except socket set */ FD_ZERO( &writeFds ); /* add socket to readable socket set */ FD_SET( testSockets[0], &writeFds ); /* monitor the readable socket set to determine the completion of the connection request. */ socketFds = select( 0, NULL, &writeFds, NULL, &waitTime); if( socketFds == SOCKET_ERROR ) { Trace("ERROR: Unexpected failure " "with select\n"); /* Do some cleanup */ CloseSocket( testSockets, numSockets ); threadExitCode=THREAD_FAIL; ExitThread(0); } if( socketFds == 0 ) { Trace("ERROR: Unexpected select " "timed out\n"); /* Do some cleanup */ CloseSocket( testSockets, numSockets ); threadExitCode=THREAD_FAIL; ExitThread(0); } } /* create events */ hWriteEvent = CreateEvent( NULL, /* no security */ FALSE, /* reset type */ FALSE, /* initial state */ NULL ); /* object name */ if( hWriteEvent == NULL ) { Trace("Client error: Unexpected failure: " "CreateEvent() " "returned %u\n", GetLastError()); /* Do some cleanup */ CloseSocket( testSockets, numSockets ); threadExitCode=THREAD_FAIL; ExitThread(0); } /* fill the sent buffer with value */ for (i=0;i<255;i++) { sendBuffer[i]= i; } /* Set the WSABUF structure */ wsaSendBuf.len = 255; wsaSendBuf.buf = sendBuffer; byteCounter = 0; /* This loop send a 400 buffer to the server. It then shutdown the connection. */ for(i=0;i<500;i++) { /* Initialize the WSAOVERLAPPED to 0 */ memset(&wsaOverlapped, 0, sizeof(WSAOVERLAPPED)); wsaOverlapped.hEvent = hWriteEvent; /* Send some data */ err = WSASendTo( testSockets[0], &wsaSendBuf, dwNbrOfBuf, &dwNbrOfByteSent, dwSendFlags, (struct sockaddr*)NULL, /* ignored in TCP */ (int)NULL, /* ignored in TCP */ &wsaOverlapped, 0 ); if(err == SOCKET_ERROR ) { /* The server shutdown its socket after 400 wsarecv, it is impossible to have 401 or more successfull send operation */ err=GetLastError(); if(err==WSAECONNABORTED ||err==WSAESHUTDOWN ||err==WSAECONNRESET) { if (i<400) { if(err==WSAESHUTDOWN) { Trace("Unexpected WSAESHUTDOWN at send %d",i); } else if(err==WSAECONNABORTED) { Trace("Unexpected WSAECONNABORTED at send %d",i); } else if(err==WSAECONNRESET) { Trace("Unexpected WSAECONNRESET at send %d",i); } CloseEventHandle(hWriteEvent); /* Do some cleanup */ CloseSocket( testSockets, numSockets ); threadExitCode=THREAD_FAIL; ExitThread(0); } else { break; } } /* Handle the overlapped operation */ if(err!=WSA_IO_PENDING) { Trace("Client error: Unexpected failure: " "WSASend() " "returned %u\n", err); CloseEventHandle(hWriteEvent); /* Do some cleanup */ CloseSocket( testSockets, numSockets ); threadExitCode=THREAD_FAIL; ExitThread(0); } /* Wait 10 seconds for hWriteEvent to be signaled for pending operation */ waitResult = WaitForSingleObject( hWriteEvent, 10000 ); if (waitResult!=WAIT_OBJECT_0) { Trace("Client Error: Unexpected failure: " "WaitForSingleObject has timed out \n"); CloseEventHandle(hWriteEvent); /* Do some cleanup */ CloseSocket( testSockets, numSockets ); threadExitCode=THREAD_FAIL; ExitThread(0); } /* The server shutdown its socket after 400 wsarecv, it is impossible to have 401 or more successfull send operation */ if(wsaOverlapped.Internal==WSAECONNABORTED|| wsaOverlapped.Internal==WSAESHUTDOWN|| wsaOverlapped.Internal==WSAECONNRESET) { if (i<400) { if(err==WSAESHUTDOWN) { Trace("Unexpected WSAESHUTDOWN at send %d",i); } else if(err==WSAECONNABORTED) { Trace("Unexpected WSAECONNABORTED at send %d",i); } else if(err==WSAECONNRESET) { Trace("Unexpected WSAECONNRESET at send %d",i); } CloseEventHandle(hWriteEvent); /* Do some cleanup */ CloseSocket( testSockets, numSockets ); threadExitCode=THREAD_FAIL; ExitThread(0); } else { break; } } } else { /* Reset Event */ ResetEvent(hWriteEvent); } /* if wsaOverlapped.InternalHigh is 0, it means that connection has been closed */ if(wsaOverlapped.InternalHigh==0&&wsaOverlapped.Internal==0) { /* The server shutdown the receiving socket after 400 successfull receive. */ if (i<400) { Trace("Unexpected wsaOverlapped.InternalHigh = 0 " "at WSASend attempt #%d", i); CloseEventHandle(hWriteEvent); /* Do some cleanup */ CloseSocket( testSockets, numSockets ); threadExitCode=THREAD_FAIL; ExitThread(0); } /* the server shutdown the socket as expected */ break; } /* keep track of the number of bytes sent */ byteCounter += wsaOverlapped.InternalHigh; /* Verify that the number of bytes sent are the number of byte specified in the wsaBuf structure */ if(wsaSendBuf.len!=wsaOverlapped.InternalHigh) { Trace("Server error: Array out of bound " "while writing buffer received in myData.\n"); CloseEventHandle(hWriteEvent); /* Do some cleanup */ CloseSocket( testSockets, numSockets ); threadExitCode=THREAD_FAIL; ExitThread(0); } }/* end of for loop */ /* close the handle to hWriteEvent Do some cleanup */ if(!CloseEventHandle(hWriteEvent)|| !CloseSocket( testSockets, numSockets )) { threadExitCode=THREAD_FAIL; ExitThread(0); } threadExitCode=THREAD_SUCCESS; ExitThread(0); }
int tcpclient_open(urg_tcpclient_t* cli, const char* ip_str, int port_num) { enum { Connect_timeout_second = 2 }; fd_set rmask, wmask; struct timeval tv = { Connect_timeout_second, 0 }; #if defined(URG_WINDOWS_OS) u_long flag; #else int flag; int sock_optval = -1; int sock_optval_size = sizeof(sock_optval); #endif int ret; cli->sock_desc = Invalid_desc; cli->pushed_back = -1; // no pushed back char. #if defined(URG_WINDOWS_OS) { static int is_initialized = 0; WORD wVersionRequested = 0x0202; WSADATA WSAData; int err; if (!is_initialized) { err = WSAStartup(wVersionRequested, &WSAData); if (err != 0) { return -1; } is_initialized = 1; } } #endif tcpclient_buffer_init(cli); cli->sock_addr_size = sizeof (struct sockaddr_in); if ((cli->sock_desc = (int)socket(AF_INET, SOCK_STREAM, 0)) < 0) { return -1; } memset((char*)&(cli->server_addr), 0, sizeof(cli->sock_addr_size)); cli->server_addr.sin_family = AF_INET; cli->server_addr.sin_port = htons(port_num); if (!strcmp(ip_str, "localhost")) { ip_str = "127.0.0.1"; } /* bind is not required, and port number is dynamic */ if ((cli->server_addr.sin_addr.s_addr = inet_addr(ip_str)) == INADDR_NONE) { return -1; } #if defined(URG_WINDOWS_OS) //ノンブロックに変更 flag = 1; ioctlsocket(cli->sock_desc, FIONBIO, &flag); if (connect(cli->sock_desc, (const struct sockaddr *)&(cli->server_addr), cli->sock_addr_size) == SOCKET_ERROR) { int error_number = WSAGetLastError(); if (error_number != WSAEWOULDBLOCK) { tcpclient_close(cli); return -1; } FD_ZERO(&rmask); FD_SET((SOCKET)cli->sock_desc, &rmask); wmask = rmask; ret = select((int)cli->sock_desc + 1, &rmask, &wmask, NULL, &tv); if (ret == 0) { // タイムアウト tcpclient_close(cli); return -2; } } //ブロックモードにする set_block_mode(cli); #else //ノンブロックに変更 flag = fcntl(cli->sock_desc, F_GETFL, 0); fcntl(cli->sock_desc, F_SETFL, flag | O_NONBLOCK); if (connect(cli->sock_desc, (const struct sockaddr *)&(cli->server_addr), cli->sock_addr_size) < 0) { if (errno != EINPROGRESS) { tcpclient_close(cli); return -1; } // EINPROGRESS:コネクション要求は始まったが、まだ完了していない FD_ZERO(&rmask); FD_SET(cli->sock_desc, &rmask); wmask = rmask; ret = select(cli->sock_desc + 1, &rmask, &wmask, NULL, &tv); if (ret <= 0) { // タイムアウト処理 tcpclient_close(cli); return -2; } if (getsockopt(cli->sock_desc, SOL_SOCKET, SO_ERROR, (int*)&sock_optval, (socklen_t*)&sock_optval_size) != 0) { // 接続に失敗 tcpclient_close(cli); return -3; } if (sock_optval != 0) { // 接続に失敗 tcpclient_close(cli); return -4; } set_block_mode(cli); } #endif return 0; }
/** * main * * executable entry point */ INT __cdecl main(INT argc, CHAR **argv) { int i; int err; int addrlen = sizeof(struct sockaddr); struct sockaddr_in mySockaddr; WSADATA wsaData; HANDLE hReadEvent; DWORD waitResult; /* Thread variable */ HANDLE hThreadClient; DWORD dwThreadClient; DWORD dwClientParam[2]; /* Sockets descriptor */ const int numSockets = 2; /* number of sockets used in this test */ SOCKET testSockets[2]; /* variable for iocltsocket */ u_long argp; /* Variables needed for setsockopt */ BOOL bReuseAddr = TRUE; /* Variables needed for select */ struct timeval waitTime; fd_set readFds; int socketFds; /* Variables needed for WSARecv */ WSABUF wsaBuf; DWORD dwNbrOfBuf = 1; DWORD dwNbrOfByteSent; DWORD dwRecvFlags = 0; WSAOVERLAPPED wsaRecvOverlapped; /* Variable used to store transmitted data */ unsigned char myBuffer[255]; unsigned char myData[500][255]; unsigned char* pMyData; int bufferCounter; /* Socket DLL version */ const WORD wVersionRequested = MAKEWORD(2,2); /* Sockets initialization to INVALID_SOCKET */ for( i = 0; i < numSockets; i++ ) { testSockets[i] = INVALID_SOCKET; } /* PAL initialization */ if( PAL_Initialize(argc, argv) != 0 ) { return FAIL; } /* Initialize to use winsock2.dll */ err = WSAStartup( wVersionRequested, &wsaData); if(err != 0) { Fail( "Server error: Unexpected failure: " "WSAStartup(%d) " "returned %u\n", wVersionRequested, GetLastError() ); } /* Confirm that the WinSock DLL supports 2.2. Note that if the DLL supports versions greater than 2.2 in addition to 2.2, it will still return 2.2 in wVersion since that is the version we requested. */ if ( wsaData.wVersion != wVersionRequested ) { Trace("Server error: Unexpected failure " "to find a usable version of WinSock DLL\n"); /* Do some cleanup */ DoWSATestCleanup( 0, 0); Fail(""); } /* create an overlapped stream socket in AF_INET domain */ testSockets[0] = WSASocketA( AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED ); if( testSockets[0] == INVALID_SOCKET ) { Trace("Server error: Unexpected failure: " "WSASocketA" "(AF_INET,SOCK_STREAM,IPPROTO_TCP,NULL,0,WSA_FLAG_OVERLAPPED)) " " returned %u\n", GetLastError()); /* Do some cleanup */ DoWSATestCleanup( 0, 0); Fail(""); } /* Allows the socket to be bound to an address that is already in use. */ err = setsockopt( testSockets[0], SOL_SOCKET, SO_REUSEADDR, (const char *)&bReuseAddr, sizeof( BOOL ) ); if( err == SOCKET_ERROR ) { Trace("Server error: Unexpected failure: " "setsockopt(.., SOL_SOCKET,SO_REUSEADDR, ..) " "returned %u\n", GetLastError() ); /* Do some cleanup */ DoWSATestCleanup( testSockets, numSockets ); Fail(""); } /* enable non blocking socket */ argp=1; err = ioctlsocket(testSockets[0], FIONBIO, (u_long FAR *)&argp); if (err==SOCKET_ERROR ) { Trace("ERROR: Unexpected failure: " "ioctlsocket(.., FIONBIO, ..) " "returned %u\n", GetLastError() ); /* Do some cleanup */ DoWSATestCleanup( testSockets, numSockets ); Fail(""); } /* prepare the sockaddr structure */ mySockaddr.sin_family = AF_INET; mySockaddr.sin_port = getRotorTestPort(); mySockaddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); memset( &(mySockaddr.sin_zero), 0, 8); /* bind local address to a socket */ err = bind( testSockets[0], (struct sockaddr *)&mySockaddr, sizeof(struct sockaddr) ); if( err == SOCKET_ERROR ) { Trace("ERROR: Unexpected failure: " "bind() socket with local address " "returned %u\n", GetLastError() ); /* Do some cleanup */ DoWSATestCleanup( testSockets, numSockets ); Fail(""); } /* listen to the socket */ err = listen( testSockets[0], listenBacklog ); if( err == SOCKET_ERROR ) { Trace("ERROR: Unexpected failure: " "listen() to sockets " "returned %u\n", GetLastError() ); /* Do some cleanup */ DoWSATestCleanup( testSockets, numSockets ); Fail(""); } /* create a client thread */ hThreadClient = CreateThread( NULL, /* no security attributes */ 0, /* use default stack size */ (LPTHREAD_START_ROUTINE)Thread_Client,/* thread function */ (LPVOID)&dwClientParam, /* argument to thread function */ 0, /* use default creation flags */ &dwThreadClient); /* returns the thread identifier*/ if(hThreadClient==NULL) { Trace( "Server Error: Unexpected failure: " "CreateThread() " "returned NULL\n"); /* Do some cleanup */ DoWSATestCleanup( testSockets, numSockets ); Fail(""); } /* set the server waiting time as 10 seconds */ waitTime.tv_sec = 10L; waitTime.tv_usec = 0L; /* initialize the except socket set */ FD_ZERO( &readFds ); /* add socket to readable socket set */ FD_SET( testSockets[0], &readFds ); /* monitor the readable socket set to determine when a connection is ready to be accepted */ socketFds = select( 0, &readFds, NULL, NULL, &waitTime); if( socketFds == SOCKET_ERROR ) { Trace("ERROR: Unexpected failure " "with select\n"); WaitForClientThreadToFinish(hThreadClient); CloseThreadHandle(hThreadClient); /* Do some cleanup */ DoWSATestCleanup( testSockets, numSockets ); Fail(""); } if( socketFds == 0 ) { Trace("ERROR: Unexpected select " "timed out\n"); WaitForClientThreadToFinish(hThreadClient); CloseThreadHandle(hThreadClient); /* Do some cleanup */ DoWSATestCleanup( testSockets, numSockets ); Fail(""); } /* accept connection */ testSockets[1] = accept( testSockets[0], (struct sockaddr *)&mySockaddr, &addrlen ); if( testSockets[1] == INVALID_SOCKET ) { Trace("ERROR: Unexpected failure: " "accept() connection on socket " "returned %u\n", GetLastError()); WaitForClientThreadToFinish(hThreadClient); CloseThreadHandle(hThreadClient); /* Do some cleanup */ DoWSATestCleanup( testSockets, numSockets ); Fail(""); } /* enable non blocking socket */ argp=1; err = ioctlsocket(testSockets[1], FIONBIO, (u_long FAR *)&argp); if (err==SOCKET_ERROR ) { Trace("ERROR: Unexpected failure: " "ioctlsocket(.., FIONBIO, ..) " "returned %u\n", GetLastError() ); WaitForClientThreadToFinish(hThreadClient); CloseThreadHandle(hThreadClient); /* Do some cleanup */ DoWSATestCleanup( testSockets, numSockets ); Fail(""); } /* create an event */ hReadEvent = CreateEvent( NULL, /* no security */ FALSE, /* reset type */ FALSE, /* initial state */ NULL ); /* object name */ if( hReadEvent == NULL ) { Trace("Server error: Unexpected failure: " "CreateEvent() " "returned %u\n", GetLastError()); WaitForClientThreadToFinish(hThreadClient); CloseThreadHandle(hThreadClient); /* Do some cleanup */ DoWSATestCleanup( testSockets, numSockets ); Fail(""); } /* Initialize the WSABUF structure */ memset(myBuffer, 0, 255); wsaBuf.buf = myBuffer; wsaBuf.len = 255; bufferCounter = 0; pMyData = (unsigned char*)myData; /* this loop receives data sent from client after 400 recv, it shutdowns the connection to test how the client react. */ for(i=0;i<400;i++) { /* Initialize the WSAOVERLAPPED to 0 */ memset(&wsaRecvOverlapped, 0, sizeof(WSAOVERLAPPED)); /* Specify which event to signal when data is arrived*/ wsaRecvOverlapped.hEvent = hReadEvent; /* reset the buffer used by WSARecv */ memset(myBuffer, 0, 255); /* Prepare to receive data */ err = WSARecv( testSockets[1], &wsaBuf, dwNbrOfBuf, &dwNbrOfByteSent, &dwRecvFlags, &wsaRecvOverlapped, 0 ); if( err != SOCKET_ERROR ) { if(dwNbrOfByteSent==0) { Trace("Server error: WSARecv() " "returned 0 bytes\n"); WaitForClientThreadToFinish(hThreadClient); CloseThreadHandle(hThreadClient); CloseEventHandle(hReadEvent); /* Do some cleanup */ DoWSATestCleanup( testSockets, numSockets ); Fail(""); } /* Reset Event */ ResetEvent(hReadEvent); } else { err = GetLastError(); /* Only WSA_IO_PENDING is expected */ if(err!=WSA_IO_PENDING) { Trace("Server error: WSARecv() " "returned %u, expected WSA_IO_PENDING\n", GetLastError() ); WaitForClientThreadToFinish(hThreadClient); CloseThreadHandle(hThreadClient); CloseEventHandle(hReadEvent); /* Do some cleanup */ DoWSATestCleanup( testSockets, numSockets ); Fail(""); } /* Wait 10 seconds for ReadEvent to be signaled from the pending operation */ waitResult = WaitForSingleObject( hReadEvent, 10000 ); if (waitResult!=WAIT_OBJECT_0) { Trace("Server error: Unexpected failure: " "WaitForSingleObject has timed out \n"); WaitForClientThreadToFinish(hThreadClient); CloseThreadHandle(hThreadClient); CloseEventHandle(hReadEvent); /* Do some cleanup */ DoWSATestCleanup( testSockets, numSockets ); Fail(""); } } /* test if data can be copied to the current position in the receiving data array. */ if( pMyData+wsaRecvOverlapped.InternalHigh < &(myData[500][255]) ) { /* copy buffer to data array */ memcpy(pMyData,wsaBuf.buf,wsaRecvOverlapped.InternalHigh); /* increment the position where we can write data on the array*/ pMyData+=wsaRecvOverlapped.InternalHigh; } else { Trace("Server error: Array out of bound " "while writing buffer received in myData.\n"); WaitForClientThreadToFinish(hThreadClient); CloseThreadHandle(hThreadClient); CloseEventHandle(hReadEvent); /* Do some cleanup */ DoWSATestCleanup( testSockets, numSockets ); Fail(""); } /* Increment bufferCounter to keep track of the number of byte received */ bufferCounter += wsaRecvOverlapped.InternalHigh; } /* end of the for loop */ // Ensure that all the data is received before the sockets are closed Sleep(2000); /* Disconnect the socket */ err = shutdown( testSockets[1], SD_BOTH); if (err == SOCKET_ERROR) { Trace("ERROR: Unexpected failure: " "shutdown() socket with local server " "returned %u\n", GetLastError()); WaitForClientThreadToFinish(hThreadClient); CloseThreadHandle(hThreadClient); CloseEventHandle(hReadEvent); /* Do some cleanup */ DoWSATestCleanup( testSockets, numSockets ); Fail(""); } if(!WaitForClientThreadToFinish(hThreadClient)) { CloseThreadHandle(hThreadClient); CloseEventHandle(hReadEvent); /* Do some cleanup */ DoWSATestCleanup( testSockets, numSockets ); Fail(""); } if(!CloseThreadHandle(hThreadClient)|| !CloseEventHandle(hReadEvent)) { /* Do some cleanup */ DoWSATestCleanup( testSockets, numSockets ); Fail(""); } /* verify that all data in the data array are as expected */ pMyData=(unsigned char*)myData; for(i=0;i<bufferCounter;i++) { if(*pMyData!=(i%255)) { Trace("Error comparing received data at position %d" " in data array",i); /* Do some cleanup */ DoWSATestCleanup( testSockets, numSockets ); Fail(""); } pMyData++; } /* Do some cleanup */ DoWSATestCleanup( testSockets, numSockets ); PAL_Terminate(); return PASS; }
float receive(){ //GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Threado Starto")); UE_LOG(YourLog, Log, TEXT("Threado Starto")); //while (true){ // if (killThread) return 0; //killThread = true; //} //while (true){ GEngine->AddOnScreenDebugMessage(2, 5.f, FColor::Red, TEXT("tick")); } SOCKET sd; unsigned short int port = 5555; struct sockaddr_in server, client; WSADATA wsaData; /* Open windows connection */ if (WSAStartup(0x0101, &wsaData) != 0)//variable w is a structure of WSADATA form. { GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Blue, TEXT("Could not open Windows connection")); fprintf(stderr, "Could not open Windows connection.\n"); UE_LOG(YourLog, Fatal, TEXT("Could not open Windows connection.\n")); return 1; } /* Open a datagram socket */ sd = socket(AF_INET, SOCK_DGRAM, 0); if (sd == INVALID_SOCKET) { GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Blue, TEXT("Could not create socket")); fprintf(stderr, "Could not create socket.\n"); UE_LOG(YourLog, Fatal, TEXT("Could not create socket.\n")); WSACleanup(); return 2; } //non blocking stuff I think u_long iMode = 1; ioctlsocket(sd, FIONBIO, &iMode); /* Clear out server struct */ memset((void *)&server, '\0', sizeof(struct sockaddr_in)); /* Set family and port */ server.sin_family = AF_INET; server.sin_port = htons(port); /* Set address automatically if desired */ /* automatically get host name of this computer */ //int errorCode; char host_name[256]; gethostname(host_name, sizeof(host_name)); hostent *hp = gethostbyname(host_name); /* Check for NULL pointer */ if (hp != NULL) { /* Assign the address */ unsigned int a, b, c, d; server.sin_addr.S_un.S_un_b.s_b1 = a = hp->h_addr_list[0][0]; server.sin_addr.S_un.S_un_b.s_b2 = b = hp->h_addr_list[0][1]; server.sin_addr.S_un.S_un_b.s_b3 = c = hp->h_addr_list[0][2]; server.sin_addr.S_un.S_un_b.s_b4 = d = hp->h_addr_list[0][3]; FString Fs = FString(ANSI_TO_TCHAR(host_name)); GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, Fs); std::cout << "Hostname: " << host_name << " " << ((int)hp->h_addr_list[0][0] & 0x256) << "." << (unsigned int)hp->h_addr_list[0][1] << "." << (unsigned int)hp->h_addr_list[0][2] << "." << (unsigned int)hp->h_addr_list[0][3] << std::endl; GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, Fs); UE_LOG(YourLog, Warning, TEXT("found address: %d.%d.%d.%d"), a, b, c, d); } /* hardcoded address as backup */ else { fprintf(stderr, "Failed to discover hostname. Defaulted to 192.168.1.107. \n"); UE_LOG(YourLog, Log, TEXT("Failed to discover hostname. Defaulted to 192.168.1.104. \n")); server.sin_addr.S_un.S_un_b.s_b1 = (unsigned char)192; server.sin_addr.S_un.S_un_b.s_b2 = (unsigned char)168; server.sin_addr.S_un.S_un_b.s_b3 = (unsigned char)1; server.sin_addr.S_un.S_un_b.s_b4 = (unsigned char)104; } //doesn't crash when stalled here, bind seems to be the tricky part UE_LOG(YourLog, Log, TEXT("about to bind")); /* Bind address to socket */ if (bind(sd, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) == -1) { int errnum = -1; errnum = WSAGetLastError(); //GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Blue, TEXT("Could not bind address to socket")); fprintf(stderr, "Could not bind address to socket.\n"); //UE_LOG(YourLog, Warning, TEXT("tryibng to print message")); //UE_LOG(YourLog, Warning, TEXT("Could not bind address to socket due to %d.\n"), errnum);//Seems like Fatal logging triggers a breakpoint UE_LOG(YourLog, Fatal, TEXT("Could not bind address to socket due to %d.\n"), errnum);//Fatal rather than warning maybe closesocket(sd); WSACleanup(); return errnum; } int client_length = (int)sizeof(struct sockaddr_in); int bytes_received; /*while (true){ Sleep(50); if (killThread == true) { //closeConnection(sd); fprintf(stderr, "KillThread: ending server for FreePIE.\n"); UE_LOG(YourLog, Warning, TEXT("KillThread: ending server for FreePIE.\n")); closesocket(sd); WSACleanup(); return 0; } }*/ //FString path = FPaths::GameDir() + "/DataLog/log.txt"; time_t timeStamp = time(0); char* timeString = std::ctime(&timeStamp); struct tm * timeinfo; timeinfo = localtime(&timeStamp); char buffer[80]; //strftime(buffer, 200, "%S-%M-%H_%a-%b-%G", timeinfo); strftime(buffer, 200, "%S-%M-%H_%d-%b-%Y", timeinfo); //FString path = FPaths::GameDir() + "/DataLog/" + buffer + ".csv"; userID = FString::FromInt(time(0)); FString path = FPaths::GameDir() + "/DataLog/" + userID + "A" +".csv"; DataLogFile.open(*path, std::ios::out); DataLogFile << "acceleration:x,y,z,Orientation:yaw,pitch,roll,PredGravityX,PredGravityY,PredGravityZ\n"; while (true){ //GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, TEXT("reading")); //UE_LOG(YourLog, Warning, TEXT("KillThread is %d"), killThread); if (killThread == true) { fprintf(stderr, "KillThread: ending server for FreePIE.\n"); DataLogFile.close(); if (!recording) std::remove(TCHAR_TO_ANSI(*path));//if recording was never started delete record file //UE_LOG(YourLog, Warning, TEXT("KillThread: ending server for FreePIE.\n"));//this will break because if killthread then game is closing closesocket(sd); WSACleanup(); return 5555; } //} //std::cout << "Reading a datagram" << std::endl; //GEngine->AddOnScreenDebugMessage(1, 5.f, FColor::Black, TEXT("about to read")); //GEngine-> /* Receive bytes from client */ bytes_received = recvfrom(sd, UDPReceiveBuffer, BUFFER_SIZE, 0, (struct sockaddr *)&client, &client_length); /*if (bytes_received < 0) { //while (true){ GEngine->AddOnScreenDebugMessage(2, 5.f, FColor::Black, TEXT("Failed to receive datagram")); //} fprintf(stderr, "Could not receive datagram.\n"); closesocket(sd); WSACleanup(); //pollingThread.~thread(); //ExitThread(0); return 4444; }*/ int nError = WSAGetLastError(); if (nError != WSAEWOULDBLOCK&&nError != 0) { UE_LOG(YourLog, Log, TEXT("Winsock error code\r\n")); std::cout << "Winsock error code: " << nError << "\r\n"; std::cout << "Server disconnected!\r\n"; return 9000; } else if (bytes_received > 0) parseDatagram((char*)UDPReceiveBuffer); //std::cout << (int)client.sin_addr.S_un.S_un_b.s_b1 << '.' << (int)client.sin_addr.S_un.S_un_b.s_b2 << '.' << (int)client.sin_addr.S_un.S_un_b.s_b3 << '.' << (int)client.sin_addr.S_un.S_un_b.s_b4 << std::endl; //fprintf(stderr, buffer); //GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, TEXT("sleeping")); Sleep(3); } return 2; }
int http_async_req_status(void *ctx) { struct http_ctx *cx = ctx; char *dns,*srv,buf[CHUNK]; int tmp, i; time_t now = time(NULL); #ifdef WIN32 unsigned long tmp2; #endif switch (cx->state) { case HTS_STRT: dns = getserv(cx->host); srv = getport(cx->host); if (resolve(dns, srv, &cx->addr)) { free(dns); free(srv); cx->state = HTS_DONE; cx->ret = 602; return 1; } free(dns); free(srv); cx->state = HTS_RSLV; return 0; case HTS_RSLV: cx->state = HTS_CONN; cx->last = now; return 0; case HTS_CONN: if (cx->fd == PERROR) { cx->fd = socket(AF_INET, SOCK_STREAM, 0); if (cx->fd == PERROR) goto fail; cx->fdhost = mystrdup(cx->host); #ifdef WIN32 tmp2 = 1; if (ioctlsocket(cx->fd, FIONBIO, &tmp2) == SOCKET_ERROR) goto fail; #else tmp = fcntl(cx->fd, F_GETFL); if (tmp < 0) goto fail; if (fcntl(cx->fd, F_SETFL, tmp|O_NONBLOCK) < 0) goto fail; #endif } if (!connect(cx->fd, (struct sockaddr *)&cx->addr, sizeof(cx->addr))) cx->state = HTS_IDLE; #ifdef WIN32 else if (PERRNO==WSAEISCONN) cx->state = HTS_IDLE; #endif #ifdef MACOSX else if (PERRNO==EISCONN) cx->state = HTS_IDLE; #endif else if (PERRNO!=PEINPROGRESS && PERRNO!=PEALREADY #ifdef WIN32 && PERRNO!=PEAGAIN && PERRNO!=WSAEINVAL #endif ) goto fail; if (now-cx->last>http_timeout) goto timeout; return 0; case HTS_IDLE: if (cx->txdl) { // generate POST cx->tbuf = malloc(strlen(cx->host) + strlen(cx->path) + 121 + cx->txdl + cx->thlen); cx->tptr = 0; cx->tlen = 0; cx->tlen += sprintf(cx->tbuf+cx->tlen, "POST %s HTTP/1.1\n", cx->path); cx->tlen += sprintf(cx->tbuf+cx->tlen, "Host: %s\n", cx->host); if (!cx->keep) cx->tlen += sprintf(cx->tbuf+cx->tlen, "Connection: close\n"); if (cx->thdr) { memcpy(cx->tbuf+cx->tlen, cx->thdr, cx->thlen); cx->tlen += cx->thlen; free(cx->thdr); cx->thdr = NULL; cx->thlen = 0; } cx->tlen += sprintf(cx->tbuf+cx->tlen, "Content-Length: %d\n", cx->txdl); #ifdef BETA cx->tlen += sprintf(cx->tbuf+cx->tlen, "X-Powder-Version: %s%dB%d\n", IDENT_VERSION, SAVE_VERSION, MINOR_VERSION); #else cx->tlen += sprintf(cx->tbuf+cx->tlen, "X-Powder-Version: %s%dS%d\n", IDENT_VERSION, SAVE_VERSION, MINOR_VERSION); #endif cx->tlen += sprintf(cx->tbuf+cx->tlen, "\n"); memcpy(cx->tbuf+cx->tlen, cx->txd, cx->txdl); cx->tlen += cx->txdl; free(cx->txd); cx->txd = NULL; cx->txdl = 0; } else { // generate GET cx->tbuf = malloc(strlen(cx->host) + strlen(cx->path) + 89 + cx->thlen); cx->tptr = 0; cx->tlen = 0; cx->tlen += sprintf(cx->tbuf+cx->tlen, "GET %s HTTP/1.1\n", cx->path); cx->tlen += sprintf(cx->tbuf+cx->tlen, "Host: %s\n", cx->host); if (cx->thdr) { memcpy(cx->tbuf+cx->tlen, cx->thdr, cx->thlen); cx->tlen += cx->thlen; free(cx->thdr); cx->thdr = NULL; cx->thlen = 0; } if (!cx->keep) cx->tlen += sprintf(cx->tbuf+cx->tlen, "Connection: close\n"); #ifdef BETA cx->tlen += sprintf(cx->tbuf+cx->tlen, "X-Powder-Version: %s%dB%d\n", IDENT_VERSION, SAVE_VERSION, MINOR_VERSION); #else cx->tlen += sprintf(cx->tbuf+cx->tlen, "X-Powder-Version: %s%dS%d\n", IDENT_VERSION, SAVE_VERSION, MINOR_VERSION); #endif cx->tlen += sprintf(cx->tbuf+cx->tlen, "\n"); } cx->state = HTS_XMIT; cx->last = now; return 0; case HTS_XMIT: tmp = send(cx->fd, cx->tbuf+cx->tptr, cx->tlen-cx->tptr, 0); if (tmp==PERROR && PERRNO!=PEAGAIN && PERRNO!=PEINTR) goto fail; if (tmp!=PERROR) { cx->tptr += tmp; if (cx->tptr == cx->tlen) { cx->tptr = 0; cx->tlen = 0; if (cx->tbuf) free(cx->tbuf); cx->state = HTS_RECV; } cx->last = now; } if (now-cx->last>http_timeout) goto timeout; return 0; case HTS_RECV: tmp = recv(cx->fd, buf, CHUNK, 0); if (tmp==PERROR && PERRNO!=PEAGAIN && PERRNO!=PEINTR) goto fail; if (tmp!=PERROR) { for (i=0; i<tmp; i++) { process_byte(cx, buf[i]); if (cx->state == HTS_DONE) return 1; } cx->last = now; } if (now-cx->last>http_timeout) goto timeout; return 0; case HTS_DONE: return 1; } return 0; fail: cx->ret = 600; cx->state = HTS_DONE; return 1; timeout: cx->ret = 605; cx->state = HTS_DONE; return 1; }
/* * send_to_kdc() sends a message to the Kerberos authentication * server(s) in the given realm and returns the reply message. * The "pkt" argument points to the message to be sent to Kerberos; * the "rpkt" argument will be filled in with Kerberos' reply. * The "realm" argument indicates the realm of the Kerberos server(s) * to transact with. If the realm is null, the local realm is used. * * If more than one Kerberos server is known for a given realm, * different servers will be queried until one of them replies. * Several attempts (retries) are made for each server before * giving up entirely. * * If an answer was received from a Kerberos host, KSUCCESS is * returned. The following errors can be returned: * * SKDC_CANT - can't get local realm * - can't find "kerberos" in /etc/services database * - can't open socket * - can't bind socket * - all ports in use * - couldn't find any Kerberos host * * SKDC_RETRY - couldn't get an answer from any Kerberos server, * after several retries */ int send_to_kdc( KTEXT pkt, KTEXT rpkt, char *realm ) { int i; SOCKET f = INVALID_SOCKET; int no_host; /* was a kerberos host found? */ int retry; int n_hosts; int retval; struct sockaddr_in to; struct hostent *host, *hostlist, *fphost, *temp_hostlist; int *portlist, *temp_portlist; char *cp; char krbhst[MAX_HSTNM]; char lrealm[REALM_SZ]; hostlist = 0; portlist = 0; /* * If "realm" is non-null, use that, otherwise get the * local realm. */ if (realm && realm[0]) { strncpy(lrealm, realm, REALM_SZ); lrealm[REALM_SZ] = 0; } else if (krb_get_lrealm(lrealm, 1)) { if (krb_debug) kdebug("%s: can't get local realm\n", prog); return(SKDC_CANT); } if (krb_debug) kdebug("lrealm is %s\n", lrealm); if (krb_udp_port_conf == 0) { register struct servent FAR *sp; if (sp = getservbyname("kerberos", "udp")) { krb_udp_port_conf = sp->s_port; } else if (KRB_PORT) { if (krb_debug) kdebug("%s: Can't get kerberos/udp service -- " "using default port\n", prog); krb_udp_port_conf = htons(KRB_PORT); } else { if (krb_debug) kdebug("%s: Can't get kerberos/udp service at all\n", prog); return(SKDC_CANT); } if (krb_debug) kdebug("krb_udp_port_conf is %d\n", ntohs(krb_udp_port_conf)); } /* from now on, exit through rtn label for cleanup */ memset((char *)&to, 0, S_AD_SZ); hostlist = (struct hostent *) malloc(sizeof(struct hostent)); if (!hostlist) { retval = SKDC_CANT; goto rtn; } memset(hostlist, 0, sizeof(struct hostent)); f = socket(AF_INET, SOCK_DGRAM, 0); if (f == INVALID_SOCKET) { if (krb_debug) kdebug("%s: Can't open socket (error %d)\n", prog, WSAGetLastError()); retval = SKDC_CANT; goto rtn; } /* make the socket non-blocking */ { u_long onOff = TRUE; if (ioctlsocket(f, FIONBIO, (u_long FAR*)&onOff)) { if (krb_debug) kdebug("%s: Can't make socket non-blocking (error %d)\n", prog, WSAGetLastError()); retval = SKDC_CANT; goto rtn; } } /* ** FTP Software's WINSOCK implmentation insists that ** a socket be bound before it can receive datagrams. ** This is outside specs. Since it shouldn't hurt any ** other implementations we'll go ahead and do it for ** now. */ { struct sockaddr_in from; memset ((char *)&from, 0, S_AD_SZ); from.sin_family = AF_INET; from.sin_addr.s_addr = INADDR_ANY; if ( bind(f, (struct sockaddr *)&from, S_AD_SZ) == SOCKET_ERROR ) { if (krb_debug) kdebug("%s : Can't bind\n", prog); retval = SKDC_CANT; goto rtn; } } /* End of kludge for FTP Software WinSock stack. */ no_host = 1; /* get an initial allocation */ n_hosts = 0; for (i = 1; krb_get_krbhst(krbhst, lrealm, i) == KSUCCESS; ++i) { #ifdef USE_DNS int krb_udp_port = krb_udp_port_dns?krb_udp_port_dns:krb_udp_port_conf; if (krb_debug) { kdebug("krb_udp_port is %d\n", ntohs(krb_udp_port)); } #else /* !USE_DNS */ int krb_udp_port = krb_udp_port_conf; #endif /* !USE_DNS */ if (krb_debug) { kdebug("Getting host entry for %s...", krbhst); } fphost = /* host = */ GETHOSTBYNAME(krbhst); if (krb_debug) { kdebug("%s.\n", fphost ? "Got it" : "Didn't get it"); } if (!fphost){ continue; } no_host = 0; /* found at least one */ n_hosts++; /* preserve host network address to check later * (would be better to preserve *all* addresses, * take care of that later) */ temp_portlist = portlist; portlist = (int *) realloc(portlist, n_hosts*sizeof(int)); if (!portlist) { portlist = temp_portlist; retval = SKDC_CANT; goto rtn; } portlist[n_hosts-1] = krb_udp_port; temp_hostlist = hostlist; hostlist = (struct hostent *) realloc((char *)hostlist, (unsigned) sizeof(struct hostent)*(n_hosts+1)); if (!hostlist){ hostlist = temp_hostlist; retval = SKDC_CANT; goto rtn; } hostlist[n_hosts-1] = *fphost; memset(&hostlist[n_hosts], 0, sizeof(struct hostent)); host = &hostlist[n_hosts-1]; cp = (char*)malloc((unsigned)host->h_length); if (!cp) { retval = SKDC_CANT; goto rtn; } memcpy(cp, host->h_addr, host->h_length); host->h_addr_list = (char **)malloc(sizeof(char *)); if (!host->h_addr_list) { retval = SKDC_CANT; goto rtn; } host->h_addr = cp; to.sin_family = host->h_addrtype; memcpy((char *)&to.sin_addr, host->h_addr, host->h_length); to.sin_port = krb_udp_port; if (send_recv(pkt, rpkt, f, &to, hostlist)) { retval = KSUCCESS; goto rtn; } if (krb_debug) { kdebug("Timeout, error, or wrong descriptor\n"); } } if (no_host) { if (krb_debug) kdebug("%s: can't find any Kerberos host.\n", prog); retval = SKDC_CANT; goto rtn; } /* retry each host in sequence */ for (retry = 0; retry < CLIENT_KRB_RETRY; ++retry) { i = 0; for (host = hostlist; host->h_name != 0; host++) { to.sin_family = host->h_addrtype; to.sin_port = portlist[i++]; memcpy((char *)&to.sin_addr, host->h_addr, host->h_length); if (send_recv(pkt, rpkt, f, &to, hostlist)) { retval = KSUCCESS; goto rtn; } } } retval = SKDC_RETRY; rtn: if (f != INVALID_SOCKET) if (closesocket(f) == SOCKET_ERROR) if (krb_debug) kdebug("%s: Could not close socket (error %d)\n", prog, WSAGetLastError()); if (hostlist) { register struct hostent *hp; for (hp = hostlist; hp->h_name; hp++) if (hp->h_addr_list) { if (hp->h_addr) free(hp->h_addr); free(hp->h_addr_list); } free(hostlist); } if (portlist) free(portlist); return(retval); }
/** * Do all socket creation and initialization */ void create_sockets(void) { struct addrinfo ai_hints, *ai_rval; int family, rval, fdflag, i; #if (defined IPV6_RECVTCLASS || defined IP_RECVTCLASS || defined IP_RECVTOS) &&\ !(defined WINDOWS && _WIN32_WINNT < _WIN32_WINNT_LONGHORN) int tosflag; #endif family = AF_INET; for (i = 0; i < pub_multi_count; i++) { if (pub_multi[i].ss.ss_family == AF_INET6) { family = AF_INET6; break; } } if ((listener = socket(family, SOCK_DGRAM, 0)) == INVALID_SOCKET) { sockerror(0, 0, 0, "Error creating socket for listener"); exit(ERR_SOCKET); } #if (defined WINDOWS && _WIN32_WINNT >= _WIN32_WINNT_LONGHORN) ||\ (!defined WINDOWS && !defined NO_DUAL) if (family == AF_INET6) { int v6flag = 0; if (setsockopt(listener, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&v6flag, sizeof(v6flag)) == SOCKET_ERROR) { sockerror(0, 0, 0, "Error setting v6only"); closesocket(listener); exit(ERR_SOCKET); } } #endif memset(&ai_hints, 0, sizeof(ai_hints)); ai_hints.ai_family = family; ai_hints.ai_socktype = SOCK_DGRAM; ai_hints.ai_protocol = 0; ai_hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV; if ((rval = getaddrinfo(NULL, portname, &ai_hints, &ai_rval)) != 0) { log0(0, 0, 0, "Error getting bind address: %s", gai_strerror(rval)); exit(ERR_SOCKET); } if (bind(listener, ai_rval->ai_addr, ai_rval->ai_addrlen) == SOCKET_ERROR) { sockerror(0, 0, 0, "Error binding socket for listener"); closesocket(listener); exit(ERR_SOCKET); } freeaddrinfo(ai_rval); #ifdef WINDOWS fdflag = 1; if (ioctlsocket(listener, FIONBIO, &fdflag) == SOCKET_ERROR) { sockerror(0, 0, 0, "Error setting non-blocking option"); closesocket(listener); exit(ERR_SOCKET); } #else if ((fdflag = fcntl(listener, F_GETFL)) == SOCKET_ERROR) { sockerror(0, 0, 0, "Error getting socket descriptor flags"); closesocket(listener); exit(ERR_SOCKET); } fdflag |= O_NONBLOCK; if (fcntl(listener, F_SETFL, fdflag) == SOCKET_ERROR) { sockerror(0, 0, 0, "Error setting non-blocking option"); closesocket(listener); exit(ERR_SOCKET); } #endif if (family == AF_INET6) { #if defined IPV6_TCLASS && !defined WINDOWS if (setsockopt(listener, IPPROTO_IPV6, IPV6_TCLASS, (char *)&dscp, sizeof(dscp)) == SOCKET_ERROR) { sockerror(0, 0, 0, "Error setting dscp"); closesocket(listener); exit(ERR_SOCKET); } #endif #ifdef IPV6_RECVTCLASS #if !(defined WINDOWS && _WIN32_WINNT < _WIN32_WINNT_LONGHORN) tosflag = 1; if (setsockopt(listener, IPPROTO_IPV6, IPV6_RECVTCLASS, (char *)&tosflag, sizeof(tosflag)) == SOCKET_ERROR) { sockerror(0, 0, 0, "Error setting recv tos"); closesocket(listener); exit(ERR_SOCKET); } #endif #endif #ifdef IPV6_MTU_DISCOVER { int mtuflag = IP_PMTUDISC_DONT; if (setsockopt(listener, IPPROTO_IPV6, IPV6_MTU_DISCOVER, (char *)&mtuflag, sizeof(mtuflag)) == SOCKET_ERROR) { sockerror(0, 0, 0, "Error disabling MTU discovery"); closesocket(listener); exit(ERR_SOCKET); } } #endif } #if (defined WINDOWS && _WIN32_WINNT < _WIN32_WINNT_LONGHORN) ||\ (defined NO_DUAL) if (family == AF_INET) { #endif if (setsockopt(listener, IPPROTO_IP, IP_TOS, (char *)&dscp, sizeof(dscp)) == SOCKET_ERROR) { sockerror(0, 0, 0, "Error setting dscp"); closesocket(listener); exit(ERR_SOCKET); } #ifdef IP_RECVTCLASS #if !(defined WINDOWS && _WIN32_WINNT < _WIN32_WINNT_LONGHORN) tosflag = 1; if (setsockopt(listener, IPPROTO_IP, IP_RECVTCLASS, (char *)&tosflag, sizeof(tosflag)) == SOCKET_ERROR) { sockerror(0, 0, 0, "Error setting recv tos"); closesocket(listener); exit(ERR_SOCKET); } #endif #elif defined IP_RECVTOS tosflag = 1; if (setsockopt(listener, IPPROTO_IP, IP_RECVTOS, (char *)&tosflag, sizeof(tosflag)) == SOCKET_ERROR) { sockerror(0, 0, 0, "Error setting recv tos"); closesocket(listener); exit(ERR_SOCKET); } #endif #ifdef IP_MTU_DISCOVER { int mtuflag = IP_PMTUDISC_DONT; if (setsockopt(listener, IPPROTO_IP, IP_MTU_DISCOVER, (char *)&mtuflag, sizeof(mtuflag)) == SOCKET_ERROR) { sockerror(0, 0, 0, "Error disabling MTU discovery"); closesocket(listener); exit(ERR_SOCKET); } } #endif #if (defined WINDOWS && _WIN32_WINNT < _WIN32_WINNT_LONGHORN) ||\ (defined NO_DUAL) } #endif if (rcvbuf) { if (setsockopt(listener, SOL_SOCKET, SO_RCVBUF, (char *)&rcvbuf, sizeof(rcvbuf)) == SOCKET_ERROR) { sockerror(0, 0, 0, "Error setting receive buffer size"); exit(ERR_SOCKET); } } else { rcvbuf = DEF_RCVBUF; if (setsockopt(listener, SOL_SOCKET, SO_RCVBUF, (char *)&rcvbuf, sizeof(rcvbuf)) == SOCKET_ERROR) { rcvbuf = DEF_BSD_RCVBUF; if (setsockopt(listener, SOL_SOCKET, SO_RCVBUF, (char *)&rcvbuf, sizeof(rcvbuf)) == SOCKET_ERROR) { sockerror(0, 0, 0, "Error setting receive buffer size"); exit(ERR_SOCKET); } } } for (i = 0; i < pub_multi_count; i++) { if (server_count > 0) { log3(0, 0, 0, "joining ssm for server IPs"); if (!multicast_join(listener, 0, &pub_multi[i], m_interface, interface_count, server_keys, server_count)) { exit(ERR_SOCKET); } if (has_proxy) { log3(0, 0, 0, "joining ssm for proxy IPs"); if (!multicast_join(listener, 0, &pub_multi[i], m_interface, interface_count, &proxy_info, 1)) { exit(ERR_SOCKET); } } } else { if (!multicast_join(listener, 0, &pub_multi[i], m_interface, interface_count, NULL, 0)) { exit(ERR_SOCKET); } } } }