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); } }
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); } }
//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; }
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, ¬blocking) != 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, ¬blocking); if (lasterr) SetLastError(lasterr); return rc; }
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, ¬blocking) != 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, ¬blocking); if (rc && lasterr) SetLastError(lasterr); return rc == 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, ¬blocking) != 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, ¬blocking); if (rc && lasterr) SetLastError(lasterr); return rc == 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); } }
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; } }
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; }
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; }
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); } }