Пример #1
0
void Java_com_apress_echo_EchoServerActivity_nativeStartUdpServer(
		JNIEnv* env,
		jobject obj,
		jint port)
{
	// Construct a new UDP socket.
	int serverSocket = NewUdpSocket(env, obj);
	if (NULL == env->ExceptionOccurred())
	{
		// Bind socket to a port number
		BindSocketToPort(env, obj, serverSocket, (unsigned short) port);
		if (NULL != env->ExceptionOccurred())
			goto exit;

		// If random port number is requested
		if (0 == port)
		{
			// Get the port number socket is currently binded
			GetSocketPort(env, obj, serverSocket);
			if (NULL != env->ExceptionOccurred())
				goto exit;
		}

		// Client address
		struct sockaddr_in address;
		memset(&address, 0, sizeof(address));

		char buffer[MAX_BUFFER_SIZE];
		ssize_t recvSize;
		ssize_t sentSize;

		// Receive from the socket
		recvSize = ReceiveDatagramFromSocket(env, obj, serverSocket,
				&address, buffer, MAX_BUFFER_SIZE);

		if ((0 == recvSize) || (NULL != env->ExceptionOccurred()))
			goto exit;

		// Send to the socket
		sentSize = SendDatagramToSocket(env, obj, serverSocket,
				&address, buffer, (size_t) recvSize);
	}

exit:
	if (serverSocket > 0)
	{
		close(serverSocket);
	}
}
Пример #2
0
void Java_com_apress_echo_EchoServerActivity_nativeStartTcpServer(
		JNIEnv* env,
		jobject obj,
		jint port)
{
	// Construct a new TCP socket.
	int serverSocket = NewTcpSocket(env, obj);
	if (NULL == env->ExceptionOccurred())
	{
		// Bind socket to a port number
		BindSocketToPort(env, obj, serverSocket, (unsigned short) port);
		if (NULL != env->ExceptionOccurred())
			goto exit;

		// If random port number is requested
		if (0 == port)
		{
			// Get the port number socket is currently binded
			GetSocketPort(env, obj, serverSocket);
			if (NULL != env->ExceptionOccurred())
				goto exit;
		}

		// Listen on socket with a backlog of 4 pending connections
		ListenOnSocket(env, obj, serverSocket, 4);
		if (NULL != env->ExceptionOccurred())
			goto exit;

		// Accept a client connection on socket
		int clientSocket = AcceptOnSocket(env, obj, serverSocket);
		if (NULL != env->ExceptionOccurred())
			goto exit;

		char buffer[MAX_BUFFER_SIZE];
		ssize_t recvSize;
		ssize_t sentSize;

		// Receive and send back the data
		while (1)
		{
			// Receive from the socket
			recvSize = ReceiveFromSocket(env, obj, clientSocket,
					buffer, MAX_BUFFER_SIZE);

			if ((0 == recvSize) || (NULL != env->ExceptionOccurred()))
				break;

			// Send to the socket
			sentSize = SendToSocket(env, obj, clientSocket,
					buffer, (size_t) recvSize);

			if ((0 == sentSize) || (NULL != env->ExceptionOccurred()))
				break;
		}

		// Close the client socket
		close(clientSocket);
	}

exit:
	if (serverSocket > 0)
	{
		close(serverSocket);
	}
}
Пример #3
0
//TODO: Seriously need some better tokenizing
bool
RoutingNode::ProcessMessages()
{
	messagesIter iter = messages.begin();
	unsigned int length = sizeof(struct sockaddr_in);
	while(iter != messages.end())
	{
		switch(iter->first)
		{
			case RoutingMessage::HELLO: break;
			case RoutingMessage::KEEPALIVE: break;
			case RoutingMessage::PASSMSGS: 
			{
				messagesToSendIter it = messagesToSend.begin();
				while(it != messagesToSend.end())
				{
					neighbor.sin_port = forwardingTable.at(it->first).begin()->first;
					inet_pton(AF_INET, neighborConnectionInfo[forwardingTable.at(it->first).begin()->first].c_str(), &(neighbor.sin_addr));
					char *cstr = new char[it->second.length() + 1];
					strcpy(cstr, it->second.c_str());
					char buf[512];
					sprintf(buf, "@%d~%d~%d.from %d to %d hops %d.%s", 
								myID, RoutingMessage::FWDMESSAGE, it->first, myID-3700, 
								(it->first)-3700, myID-3700, cstr);
					SendMessage(neighbor, buf);
					it++;
				}
				break;
			}
			case RoutingMessage::NEWMESSAGE:
			{
				int destID;
				string message;
				string buf(iter->second);
				string delim = ".";
				destID = atoi(buf.substr(0, buf.find(delim)).c_str());
				buf.erase(0, buf.find(delim) + delim.length());
				message = buf.substr(0, buf.find(delim));
				messagesToSend.insert(pair<int,string>(destID, message));

				#if logging > 1
					cout << "Message Added: " << destID << "." << message<< endl;
				#endif
				break;
			}
			case RoutingMessage::FWDMESSAGE:
			{
				//Message Format:
				//@FromNode~12~DestNode.from x to y hops .<the message>
				int destID;
				string changableStr, finalMessage;
				string buf(iter->second);
				string delim = ".";
				destID = atoi(buf.substr(0, buf.find(delim)).c_str());
				buf.erase(0, buf.find(delim) + delim.length());

				changableStr = buf.substr(0, buf.find(delim));

				stringstream sstm;
				sstm << changableStr << " " << myID-3700;
				changableStr = sstm.str();
				buf.erase(0, buf.find(delim) + delim.length());

				string theMsg = buf.substr(0, buf.find(delim));

				stringstream sstm2;
				sstm2 << changableStr << "." << theMsg;
				finalMessage = sstm2.str();				
	
				if(destID != myID)
				{
					neighbor.sin_port = forwardingTable.at(destID).begin()->first;		
					inet_pton(AF_INET, neighborConnectionInfo[destID].c_str(), &(neighbor.sin_addr));
					char *cstr = new char[finalMessage.length() + 1];
					strcpy(cstr, finalMessage.c_str());
					char buf[512];
					sprintf(buf, "@%d~%d~%d.%s", myID, RoutingMessage::FWDMESSAGE, destID, cstr);
					SendMessage(neighbor, buf);
				}

				PrintMessage(finalMessage);
				break;
			}
			case RoutingMessage::NEWNODE: 
			{
				myID = atoi(iter->second.c_str());
				BindSocketToPort();
				UpdateForwardingTable(myID, myID, 0);
			} break;			
			case RoutingMessage::REQCONINFO: break;
			case RoutingMessage::ACKCONINFO: 
			{			
				int neighborNode;	
				string buf(iter->second);
				string delim = ".";	
				neighborNode = atoi(buf.substr(0, buf.find(delim)).c_str());
				buf.erase(0, buf.find(delim) + delim.length());
				
				neighborConnectionInfo[neighborNode] = buf;
				#if logging > 1
					cout << "Neighbor: " << neighborNode << "|| " << neighborConnectionInfo[neighborNode] << endl;
				#endif
			}break;
			case RoutingMessage::CONVERGING: break;			
			case RoutingMessage::LINKADD: 
			{
				int destID, destCost;
				string buf(iter->second);
				string delim = ".";	
				destID = atoi(buf.substr(0, buf.find(delim)).c_str());
				buf.erase(0, buf.find(delim) + delim.length());
				destCost = atoi(buf.substr(0, buf.find(delim)).c_str());

				cout << "now linked to node " << destID-3700 << " with cost " << destCost << endl;

				neighbors.insert(pair<int,int>(destID, destCost));
				UpdateForwardingTable(destID, destID, destCost);
			} break;
			case RoutingMessage::LINKUPDATE: 
			{
				int neighbor, destCost;
				string buf(iter->second);
				string delim = ".";	
				neighbor = atoi(buf.substr(0, buf.find(delim)).c_str());
				buf.erase(0, buf.find(delim) + delim.length());
				destCost = atoi(buf.substr(0, buf.find(delim)).c_str());

				neighbors.at(neighbor) = destCost;
				UpdateNeighborVector(neighbor, myID, destCost);

			}break;
			case RoutingMessage::VECTOR:
			{
				int destID, destCost;
				string buf(iter->second);
				string delim = ".";	
				destID = atoi(buf.substr(0, buf.find(delim)).c_str());
				buf.erase(0, buf.find(delim) + delim.length());
				destCost = atoi(buf.substr(0, buf.find(delim)).c_str());

				if (destID != myID)
					UpdateNeighborVector(fromNode, destID, destCost);
				
				break;
			}
			case RoutingMessage::REQUPDATE:
			{
				SendForwardingTableToNeighbors();
			} break;
			case RoutingMessage::REQNBRINFO: break;
			case RoutingMessage::CONVERGED: break;
			case RoutingMessage::DEBUG: break;
			case RoutingMessage::ERROR: break;
			default: break;
		}
		iter++;
	}

	messages.clear();
	//TEMPORARY - FIX THIS
	return false;
}
Пример #4
0
static int my_connect(NetlibConnection *nlc, NETLIBOPENCONNECTION * nloc)
{
	int rc = 0, retrycnt = 0;
	u_long notblocking = 1;	
	DWORD lasterr = 0;	
	static const TIMEVAL tv = { 1, 0 };

	unsigned int dwTimeout = (nloc->cbSize == sizeof(NETLIBOPENCONNECTION) && nloc->flags & NLOCF_V2) ? nloc->timeout : 0;
	// if dwTimeout is zero then its an old style connection or new with a 0 timeout, select() will error quicker anyway
	if (dwTimeout == 0) dwTimeout = 30;

	// this is for XP SP2 where there is a default connection attempt limit of 10/second
	if (connectionTimeout)
	{
		WaitForSingleObject(hConnectionOpenMutex, 10000);
		int waitdiff = GetTickCount() - g_LastConnectionTick;
		if (waitdiff < connectionTimeout) SleepEx(connectionTimeout, TRUE);
		g_LastConnectionTick = GetTickCount();
		ReleaseMutex(hConnectionOpenMutex);

		// might of died in between the wait
		if (Miranda_Terminated()) return SOCKET_ERROR;
	}

retry:
	nlc->s = socket(AF_INET,nloc->flags & NLOCF_UDP ? SOCK_DGRAM : SOCK_STREAM, 0);
	if (nlc->s == INVALID_SOCKET) return SOCKET_ERROR;

	// return the socket to non blocking
	if (ioctlsocket(nlc->s, FIONBIO, &notblocking) != 0) return SOCKET_ERROR;

	if (nlc->nlu->settings.specifyOutgoingPorts && nlc->nlu->settings.szOutgoingPorts  && nlc->nlu->settings.szOutgoingPorts[0]) 
	{
		if (!BindSocketToPort(nlc->nlu->settings.szOutgoingPorts, nlc->s, &nlc->nlu->inportnum))
			NetlibLogf(nlc->nlu,"Netlib connect: Not enough ports for outgoing connections specified");
	} 

	// try a connect
	if (connect(nlc->s, (LPSOCKADDR)&nlc->sinProxy, sizeof(nlc->sinProxy)) == 0) 
	{
		goto unblock;
	}

	// didn't work, was it cos of nonblocking?
	if (WSAGetLastError() != WSAEWOULDBLOCK) 
	{
		rc = SOCKET_ERROR;
		goto unblock;
	}

	for (;;) 
	{		
		fd_set r, w, e;
		FD_ZERO(&r); FD_ZERO(&w); FD_ZERO(&e);
		FD_SET(nlc->s, &r);
		FD_SET(nlc->s, &w);
		FD_SET(nlc->s, &e);		
		if ((rc = select(0, &r, &w, &e, &tv)) == SOCKET_ERROR) 
			break;

		if (rc > 0) 
		{			
			if (FD_ISSET(nlc->s, &w))
			{
				// connection was successful
				rc = 0;
			}
			if (FD_ISSET(nlc->s, &r)) 
			{
				// connection was closed
				rc = SOCKET_ERROR;
				lasterr = WSAECONNRESET;
			}
			if (FD_ISSET(nlc->s, &e)) 
			{
				// connection failed.
				int len = sizeof(lasterr);
				rc = SOCKET_ERROR;
				getsockopt(nlc->s, SOL_SOCKET, SO_ERROR, (char*)&lasterr, &len);
				if (lasterr == WSAEADDRINUSE && ++retrycnt <= 2) 
				{
					closesocket(nlc->s);
					goto retry;
				}
			}
			break;
		} 
		else if (Miranda_Terminated()) 
		{
			rc = SOCKET_ERROR;
			lasterr = ERROR_TIMEOUT;
			break;
		} 
		else if (nloc->cbSize == sizeof(NETLIBOPENCONNECTION) && nloc->flags & NLOCF_V2 && 
			nloc->waitcallback != NULL && nloc->waitcallback(&dwTimeout) == 0)
		{
			rc = SOCKET_ERROR;
			lasterr = ERROR_TIMEOUT;
			break;
		}
		if (--dwTimeout == 0) 
		{
			rc = SOCKET_ERROR;
			lasterr = ERROR_TIMEOUT;
			break;
		}
	}

unblock:	
	notblocking = 0;
	ioctlsocket(nlc->s, FIONBIO, &notblocking);
	if (lasterr) SetLastError(lasterr);
	return rc;
}
Пример #5
0
static bool my_connectIPv4(NetlibConnection *nlc, NETLIBOPENCONNECTION * nloc)
{
	int rc = 0, retrycnt = 0;
	u_long notblocking = 1;
	DWORD lasterr = 0;
	static const TIMEVAL tv = { 1, 0 };

	unsigned int dwTimeout = (nloc->cbSize == sizeof(NETLIBOPENCONNECTION) && nloc->flags & NLOCF_V2) ? nloc->timeout : 0;
	// if dwTimeout is zero then its an old style connection or new with a 0 timeout, select() will error quicker anyway
	if (dwTimeout == 0) dwTimeout = 30;

	// this is for XP SP2 where there is a default connection attempt limit of 10/second
	if (connectionTimeout) {
		WaitForSingleObject(hConnectionOpenMutex, 10000);
		int waitdiff = GetTickCount() - g_LastConnectionTick;
		if (waitdiff < connectionTimeout) SleepEx(connectionTimeout, TRUE);
		g_LastConnectionTick = GetTickCount();
		ReleaseMutex(hConnectionOpenMutex);

		// might of died in between the wait
		if (Miranda_Terminated()) return false;
	}

	PHOSTENT he;
	SOCKADDR_IN sin = {0};
	sin.sin_family = AF_INET;

	if (nlc->proxyType) {
		if (!nlc->szProxyServer) return false;

		if (nloc)
			NetlibLogf(nlc->nlu, "(%p) Connecting to proxy %s:%d for %s:%d ....", nlc, nlc->szProxyServer, nlc->wProxyPort, nloc->szHost, nloc->wPort);
		else
			NetlibLogf(nlc->nlu, "(%p) Connecting to proxy %s:%d ....", nlc, nlc->szProxyServer, nlc->wProxyPort);

		sin.sin_port = htons(nlc->wProxyPort);
		he = gethostbyname(nlc->szProxyServer);
	}
	else {
		if (!nloc || !nloc->szHost || nloc->szHost[0] == '[' || strchr(nloc->szHost, ':')) return false;
		NetlibLogf(nlc->nlu, "(%p) Connecting to server %s:%d....", nlc, nloc->szHost, nloc->wPort);

		sin.sin_port = htons(nloc->wPort);
		he = gethostbyname(nloc->szHost);
	}

	for (char** har = he->h_addr_list; *har && !Miranda_Terminated(); ++har) {
		sin.sin_addr.s_addr = *(u_long*)*har;

		char* szIp = NetlibAddressToString((SOCKADDR_INET_M*)&sin);
		NetlibLogf(nlc->nlu, "(%p) Connecting to ip %s ....", nlc, szIp);
		mir_free(szIp);

retry:
		nlc->s = socket(AF_INET, nloc->flags & NLOCF_UDP ? SOCK_DGRAM : SOCK_STREAM, 0);
		if (nlc->s == INVALID_SOCKET)
			return false;

		// return the socket to non blocking
		if (ioctlsocket(nlc->s, FIONBIO, &notblocking) != 0)
			return false;

		if (nlc->nlu->settings.specifyOutgoingPorts && nlc->nlu->settings.szOutgoingPorts  && nlc->nlu->settings.szOutgoingPorts[0]) {
			if (!BindSocketToPort(nlc->nlu->settings.szOutgoingPorts, nlc->s, INVALID_SOCKET, &nlc->nlu->inportnum))
				NetlibLogf(nlc->nlu, "Netlib connect: Not enough ports for outgoing connections specified");
		}

		// try a connect
		if (connect(nlc->s, (LPSOCKADDR)&sin, sizeof(sin)) == 0) {
			rc = 0;
			break;
		}

		// didn't work, was it cos of nonblocking?
		if (WSAGetLastError() != WSAEWOULDBLOCK) {
			rc = SOCKET_ERROR;
			closesocket(nlc->s);
			nlc->s = INVALID_SOCKET;
			continue;
		}

		while (true) {
			fd_set r, w, e;
			FD_ZERO(&r); FD_ZERO(&w); FD_ZERO(&e);
			FD_SET(nlc->s, &r);
			FD_SET(nlc->s, &w);
			FD_SET(nlc->s, &e);
			if ((rc = select(0, &r, &w, &e, &tv)) == SOCKET_ERROR)
				break;

			if (rc > 0) {
				if (FD_ISSET(nlc->s, &w)){
					// connection was successful
					rc = 0;
				}
				if (FD_ISSET(nlc->s, &r)) {
					// connection was closed
					rc = SOCKET_ERROR;
					lasterr = WSAECONNRESET;
				}
				if (FD_ISSET(nlc->s, &e)) {
					// connection failed.
					int len = sizeof(lasterr);
					rc = SOCKET_ERROR;
					getsockopt(nlc->s, SOL_SOCKET, SO_ERROR, (char*)&lasterr, &len);
					if (lasterr == WSAEADDRINUSE && ++retrycnt <= 2) {
						closesocket(nlc->s);
						goto retry;
					}
				}
				break;
			}
			else if (Miranda_Terminated()) {
				rc = SOCKET_ERROR;
				lasterr = ERROR_TIMEOUT;
				break;
			}
			else if (nloc->cbSize == sizeof(NETLIBOPENCONNECTION) && nloc->flags & NLOCF_V2 && nloc->waitcallback != NULL && nloc->waitcallback(&dwTimeout) == 0) {
				rc = SOCKET_ERROR;
				lasterr = ERROR_TIMEOUT;
				break;
			}
			if (--dwTimeout == 0) {
				rc = SOCKET_ERROR;
				lasterr = ERROR_TIMEOUT;
				break;
			}
		}

		if (rc == 0) break;

		closesocket(nlc->s);
		nlc->s = INVALID_SOCKET;
	}

	notblocking = 0;
	if (nlc->s != INVALID_SOCKET) ioctlsocket(nlc->s, FIONBIO, &notblocking);
	if (rc && lasterr) SetLastError(lasterr);
	return rc == 0;
}
Пример #6
0
static bool my_connectIPv6(NetlibConnection *nlc, NETLIBOPENCONNECTION * nloc)
{
	int rc = SOCKET_ERROR, retrycnt = 0;
	u_long notblocking = 1;
	DWORD lasterr = 0;
	static const TIMEVAL tv = { 1, 0 };

	unsigned int dwTimeout = (nloc->cbSize == sizeof(NETLIBOPENCONNECTION) && nloc->flags & NLOCF_V2) ? nloc->timeout : 0;
	// if dwTimeout is zero then its an old style connection or new with a 0 timeout, select() will error quicker anyway
	if (dwTimeout == 0) dwTimeout = 30;

	// this is for XP SP2 where there is a default connection attempt limit of 10/second
	if (connectionTimeout) {
		WaitForSingleObject(hConnectionOpenMutex, 10000);
		int waitdiff = GetTickCount() - g_LastConnectionTick;
		if (waitdiff < connectionTimeout) SleepEx(connectionTimeout, TRUE);
		g_LastConnectionTick = GetTickCount();
		ReleaseMutex(hConnectionOpenMutex);

		// might of died in between the wait
		if (Miranda_Terminated()) return false;
	}

	char szPort[6];
	addrinfo *air = NULL, *ai, hints = {0};

	hints.ai_family = AF_UNSPEC;

	if (nloc->flags & NLOCF_UDP) {
		hints.ai_socktype = SOCK_DGRAM;
		hints.ai_protocol = IPPROTO_UDP;
	}
	else {
		hints.ai_socktype = SOCK_STREAM;
		hints.ai_protocol = IPPROTO_TCP;
	}

	if (nlc->proxyType) {
		if (!nlc->szProxyServer)
			return false;

		if (nloc)
			NetlibLogf(nlc->nlu, "(%p) Connecting to proxy %s:%d for %s:%d ....", nlc, nlc->szProxyServer, nlc->wProxyPort, nloc->szHost, nloc->wPort);
		else
			NetlibLogf(nlc->nlu, "(%p) Connecting to proxy %s:%d ....", nlc, nlc->szProxyServer, nlc->wProxyPort);

		_itoa(nlc->wProxyPort, szPort, 10);
		if (GetAddrInfoA(nlc->szProxyServer, szPort, &hints, &air)) {
			NetlibLogf(nlc->nlu, "%s %d: %s() for host %s failed (%u)", __FILE__, __LINE__, "getaddrinfo", nlc->szProxyServer, WSAGetLastError());
			return false;
		}
	}
	else {
		if (!nloc || !nloc->szHost)
			return false;

		NetlibLogf(nlc->nlu, "(%p) Connecting to server %s:%d....", nlc, nloc->szHost, nloc->wPort);

		_itoa(nlc->nloc.wPort, szPort, 10);

		if (GetAddrInfoA(nlc->nloc.szHost, szPort, &hints, &air)) {
			NetlibLogf(nlc->nlu, "%s %d: %s() for host %s failed (%u)", __FILE__, __LINE__, "getaddrinfo", nlc->nloc.szHost, WSAGetLastError());
			return false;
		}
	}

	for (ai = air; ai && !Miranda_Terminated(); ai = ai->ai_next) {
		NetlibLogf(nlc->nlu, "(%p) Connecting to ip %s ....", nlc, ptrA( NetlibAddressToString((SOCKADDR_INET_M*)ai->ai_addr)));
retry:
		nlc->s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
		if (nlc->s == INVALID_SOCKET)
			return false;

		// return the socket to non blocking
		if (ioctlsocket(nlc->s, FIONBIO, &notblocking) != 0)
			return false;

		if (nlc->nlu->settings.specifyOutgoingPorts && nlc->nlu->settings.szOutgoingPorts  && nlc->nlu->settings.szOutgoingPorts[0]) {
			SOCKET s = ai->ai_family == AF_INET ? nlc->s : INVALID_SOCKET;
			SOCKET s6 = ai->ai_family == AF_INET6 ? nlc->s : INVALID_SOCKET;
			if (!BindSocketToPort(nlc->nlu->settings.szOutgoingPorts, s, s6, &nlc->nlu->inportnum))
				NetlibLogf(nlc->nlu, "Netlib connect: Not enough ports for outgoing connections specified");
		}

		// try a connect
		if (connect(nlc->s, ai->ai_addr, (int)ai->ai_addrlen) == 0) {
			rc = 0;
			break;
		}

		// didn't work, was it cos of nonblocking?
		if (WSAGetLastError() != WSAEWOULDBLOCK) {
			rc = SOCKET_ERROR;
			closesocket(nlc->s);
			nlc->s = INVALID_SOCKET;
			continue;
		}

		while (true) { // timeout loop
			fd_set r, w, e;
			FD_ZERO(&r); FD_ZERO(&w); FD_ZERO(&e);
			FD_SET(nlc->s, &r);
			FD_SET(nlc->s, &w);
			FD_SET(nlc->s, &e);
			if ((rc = select(0, &r, &w, &e, &tv)) == SOCKET_ERROR)
				break;

			if (rc > 0) {
				if (FD_ISSET(nlc->s, &w)){
					// connection was successful
					rc = 0;
					lasterr = 0;
				}
				if (FD_ISSET(nlc->s, &r)) {
					// connection was closed
					rc = SOCKET_ERROR;
					lasterr = WSAECONNRESET;
				}
				if (FD_ISSET(nlc->s, &e)) {
					// connection failed.
					int len = sizeof(lasterr);
					rc = SOCKET_ERROR;
					getsockopt(nlc->s, SOL_SOCKET, SO_ERROR, (char*)&lasterr, &len);
					if (lasterr == WSAEADDRINUSE && ++retrycnt <= 2)
					{
						closesocket(nlc->s);
						nlc->s = INVALID_SOCKET;
						goto retry;
					}
				}
				break;
			}
			else if (Miranda_Terminated()) {
				rc = SOCKET_ERROR;
				lasterr = ERROR_TIMEOUT;
				break;
			}
			else if (nloc->cbSize == sizeof(NETLIBOPENCONNECTION) && nloc->flags & NLOCF_V2 && nloc->waitcallback != NULL && nloc->waitcallback(&dwTimeout) == 0) {
				rc = SOCKET_ERROR;
				lasterr = ERROR_TIMEOUT;
				break;
			}
			if (--dwTimeout == 0) {
				rc = SOCKET_ERROR;
				lasterr = ERROR_TIMEOUT;
				break;
			}
		}

		if (rc == 0) break;

		closesocket(nlc->s);
		nlc->s = INVALID_SOCKET;
	}

	FreeAddrInfoA(air);

	notblocking = 0;
	if (nlc->s != INVALID_SOCKET) ioctlsocket(nlc->s, FIONBIO, &notblocking);
	if (rc && lasterr) SetLastError(lasterr);
	return rc == 0;
}
Пример #7
0
JNIEXPORT void JNICALL Java_com_example_hellojni_Native_nativeStartTcpServer
(JNIEnv *env, jobject obj, jint port) {
// Construct a new TCP socket.
    int serverSocket = NewTcpSocket(env, obj);
    if (NULL == env->ExceptionOccurred())
    {
        // Bind socket to a port number
        BindSocketToPort(env, obj, serverSocket, (unsigned short) port);
        if (NULL != env->ExceptionOccurred())
            goto exit;

        // If random port number is requested
        if (0 == port)
        {
            // Get the port number socket is currently binded
            GetSocketPort(env, obj, serverSocket);
            if (NULL != env->ExceptionOccurred())
                goto exit;
        }

        // Listen on socket with a backlog of 4 pending connections
        ListenOnSocket(env, obj, serverSocket, 4);
        if (NULL != env->ExceptionOccurred())
            goto exit;

        // Accept a client connection on socket
        int clientSocket = AcceptOnSocket(env, obj, serverSocket);
        if (NULL != env->ExceptionOccurred())
            goto exit;

        char buffer[MAX_BUFFER_SIZE];
        ssize_t recvSize;
        ssize_t sentSize;

        // Receive and send back the data
        while (1)
        {
            // Receive from the socket
            recvSize = ReceiveFromSocket(env, obj, clientSocket,
                                         buffer, MAX_BUFFER_SIZE);

            if ((0 == recvSize) || (NULL != env->ExceptionOccurred()))
                break;

            // Send to the socket
            char prefix[] = "Server: ";
            char toSend[MAX_BUFFER_SIZE + strlen(prefix)];
            strcpy(toSend, prefix);
            strcat(toSend, buffer);
            sentSize = SendToSocket(env, obj, clientSocket,
                                    toSend, (size_t) strlen(toSend));
            if ((0 == sentSize) || (NULL != env->ExceptionOccurred()))
                break;
        }

        // Close the client socket
        close(clientSocket);
    }

exit:
    if (serverSocket > 0)
    {
        close(serverSocket);
    }
}
Пример #8
0
bool BindSocketToPort(const char *szPorts, SOCKET s, int* portn)
{
    SOCKADDR_IN sin = {0};
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = htonl(INADDR_ANY);

    EnterCriticalSection(&csNetlibUser);

    if (--*portn < 0 && s != INVALID_SOCKET)
    {
        BindSocketToPort(szPorts, INVALID_SOCKET, portn);
        if (*portn == 0)
        {
            LeaveCriticalSection(&csNetlibUser);
            return false;
        }
        WORD num;
        CallService(MS_UTILS_GETRANDOM, sizeof(WORD), (LPARAM)&num);
        *portn = num % *portn;
    }

    bool before=false;
    for (;;)
    {
        const char *psz;
        char *pszEnd;
        int portMin, portMax, port, portnum = 0;

        for(psz=szPorts; *psz;)
        {
            while (*psz == ' ' || *psz == ',') psz++;
            portMin = strtol(psz, &pszEnd, 0);
            if (pszEnd == psz) break;
            while (*pszEnd == ' ') pszEnd++;
            if(*pszEnd == '-')
            {
                psz = pszEnd + 1;
                portMax = strtol(psz, &pszEnd, 0);
                if (pszEnd == psz) portMax = 65535;
                if (portMin > portMax)
                {
                    port = portMin;
                    portMin = portMax;
                    portMax = port;
                }
            }
            else portMax = portMin;
            if (portMax >= 1)
            {
                if (portMin <= 0) portMin = 1;
                for (port = portMin; port <= portMax; port++)
                {
                    if (port > 65535) break;

                    ++portnum;

                    if (s == INVALID_SOCKET) continue;
                    if (!before && portnum <= *portn) continue;
                    if (before  && portnum >= *portn)
                    {
                        LeaveCriticalSection(&csNetlibUser);
                        return false;
                    }

                    sin.sin_port = htons((WORD)port);
                    if (bind(s, (SOCKADDR*)&sin, sizeof(sin)) == 0)
                    {
                        LeaveCriticalSection(&csNetlibUser);
                        *portn = portnum + 1;
                        return true;
                    }
                }
            }
            psz = pszEnd;
        }
        if (*portn < 0)
        {
            *portn = portnum;
            LeaveCriticalSection(&csNetlibUser);
            return true;
        }
        else if (*portn >= portnum)
            *portn = 0;
        else
            before = true;
    }
}
Пример #9
0
INT_PTR NetlibBindPort(WPARAM wParam,LPARAM lParam)
{
    NETLIBBIND *nlb = (NETLIBBIND*)lParam;
    struct NetlibUser *nlu = (struct NetlibUser*)wParam;
    struct NetlibBoundPort *nlbp;
    SOCKADDR_IN sin;
    int foundPort = 0;
    UINT dwThreadId;

    if (GetNetlibHandleType(nlu) != NLH_USER || !(nlu->user.flags & NUF_INCOMING) ||
            nlb == NULL || nlb->pfnNewConnection == NULL)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return 0;
    }
    if (nlb->cbSize != sizeof(NETLIBBIND)   &&
            nlb->cbSize != NETLIBBIND_SIZEOF_V2 &&
            nlb->cbSize != NETLIBBIND_SIZEOF_V1)
    {
        return 0;
    }
    nlbp = (NetlibBoundPort*)mir_calloc(sizeof(NetlibBoundPort));
    nlbp->handleType = NLH_BOUNDPORT;
    nlbp->nlu = nlu;
    nlbp->pfnNewConnectionV2 = nlb->pfnNewConnectionV2;
    nlbp->s = socket(AF_INET, SOCK_STREAM, 0);
    nlbp->pExtra = (nlb->cbSize != NETLIBBIND_SIZEOF_V1) ? nlb->pExtra : NULL;
    if (nlbp->s == INVALID_SOCKET)
    {
        NetlibLogf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"socket",WSAGetLastError());
        mir_free(nlbp);
        return 0;
    }
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = htonl(INADDR_ANY);
    sin.sin_port = 0;

    /* if the netlib user wanted a free port given in the range, then
    they better have given wPort==0, let's hope so */
    if (nlu->settings.specifyIncomingPorts && nlu->settings.szIncomingPorts && nlb->wPort == 0)
    {
        if (!BindSocketToPort(nlu->settings.szIncomingPorts, nlbp->s, &nlu->outportnum))
        {
            NetlibLogf(nlu, "Netlib bind: Not enough ports for incoming connections specified");
            SetLastError(WSAEADDRINUSE);
        }
        else
            foundPort = 1;
    }
    else
    {
        /* if ->wPort==0 then they'll get any free port, otherwise they'll
        be asking for whatever was in nlb->wPort*/
        if (nlb->wPort != 0)
        {
            NetlibLogf(nlu,"%s %d: trying to bind port %d, this 'feature' can be abused, please be sure you want to allow it.",__FILE__,__LINE__,nlb->wPort);
            sin.sin_port = htons(nlb->wPort);
        }
        if (bind(nlbp->s, (PSOCKADDR)&sin, sizeof(sin)) == 0)
            foundPort = 1;
    }
    if (!foundPort)
    {
        NetlibLogf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"bind",WSAGetLastError());
        closesocket(nlbp->s);
        mir_free(nlbp);
        return 0;
    }

    if (listen(nlbp->s, 5))
    {
        NetlibLogf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"listen",WSAGetLastError());
        closesocket(nlbp->s);
        mir_free(nlbp);
        return 0;
    }

    {   int len;
        DWORD extIP;

        ZeroMemory(&sin,sizeof(sin));
        len = sizeof(sin);
        if (getsockname(nlbp->s,(SOCKADDR *)&sin,&len))
        {
            NetlibLogf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"getsockname",WSAGetLastError());
            closesocket(nlbp->s);
            mir_free(nlbp);
            return 0;
        }
        nlb->wPort = ntohs(sin.sin_port);
        nlbp->wPort = nlb->wPort;
        nlb->dwInternalIP = ntohl(sin.sin_addr.S_un.S_addr);

        if (nlb->dwInternalIP == 0)
        {
            char hostname[64];
            struct hostent *he;

            gethostname(hostname, SIZEOF(hostname));
            he = gethostbyname(hostname);
            if (he && he->h_addr_list[0])
                nlb->dwInternalIP = ntohl(*(PDWORD)he->h_addr_list[0]);
        }
        if (nlu->settings.enableUPnP &&
                NetlibUPnPAddPortMapping(nlb->wPort, "TCP", &nlbp->wExPort, &extIP, nlb->cbSize > NETLIBBIND_SIZEOF_V2))
        {
            NetlibLogf(NULL, "UPnP port mapping succeeded. Internal Port: %u External Port: %u\n",
                       nlb->wPort, nlbp->wExPort);
            if (nlb->cbSize > NETLIBBIND_SIZEOF_V2)
            {
                nlb->wExPort = nlbp->wExPort;
                nlb->dwExternalIP = extIP;
            }
        }
        else
        {
            if (nlu->settings.enableUPnP)
                NetlibLogf(NULL, "UPnP port mapping failed. Internal Port: %u\n", nlb->wPort);
            else
                NetlibLogf(NULL, "UPnP disabled. Internal Port: %u\n", nlb->wPort);

            nlbp->wExPort = 0;
            if (nlb->cbSize > NETLIBBIND_SIZEOF_V2)
            {
                nlb->wExPort = nlb->wPort;
                nlb->dwExternalIP = nlb->dwInternalIP;
            }
        }
    }
    nlbp->hThread = (HANDLE)forkthreadex(NULL, 0, NetlibBindAcceptThread, 0, nlbp, &dwThreadId);
    return (INT_PTR)nlbp;
}
Пример #10
0
JNIEXPORT void JNICALL Java_com_eric_ndkapp_ServerActivity_nativeStartServer
  (JNIEnv * env, jobject obj, jstring ip, jint port, jstring message)
{
	// Construct a new TCP socket.
	if (serverSocket > 0)
	{
		LogMessage(env, obj, "Server is running");
		return;
	}

	serverSocket = NewTcpSocket(env, obj);
	if (NULL == env->ExceptionOccurred())
	{
		// Get IP address as C string
		const char* ipAddress = env->GetStringUTFChars(ip, NULL);
		if (NULL == ipAddress)
			goto exit;

		// Bind socket to a port number
		BindSocketToPort(env, obj, serverSocket, ipAddress, (unsigned short) port);

		// Release the IP address
		env->ReleaseStringUTFChars(ip, ipAddress);

		if (NULL != env->ExceptionOccurred())
			goto exit;

		// Listen on socket with a backlog of 4 pending connections
		ListenOnSocket(env, obj, serverSocket, 4);
		if (NULL != env->ExceptionOccurred())
			goto exit;

		// Accept a client connection on socket
		int socket = 0;

		if (clientSocket == 0)
		{
			clientSocket = AcceptOnSocket(env, obj, serverSocket);
		}

		if (env->ExceptionOccurred() == NULL)
		{
			// Receive and send back the data
			char buffer[MAX_BUFFER_SIZE];
			ssize_t recvSize;
			ssize_t sentSize;

			// Get message as C string
			const char* messageText = env->GetStringUTFChars(message, NULL);
			if (NULL == messageText)
				goto exit;

			// Get the message size
			jsize messageSize = env->GetStringUTFLength(message);

			// Send to the socket
			sentSize = SendToSocket(env, obj, clientSocket, messageText, messageSize);

			// Release the message text
			env->ReleaseStringUTFChars(message, messageText);

			while ((recvSize = ReceiveFromSocket(env, obj, clientSocket, buffer, MAX_BUFFER_SIZE)) > 0)
			{
			}
		}
	}

exit:
	return;
}
Пример #11
0
JNIEXPORT void JNICALL Java_com_example_hellojni_Native_nativeStartUdpServer
(JNIEnv *env, jobject obj, jint port)
{
    // Construct a new UDP socket.
    int serverSocket = NewUdpSocket(env, obj);
    if (NULL == env->ExceptionOccurred())
    {
        LOGD("Create UDP Socket...");
        // Bind socket to a port number
        BindSocketToPort(env, obj, serverSocket, (unsigned short) port);
        if (NULL != env->ExceptionOccurred())
            goto exit;

        // If random port number is requested
        if (0 == port)
        {
            // Get the port number socket is currently binded
            GetSocketPort(env, obj, serverSocket);
            if (NULL != env->ExceptionOccurred())
                goto exit;
        }

        struct sockaddr_in serv;
        char serv_ip[20];
        socklen_t serv_len = sizeof(serv);
        getsockname(serverSocket, (struct sockaddr *)&serv, &serv_len);
        inet_ntop(AF_INET, &serv.sin_addr, serv_ip, sizeof(serv_ip));
        LogMessage(env, obj, "Server on %s:%d\n", serv_ip, ntohs(serv.sin_port));
        // LogMessage(env, obj, "Server on %s:%d\n", serv_ip, ntohs(serv.sin_port));
        while (1) {
            // Client address
            struct sockaddr_in address;
            memset(&address, 0, sizeof(address));

            char buffer[MAX_BUFFER_SIZE];
            ssize_t recvSize;
            ssize_t sentSize;
            // Receive from the socket
            recvSize = ReceiveDatagramFromSocket(env, obj, serverSocket,
                                                 &address, buffer, MAX_BUFFER_SIZE);
            LOGD("Received from %s:%hu."
                 , inet_ntoa(address.sin_addr), ntohs(address.sin_port));
            LOGD("Received %hu bytes: %s", recvSize, buffer);
            // LogMessage(env, obj, "Received from %s:%hu"
            //            , inet_ntoa(address.sin_addr), ntohs(address.sin_port));
            // LogMessage(env, obj, "Received %hu bytes: %s", recvSize, buffer);


            if ((0 == recvSize) || (NULL != env->ExceptionOccurred()))
                goto exit;

            // Send to the socket
            // combine data
            char prefix[] = "Server: ";
            char buffer2[MAX_BUFFER_SIZE + strlen(prefix)];
            strcpy(buffer2, prefix);
            strcat(buffer2, buffer);
            sentSize = SendDatagramToSocket(env, obj, serverSocket,
                                            &address, buffer2, (size_t) recvSize);
        }
    }

exit:
    if (serverSocket > 0)
    {
        close(serverSocket);
    }
}