int _tmain(int argc, _TCHAR* argv[]) { // Get the command line options WCHAR *lPort, *rPort, *rAddr, *targetName = NULL; int i = 1; argv[i] ? NULL : info(argv[0]); bool showTargetName = false; if (!_wcsicmp(argv[i], L"shT")) { showTargetName = true; i++; argv[i] ? NULL : info(argv[0]); } if (!_wcsicmp(argv[i], L"setT")) { (targetName = argv[++i]) ? NULL : info(argv[0]); i++; argv[i] ? NULL : info(argv[0]); } if (!_wcsicmp(argv[i], L"lp")) { (lPort = argv[++i]) ? NULL : info(argv[0]); (rAddr = argv[++i]) ? NULL : info(argv[0]); (rPort = argv[++i]) ? NULL : info(argv[0]); } else { lPort = L"3128"; (rAddr = argv[i++]) ? NULL : info(argv[0]); (rPort = argv[i++]) ? NULL : info(argv[0]); } if (WSAInit()) return -1; //---------------------------------------------------------------------------------------------------- ADDRINFOT hints, *remoteAddr = NULL, *inetAddr = NULL; memset(&hints, 0, sizeof hints); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; int iResult = GetAddrInfo(rAddr, rPort, &hints, &remoteAddr); if (iResult != 0) { switch (iResult) { case WSAHOST_NOT_FOUND: wprintf(L"Host not found\n"); break; case WSANO_DATA: wprintf(L"No data record found\n"); break; default: wprintf(L"Gethost function failed with error: %i\n", iResult); } return -1; } WCHAR hostName[NI_MAXHOST]; iResult = GetNameInfo(remoteAddr->ai_addr, sizeof(SOCKADDR), hostName, NI_MAXHOST, NULL, 0, NI_NAMEREQD); if (iResult != 0) { switch (iResult) { case EAI_AGAIN: wprintf(L"The name can not be determined at the moment\n"); break; case EAI_BADFLAGS: wprintf(L"The flags parameter has an invalid value\n"); break; case EAI_FAIL: wprintf(L"Name info failed\n"); break; case EAI_FAMILY: wprintf(L"It does not recognize the address family\n"); break; case EAI_MEMORY: wprintf(L"Not enough memory\n"); break; case EAI_NONAME: wprintf(L"The name can not be determined\n"); break; default: wprintf(L"Nameinfo function failed with error: %i\n", iResult); } return -1; } if (!targetName) { targetName = buildTargetName(hostName); } if (showTargetName) { wprintf(L"Target Name: '%s'\n", targetName); } // Create a listening socket SOCKET ListenSocket = newSock(); if (ListenSocket == INVALID_SOCKET) return -1; // Listen address memset(&hints, 0, sizeof hints); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; iResult = GetAddrInfo(NULL, lPort, &hints, &inetAddr); if (iResult != 0) { switch (iResult) { case WSAHOST_NOT_FOUND: wprintf(L"Host not found\n"); break; case WSANO_DATA: wprintf(L"No data record found\n"); break; default: wprintf(L"Gethost function failed with error: %i\n", iResult); } return -1; } //------------------------- // Bind the listening socket iResult = bind(ListenSocket, inetAddr->ai_addr, sizeof(SOCKADDR)); if (iResult != 0) { wprintf(L"bind failed with error: %i\n", WSAGetLastError()); return -1; } //------------------------- // Create a new event WSAEVENT NewEvent; if (createEv(&NewEvent)) return -1; //------------------------- // Associate event types FD_ACCEPT and FD_CLOSE // with the listening socket and NewEvent iResult = WSAEventSelect(ListenSocket, NewEvent, FD_ACCEPT); if (iResult != 0) { wprintf(L"WSAEventSelect failed with error: %i\n", WSAGetLastError()); return -1; } //------------------------- // Start listening on the socket iResult = listen(ListenSocket, 0); if (iResult != 0) { wprintf(L"listen failed with error: %i\n", WSAGetLastError()); return -1; } wprintf(L"NegotiateProxy listen on port %s\n", lPort); //------------------------- // Add the socket and event to the arrays, increment number of events SOCKET SocketArray[WSA_MAXIMUM_WAIT_EVENTS]; WSAEVENT EventArray[WSA_MAXIMUM_WAIT_EVENTS]; DWORD EventTotal = 0; SocketArray[EventTotal] = ListenSocket; EventArray[EventTotal++] = NewEvent; //bool needAuth[WSA_MAXIMUM_WAIT_EVENTS]; //memset(needAuth, true, sizeof(needAuth)); bool toProxy; DWORD secondIndex; DWORD index; SOCKET ClientSocket, ProxySocket; WSANETWORKEVENTS NetworkEvents; // The buffers for the reception - transmission //char prBuff[BUFF_SIZE], clBuff[BUFF_SIZE]; int connections = 0; char* previousMessagesArray[WSA_MAXIMUM_WAIT_EVENTS]; memset(previousMessagesArray, NULL, WSA_MAXIMUM_WAIT_EVENTS); for (int i = 0; i < WSA_MAXIMUM_WAIT_EVENTS; previousMessagesArray[i] = NULL, i++) {} while (1) { // Wait for network events on all sockets index = WSAWaitForMultipleEvents(EventTotal, EventArray, FALSE, WSA_INFINITE, FALSE); index -= WSA_WAIT_EVENT_0; if ((index != WSA_WAIT_FAILED) && (index != WSA_WAIT_TIMEOUT)) { WSAEnumNetworkEvents(SocketArray[index], EventArray[index], &NetworkEvents); WSAResetEvent(EventArray[index]); toProxy = (index % 2) ? true : false; secondIndex = toProxy ? index + 1 : index - 1; if ((NetworkEvents.lNetworkEvents & FD_ACCEPT) && (NetworkEvents.iErrorCode[FD_ACCEPT_BIT] == 0)) { ClientSocket = accept(ListenSocket, NULL, NULL); if (INVALID_SOCKET == ClientSocket) wprintf(L"Invalid socket\n"); ProxySocket = socket(AF_INET, SOCK_STREAM, 0); if (INVALID_SOCKET == ProxySocket) wprintf(L"INVALID_SOCKET ERROR!!!\n"); iResult = connect(ProxySocket, remoteAddr->ai_addr, sizeof(SOCKADDR)); if (iResult != 0) { wprintf(L"Connection failed with error: %d\n", WSAGetLastError()); return -1; } printConnections(++connections); if (createEv(&NewEvent)) return -1; SocketArray[EventTotal] = ClientSocket; EventArray[EventTotal] = NewEvent; //------------------------- // Associate event types FD_READ and FD_CLOSE // with the client socket and NewEvent iResult = WSAEventSelect(SocketArray[EventTotal], EventArray[EventTotal], FD_READ | FD_CLOSE); if (iResult != 0) { wprintf(L"WSAEventSelect failed with error: %d\n", WSAGetLastError()); return -1; } EventTotal++; if (createEv(&NewEvent)) return -1; SocketArray[EventTotal] = ProxySocket; EventArray[EventTotal] = NewEvent; //------------------------- // Associate event types FD_READ and FD_CLOSE // with the proxy socket and NewEvent iResult = WSAEventSelect(SocketArray[EventTotal], EventArray[EventTotal], FD_READ | FD_CLOSE); if (iResult != 0) { wprintf(L"WSAEventSelect failed with error: %d\n", WSAGetLastError()); return -1; } EventTotal++; } if ((NetworkEvents.lNetworkEvents & FD_READ) && (NetworkEvents.iErrorCode[FD_READ_BIT] == 0)) { // transfers data iResult = transmit( &SocketArray[index], &SocketArray[secondIndex], toProxy, previousMessagesArray, index, targetName, hostName, remoteAddr->ai_addr, &EventArray[index]); if (iResult < 0) return -1; } if (NetworkEvents.lNetworkEvents & FD_CLOSE) { closesocket(SocketArray[secondIndex]); closesocket(SocketArray[index]); WSACloseEvent(EventArray[secondIndex]); WSACloseEvent(EventArray[index]); // Move from the top to the free place SocketArray[index] = toProxy ? SocketArray[EventTotal - 2] : SocketArray[EventTotal - 1]; SocketArray[secondIndex] = toProxy ? SocketArray[EventTotal - 1] : SocketArray[EventTotal - 2]; EventArray[index] = toProxy ? EventArray[EventTotal - 2] : EventArray[EventTotal - 1]; EventArray[secondIndex] = toProxy ? EventArray[EventTotal - 1] : EventArray[EventTotal - 2]; EventTotal -= 2; printConnections(--connections); } } } return 0; }
/** process http requests coming in */ void RpcHttpTransport::processRequest() { while ( true ) // ( status() == keRpcStarted ) { // Accept a connection // (this will block until client initiates request). RefCountedPtr<Socket> newSock( _listener.accept() ); // if the process is stopped or shutting down if ( newSock == NULL ) { if ( status() == keRpcStopPending ) { // a hard close was performed on the listener socket // this is the signal for this thread to exit break; } else { // some other type of socket error, but not a hard close // in this case, we will just attempt to re-listen // probably the client connected and then immediately disconnected continue; } } CBLOGDBG(_logger, NTEXT("RpcHttpTransport::processRequest: received socket connection...") ); RefCountedPtr<HttpSerPost> post(new HttpSerPost(newSock)); RefCountedPtr<HttpContent> content(new HttpContent); if ( post->readRequest( *content ) && ( content->getHttpMsgType() == HttpContent::HTTP_MSG_TYPE_REQUEST ) ) { int errCode = HttpUtils::keCodeBadRequest; String payload; if ( content->getIsForm() ) { payload = content->getQueryString( Rpc::PAYLOAD ); } else { payload = content->getRequestBody(); } // Now process the payload if it is not empty if ( !payload.empty() ) { CBLOGDBG(_logger, NTEXT("RpcHttpTransport::processRequest: receiving request - ") + payload ); // store post in pending list unsigned long sessionId = _sSessionId++; PendingPostReference postRef(post, content); addPost( sessionId, postRef ); //BUGBUG handleContent( sessionId, content ); _masterServer->queueMessage( sessionId, content->getHeaders(), payload, RPC_HTTP_NAME ); errCode = HttpUtils::keCodeOk; } if ( errCode != HttpUtils::keCodeOk ) { if ( !payload.empty() ) { CBLOGERR(_logger, NTEXT("HttpTransport::processRequest - Unable to Parse XML Data: ") + payload); } else { CBLOGERR(_logger, NTEXT("HttpTransport::processRequest - Unable to Parse XML Data")); } /** Send an http reply in case of exception, back to client **/ if ( post != NULL ) { HttpContent errContent; errContent.setHttpMsgType( HttpContent::HTTP_MSG_TYPE_RESPONSE ); errContent.setErrorCode( errCode ); post->sendResponse( errContent ); } } // if ( errCode != HttpUtils::keCodeOk ) } else { CBLOGERR(_logger, NTEXT("HttpTransport::processRequest - Unable to read request from client")); } } }