Example #1
0
// ---------------- 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);
}
Example #2
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;

					}

				}

			}

		}

	}

}
Example #3
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;
}
Example #4
0
/**
 * @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);
	}
}
Example #5
0
/*
====================
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;
}
Example #6
0
//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.");
	}
}
Example #8
0
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, &notmoved, &notremoved);
                }
            }
        }
        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;
}
Example #10
0
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);
}
Example #11
0
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;
		}
	}
}
Example #12
0
File: Rsock.c Project: kmillar/rho
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); */
}
Example #13
0
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;
}
Example #14
0
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;
}
Example #15
0
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;
}
Example #16
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
		}
	}
Example #17
0
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;
}
Example #18
0
/*
========================
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;
}
Example #19
0
/*..........................................................................*/
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);
}
Example #21
0
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, &notblock);
#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;
}
Example #22
0
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, &param) < 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, &param) < 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;
}
Example #23
0
/*
====================
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;
}
Example #24
0
/* 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;
}
Example #26
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;
}
Example #27
0
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;
}
Example #28
0
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;
}
Example #29
0
/*
 * 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);
}
Example #30
0
/**
 * 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);
            }
        }
    }
}