void ILibAsyncServerSocket_PreSelect(void * socketModule, void *readset, void *writeset, void *errorset, int* blocktime)
{
    struct ILibAsyncServerSocketModule *module = (struct ILibAsyncServerSocketModule*)socketModule;
    int flags, i;

    // 没有开始监听
    if (module->listening == 0) {
        // Set the socket to non-block mode, so we can play nice and share the thread
#ifdef _WIN32_WCE
        flags = 1;
        ioctlsocket(module->ListenSocket,FIONBIO,&flags);
#elif WIN32
        flags = 1;
        ioctlsocket(module->ListenSocket, FIONBIO, &flags);
#elif _POSIX
        flags = fcntl(module->ListenSocket,F_GETFL,0);
        fcntl(module->ListenSocket,F_SETFL,O_NONBLOCK|flags);
#endif

        // Put the socket in Listen, and add it to the fdset for the Select loop
        module->listening = 1;
        listen(module->ListenSocket, 4);
        FD_SET(module->ListenSocket, (fd_set*)readset);
    } else {
        // Only put the ListenSocket in the readset, if we are able to handle a new socket
        for (i = 0; i < module->MaxConnection; ++i) {
            if (ILibAsyncSocket_IsFree(module->AsyncSockets[i]) != 0) {
                FD_SET(module->ListenSocket, (fd_set*)readset);
                break;
            }
        }
    }
}
void ILibAsyncServerSocket_PreSelect(void* socketModule,fd_set *readset, fd_set *writeset, fd_set *errorset, int* blocktime)
{
	struct AsyncServerSocketModule *module = (struct AsyncServerSocketModule*)socketModule;
	int flags,i;

	if(module->listening==0)
	{
		#ifdef _WIN32_WCE
			flags = 1;
			ioctlsocket(module->ListenSocket,FIONBIO,&flags);
		#elif WIN32
			flags = 1;
			ioctlsocket(module->ListenSocket,FIONBIO,&flags);
		#elif _POSIX
			flags = fcntl(module->ListenSocket,F_GETFL,0);
			fcntl(module->ListenSocket,F_SETFL,O_NONBLOCK|flags);
		#endif
		
		module->listening=1;
		listen(module->ListenSocket,4);
		FD_SET(module->ListenSocket,readset);
	}
	else
	{
		// Only put the ListenSocket in the readset, if we are able to handle a new socket
		for(i=0;i<module->MaxConnection;++i)
		{
			if(ILibAsyncSocket_IsFree(module->AsyncSockets[i])!=0)
			{
				FD_SET(module->ListenSocket,readset);
				break;
			}
		}
	}
}
void ILibWebServer_IdleSink(void *object)
{
	struct ILibWebServer_Session *session = (struct ILibWebServer_Session*)object;
	if(ILibAsyncSocket_IsFree(session->Reserved2)==0)
	{
		ILibAsyncServerSocket_Disconnect(session->Reserved1,session->Reserved2);
	}
}
void ILibAsyncServerSocket_PostSelect(void* socketModule,int slct, fd_set *readset, fd_set *writeset, fd_set *errorset)
{
	struct AsyncServerSocket_Data *data;
	struct sockaddr_in addr;
	int addrlen;
	struct AsyncServerSocketModule *module = (struct AsyncServerSocketModule*)socketModule;
	int i,flags;
	#ifdef _WIN32_WCE
		SOCKET NewSocket;
	#elif WIN32
		SOCKET NewSocket;
	#elif _POSIX
		int NewSocket;
	#endif

	if(FD_ISSET(module->ListenSocket,readset)!=0)
	{
		for(i=0;i<module->MaxConnection;++i)
		{
			if(ILibAsyncSocket_IsFree(module->AsyncSockets[i])!=0)
			{
				addrlen = sizeof(addr);
				NewSocket = accept(module->ListenSocket,(struct sockaddr*)&addr,&addrlen);
				if (NewSocket != ~0)
				{
					#ifdef _WIN32_WCE
						flags = 1;
						ioctlsocket(NewSocket,FIONBIO,&flags);
					#elif WIN32
						flags = 1;
						ioctlsocket(NewSocket,FIONBIO,&flags);
					#elif _POSIX
						flags = fcntl(NewSocket,F_GETFL,0);
						fcntl(NewSocket,F_SETFL,O_NONBLOCK|flags);
					#endif
					data = (struct AsyncServerSocket_Data*)MALLOC(sizeof(struct AsyncServerSocket_Data));
					data->module = socketModule;
					data->user = NULL;

					ILibAsyncSocket_UseThisSocket(module->AsyncSockets[i],&NewSocket,&ILibAsyncServerSocket_OnInterrupt,data);
					ILibAsyncSocket_SetRemoteAddress(module->AsyncSockets[i],addr.sin_addr.s_addr);

					if(module->OnConnect!=NULL)
					{
						module->OnConnect(module,module->AsyncSockets[i],&(data->user));
					}
				}
				else {break;}
			}
		}
	}
}
void ILibAsyncServerSocket_OnData(ILibAsyncSocket_SocketModule socketModule,char* buffer,int *p_beginPointer, int endPointer,void (**OnInterrupt)(void *AsyncSocketMoudle, void *user),void **user, int *PAUSE)
{
    struct ILibAsyncServerSocket_Data *data = (struct ILibAsyncServerSocket_Data*)(*user);
    int bpointer = *p_beginPointer;

    // Pass the received data up
    if (data != NULL && data->module->OnReceive != NULL) {
        data->module->OnReceive(data->module,socketModule,buffer,&bpointer,endPointer,&(data->module->OnInterrupt),&(data->user),PAUSE);
        if (ILibAsyncSocket_IsFree(socketModule)) {
            *p_beginPointer = endPointer;
        } else {
            *p_beginPointer = bpointer;
        }
    }
}
void ILibAsyncServerSocket_PostSelect(void* socketModule,int slct, void *readset, void *writeset, void *errorset)
{
    struct ILibAsyncServerSocket_Data *data;
    struct sockaddr_in addr;
    int addrlen;
    struct ILibAsyncServerSocketModule *module = (struct ILibAsyncServerSocketModule*)socketModule;
    int i,flags;
    struct sockaddr_in receivingAddress;
    int receivingAddressLength = sizeof(struct sockaddr_in);
#ifdef _WIN32_WCE
    SOCKET NewSocket;
#elif WIN32
    SOCKET NewSocket;
#elif defined( _POSIX)
    int NewSocket;
#endif

    if (FD_ISSET(module->ListenSocket,(fd_set*)readset) != 0) {
        // There are pending TCP connection requests
        for (i = 0; i < module->MaxConnection; ++i) {
            // Check to see if we have available resources to handle this connection request
            if(ILibAsyncSocket_IsFree(module->AsyncSockets[i])!=0)
            {
                addrlen = sizeof(addr);
                NewSocket = accept(module->ListenSocket, (struct sockaddr*)&addr ,&addrlen);

                if (NewSocket != ~0) {
                    switch(module->scope) {
                    case ILibServerScope_LocalLoopback:
                        // Check that the caller ip address is the same as the receive IP address
                        getsockname(NewSocket, (struct sockaddr*)&receivingAddress, &receivingAddressLength);
                        if(receivingAddress.sin_addr.s_addr != addr.sin_addr.s_addr)
                        {
#if defined(WIN32) || defined(_WIN32_WCE)
                            closesocket(NewSocket);
#else
                            close(NewSocket);
#endif
                            NewSocket = ~0;
                        }
                        break;
                    case ILibServerScope_LocalSegment:
                        getsockname(NewSocket, (struct sockaddr*)&receivingAddress, &receivingAddressLength);
                        break;
                    default:
                        break;
                    }
                }
                if (NewSocket != ~0) {
                    // Set this new socket to non-blocking mode, so we can play nice and share thread
#ifdef _WIN32_WCE
                    flags = 1;
                    ioctlsocket(NewSocket,FIONBIO,&flags);
#elif WIN32
                    flags = 1;
                    ioctlsocket(NewSocket,FIONBIO,&flags);
#elif _POSIX
                    flags = fcntl(NewSocket,F_GETFL,0);
                    fcntl(NewSocket,F_SETFL,O_NONBLOCK|flags);
#endif
                    // Instantiate a module to contain all the data about this connection
                    data = (struct ILibAsyncServerSocket_Data*)malloc(sizeof(struct ILibAsyncServerSocket_Data));
                    memset(data,0,sizeof(struct ILibAsyncServerSocket_Data));
                    data->module = socketModule;

                    ILibAsyncSocket_UseThisSocket(module->AsyncSockets[i], &NewSocket, &ILibAsyncServerSocket_OnInterruptSink, data);
                    ILibAsyncSocket_SetRemoteAddress(module->AsyncSockets[i],addr.sin_addr.s_addr);

                    // Notify the user about this new connection
                    if (module->OnConnect != NULL) {
                        module->OnConnect(module,module->AsyncSockets[i], &(data->user));
                    }
                } else {
                    break;
                }
            }
        }
    }
}
//
// Chain PostSelect handler
//
// <param name="socketModule"></param>
// <param name="slct"></param>
// <param name="readset"></param>
// <param name="writeset"></param>
// <param name="errorset"></param>
void ILibAsyncServerSocket_PostSelect(void* socketModule, int slct, fd_set *readset, fd_set *writeset, fd_set *errorset)
{
	struct ILibAsyncServerSocket_Data *data;
	struct sockaddr_in6 addr;
	//struct sockaddr_in6 receivingAddress;

#ifdef _POSIX
	socklen_t addrlen;
	//socklen_t receivingAddressLength = sizeof(struct sockaddr_in6);
#else
	int addrlen;
	//int receivingAddressLength = sizeof(struct sockaddr_in6);
#endif

	struct ILibAsyncServerSocketModule *module = (struct ILibAsyncServerSocketModule*)socketModule;
	int i,flags;
#ifdef _WIN32_WCE
	SOCKET NewSocket;
#elif WIN32
	SOCKET NewSocket;
#elif defined( _POSIX)
	int NewSocket;
#endif

	UNREFERENCED_PARAMETER( slct );
	UNREFERENCED_PARAMETER( writeset );
	UNREFERENCED_PARAMETER( errorset );

	if (FD_ISSET(module->ListenSocket, readset) != 0)
	{
		//
		// There are pending TCP connection requests
		//
		for(i = 0; i < module->MaxConnection; ++i)
		{
			//
			// Check to see if we have available resources to handle this connection request
			//
			if (ILibAsyncSocket_IsFree(module->AsyncSockets[i]) != 0)
			{
				addrlen = sizeof(addr);
				NewSocket = accept(module->ListenSocket, (struct sockaddr*)&addr, &addrlen);
				//printf("Accept NewSocket=%d\r\n", NewSocket);

				// This code rejects connections that are from out-of-scope addresses (Outside the subnet, outside local host...)
				// It needs to be updated to IPv6.
				/*
				if (NewSocket != ~0)
				{
				switch(module->scope)
				{
				case ILibServerScope_LocalLoopback:
				// Check that the caller ip address is the same as the receive IP address
				getsockname(NewSocket, (struct sockaddr*)&receivingAddress, &receivingAddressLength);
				if (((struct sockaddr_in*)&receivingAddress)->sin_addr.s_addr != ((struct sockaddr_in*)&addr)->sin_addr.s_addr)   // TODO: NOT IPv6 COMPILANT!!!!!!!!!!!!!!!!!!!!!!!!
				{
				#if defined(WIN32) || defined(_WIN32_WCE)
				closesocket(NewSocket);
				#else
				close(NewSocket);
				#endif
				NewSocket = ~0;
				}
				break;
				case ILibServerScope_LocalSegment:
				getsockname(NewSocket, (struct sockaddr*)&receivingAddress, &receivingAddressLength);
				break;
				default:
				break;
				}
				}
				*/
				if (NewSocket != ~0)
				{
					//printf("Accepting new connection, socket = %d\r\n", NewSocket);
					//
					// Set this new socket to non-blocking mode, so we can play nice and share thread
					//
#ifdef _WIN32_WCE
					flags = 1;
					ioctlsocket(NewSocket ,FIONBIO, &flags);
#elif WIN32
					flags = 1;
					ioctlsocket(NewSocket, FIONBIO, (u_long *)(&flags));
#elif _POSIX
					flags = fcntl(NewSocket, F_GETFL,0);
					fcntl(NewSocket, F_SETFL, O_NONBLOCK|flags);
#endif
					//
					// Instantiate a module to contain all the data about this connection
					//
					if ((data = (struct ILibAsyncServerSocket_Data*)malloc(sizeof(struct ILibAsyncServerSocket_Data))) == NULL) ILIBCRITICALEXIT(254);
					memset(data, 0, sizeof(struct ILibAsyncServerSocket_Data));
					data->module = socketModule;

					ILibAsyncSocket_UseThisSocket(module->AsyncSockets[i], &NewSocket, &ILibAsyncServerSocket_OnInterruptSink, data);
					ILibAsyncSocket_SetRemoteAddress(module->AsyncSockets[i], (struct sockaddr*)&addr);

					#ifndef MICROSTACK_NOTLS
					if (module->ssl_ctx != NULL)
					{
						// Accept a new TLS connection
						ILibAsyncSocket_SetSSLContext(module->AsyncSockets[i], module->ssl_ctx, 1);
					}
					else
					#endif	
					if (module->OnConnect != NULL)
					{
						// Notify the user about this new connection
						module->OnConnect(module, module->AsyncSockets[i], &(data->user));
					}
				}
				else {break;}
			}
		}
	}
}
//
// Chain PreSelect handler
//
// <param name="socketModule"></param>
// <param name="readset"></param>
// <param name="writeset"></param>
// <param name="errorset"></param>
// <param name="blocktime"></param>
void ILibAsyncServerSocket_PreSelect(void* socketModule, fd_set *readset, fd_set *writeset, fd_set *errorset, int* blocktime)
{
	struct ILibAsyncServerSocketModule *module = (struct ILibAsyncServerSocketModule*)socketModule;
	int flags,i;

	UNREFERENCED_PARAMETER( writeset );
	UNREFERENCED_PARAMETER( errorset );
	UNREFERENCED_PARAMETER( blocktime );

	//
	// The socket isn't put in listening mode, until the chain is started.
	// If this variable == 0, that means we need to do that.
	//
	if (module->listening == 0)
	{
		//
		// Set the socket to non-block mode, so we can play nice and share the thread
		//
#ifdef _WIN32_WCE
		flags = 1;
		ioctlsocket(module->ListenSocket, FIONBIO, &flags);
#elif WIN32
		flags = 1;
		ioctlsocket(module->ListenSocket, FIONBIO, (u_long *)(&flags));
#elif _POSIX
		flags = fcntl(module->ListenSocket, F_GETFL,0);
		fcntl(module->ListenSocket, F_SETFL, O_NONBLOCK | flags);
#endif

		//
		// Put the socket in Listen, and add it to the fdset for the Select loop
		//
		module->listening = 1;
		listen(module->ListenSocket, 4);
		#if defined(WIN32)
		#pragma warning( push, 3 ) // warning C4127: conditional expression is constant
		#endif
		FD_SET(module->ListenSocket, readset);
		#if defined(WIN32)
		#pragma warning( pop )
		#endif
	}
	else
	{
		// Only put the ListenSocket in the readset, if we are able to handle a new socket
		for(i = 0; i < module->MaxConnection; ++i)
		{
			if (ILibAsyncSocket_IsFree(module->AsyncSockets[i]) != 0)
			{
				#if defined(WIN32)
				#pragma warning( push, 3 ) // warning C4127: conditional expression is constant
				#endif
				FD_SET(module->ListenSocket, readset);
				#if defined(WIN32)
				#pragma warning( pop )
				#endif
				break;
			}
		}
	}
}
Exemple #9
0
//
// An internal method called by Chain as Destroy, to cleanup AsyncSocket
//
// <param name="socketModule">The AsyncSocketModule</param>
void ILibAsyncSocket_Destroy(void *socketModule)
{
	struct ILibAsyncSocketModule* module = (struct ILibAsyncSocketModule*)socketModule;
	struct ILibAsyncSocket_SendData *temp,*current;


	//
	// Call the interrupt event if necessary
	//
	if(!ILibAsyncSocket_IsFree(module))
	{
		if(module->OnInterrupt!=NULL)
		{
			module->OnInterrupt(module,module->user);
		}
	}

	//
	// Close socket if necessary
	//
	if(module->internalSocket!=~0)
	{
		#if defined(_WIN32_WCE) || defined(WIN32)
			#if defined(WINSOCK2)
				shutdown(module->internalSocket,SD_BOTH);
			#endif
			closesocket(module->internalSocket);
		#elif defined(_POSIX)
			shutdown(module->internalSocket,SHUT_RDWR);
			close(module->internalSocket);
		#endif
	}
	


	//
	// Free the buffer if necessary
	//
	if(module->buffer!=NULL)
	{
		free(module->buffer);
		module->buffer = NULL;
		module->MallocSize = 0;
	}
	
	//
	// Clear all the data that is pending to be sent
	//
	temp=current=module->PendingSend_Head;
	while(current!=NULL)
	{
		temp = current->Next;
		if(current->UserFree==0)
		{
			free(current->buffer);
		}
		free(current);
		current = temp;
	}
	
	sem_destroy(&(module->SendLock));
}