/** * This method should be called to handle requests on the socket. */ bool WatcherNub::receiveRequest() { if (!isInitialised_) { // TODO: Allow calls to this when not initialised before the client // currently does this. Should really fix the client so that this is // only called once initialised. return false; } sockaddr_in senderAddr; int len; if (wrh_ == NULL) { ERROR_MSG( "WatcherNub::receiveRequest: Can't call me before\n" "\tcalling setRequestHandler(WatcherRequestHandler*)\n" ); return false; } if (insideReceiveRequest_) { ERROR_MSG( "WatcherNub::receiveRequest: BAD THING NOTICED:\n" "\tAttempted re-entrant call to receiveRequest\n" ); return false; } insideReceiveRequest_ = true; // try to recv len = socket_.recvfrom( requestPacket_, WN_PACKET_SIZE, senderAddr ); if (len == -1) { // EAGAIN = no packets waiting, ECONNREFUSED = rejected outgoing packet #ifdef _WIN32 int err = WSAGetLastError(); if (err != WSAEWOULDBLOCK && err != WSAECONNREFUSED && err != WSAECONNRESET) #else int err = errno; if (err != EAGAIN && err != ECONNREFUSED) #endif { ERROR_MSG( "WatcherNub::receiveRequest: recvfrom failed\n" ); } insideReceiveRequest_ = false; return false; } // make sure we haven't picked up a weird packet (from when broadcast // was on, say ... hey, it could happen!) WatcherDataMsg * wdm = (WatcherDataMsg*)requestPacket_; if (len < (int)sizeof(WatcherDataMsg)) { ERROR_MSG( "WatcherNub::receiveRequest: Packet is too short\n" ); insideReceiveRequest_ = false; return false; } if (! (wdm->message == WATCHER_MSG_GET || wdm->message == WATCHER_MSG_GET_WITH_DESC || wdm->message == WATCHER_MSG_SET || wdm->message == WATCHER_MSG_GET2 || wdm->message == WATCHER_MSG_SET2 ) ) { wrh_->processExtensionMessage( wdm->message, requestPacket_ + sizeof( wdm->message ), len - sizeof( wdm->message ), Mercury::Address( senderAddr.sin_addr.s_addr, senderAddr.sin_port ) ); insideReceiveRequest_ = false; return true; } // Our reply handler for the current request. WatcherPacketHandler *packetHandler = NULL; // and call back to the program switch (wdm->message) { case WATCHER_MSG_GET: case WATCHER_MSG_GET_WITH_DESC: { // Create the packet reply handler for the current incoming request packetHandler = new WatcherPacketHandler( socket_, senderAddr, wdm->count, WatcherPacketHandler::WP_VERSION_1, false ); char *astr = wdm->string; for(int i=0;i<wdm->count;i++) { wrh_->processWatcherGetRequest( *packetHandler, astr, (wdm->message == WATCHER_MSG_GET_WITH_DESC) ); astr += strlen(astr)+1; } } break; case WATCHER_MSG_GET2: { // Create the packet reply handler for the current incoming request packetHandler = new WatcherPacketHandler( socket_, senderAddr, wdm->count, WatcherPacketHandler::WP_VERSION_2, false ); char *astr = wdm->string; for(int i=0;i<wdm->count;i++) { unsigned int & seqNum = (unsigned int &)*astr; astr += sizeof(unsigned int); wrh_->processWatcherGet2Request( *packetHandler, astr, seqNum ); astr += strlen(astr)+1; } } break; case WATCHER_MSG_SET: { // Create the packet reply handler for the current incoming request packetHandler = new WatcherPacketHandler( socket_, senderAddr, wdm->count, WatcherPacketHandler::WP_VERSION_1, true ); char *astr = wdm->string; for(int i=0;i<wdm->count;i++) { char *bstr = astr + strlen(astr)+1; wrh_->processWatcherSetRequest( *packetHandler, astr,bstr ); astr = bstr + strlen(bstr)+1; } } break; case WATCHER_MSG_SET2: { // Create the packet reply handler for the current incoming request packetHandler = new WatcherPacketHandler( socket_, senderAddr, wdm->count, WatcherPacketHandler::WP_VERSION_2, true ); char *astr = wdm->string; for(int i=0;i<wdm->count;i++) { wrh_->processWatcherSet2Request( *packetHandler, astr ); } } break; default: { Mercury::Address srcAddr( senderAddr.sin_addr.s_addr, senderAddr.sin_port ); WARNING_MSG( "WatcherNub::receiveRequest: " "Unknown message %d from %s\n", wdm->message, srcAddr.c_str() ); } break; } // Start running the packet handler now, it will delete itself when // complete. if (packetHandler) { packetHandler->run(); packetHandler = NULL; } // and we're done! insideReceiveRequest_ = false; return true; }
bool FvNetWatcherNub::ReceiveRequest() { if (!m_bIsInitialised) { return false; } sockaddr_in senderAddr; int len; if (m_pkWRHandler == NULL) { FV_ERROR_MSG( "FvNetWatcherNub::ReceiveRequest: Can't call me before\n" "\tcalling setRequestHandler(WatcherRequestHandler*)\n" ); return false; } if (m_bInsideReceiveRequest) { FV_ERROR_MSG( "FvNetWatcherNub::ReceiveRequest: BAD THING NOTICED:\n" "\tAttempted re-entrant call to receiveRequest\n" ); return false; } m_bInsideReceiveRequest = true; len = m_kSocket.RecvFrom( m_pcRequestPacket, FV_NET_WN_PACKET_SIZE, senderAddr ); if (len == -1) { // EAGAIN = no packets waiting, ECONNREFUSED = rejected outgoing packet #ifdef _WIN32 int err = WSAGetLastError(); if (err != WSAEWOULDBLOCK && err != WSAECONNREFUSED && err != WSAECONNRESET) #else int err = errno; if (err != EAGAIN && err != ECONNREFUSED) #endif { FV_ERROR_MSG( "FvNetWatcherNub::ReceiveRequest: recvfrom failed\n" ); } m_bInsideReceiveRequest = false; return false; } FvNetWatcherDataMsg * wdm = (FvNetWatcherDataMsg*)m_pcRequestPacket; if (len < (int)sizeof(FvNetWatcherDataMsg)) { FV_ERROR_MSG( "FvNetWatcherNub::ReceiveRequest: Packet is too short\n" ); m_bInsideReceiveRequest = false; return false; } if (! (wdm->m_iMessage == FV_NET_WATCHER_MSG_GET || wdm->m_iMessage == FV_NET_WATCHER_MSG_GET_WITH_DESC || wdm->m_iMessage == FV_NET_WATCHER_MSG_SET || wdm->m_iMessage == FV_NET_WATCHER_MSG_GET2 || wdm->m_iMessage == FV_NET_WATCHER_MSG_SET2 ) ) { m_pkWRHandler->ProcessExtensionMessage( wdm->m_iMessage, m_pcRequestPacket + sizeof( wdm->m_iMessage ), len - sizeof( wdm->m_iMessage ), FvNetAddress( senderAddr.sin_addr.s_addr, senderAddr.sin_port ) ); m_bInsideReceiveRequest = false; return true; } FvNetWatcherPacketHandler *packetHandler = NULL; switch (wdm->m_iMessage) { case FV_NET_WATCHER_MSG_GET: case FV_NET_WATCHER_MSG_GET_WITH_DESC: { packetHandler = new FvNetWatcherPacketHandler( m_kSocket, senderAddr, wdm->m_iCount, FvNetWatcherPacketHandler::WP_VERSION_1, false ); char *astr = wdm->m_acString; for(int i=0;i<wdm->m_iCount;i++) { m_pkWRHandler->ProcessWatcherGetRequest( *packetHandler, astr, (wdm->m_iMessage == FV_NET_WATCHER_MSG_GET_WITH_DESC) ); astr += strlen(astr)+1; } } break; case FV_NET_WATCHER_MSG_GET2: { packetHandler = new FvNetWatcherPacketHandler( m_kSocket, senderAddr, wdm->m_iCount, FvNetWatcherPacketHandler::WP_VERSION_2, false ); char *astr = wdm->m_acString; for(int i=0;i<wdm->m_iCount;i++) { unsigned int & seqNum = (unsigned int &)*astr; astr += sizeof(unsigned int); m_pkWRHandler->ProcessWatcherGet2Request( *packetHandler, astr, seqNum ); astr += strlen(astr)+1; } } break; case FV_NET_WATCHER_MSG_SET: { packetHandler = new FvNetWatcherPacketHandler( m_kSocket, senderAddr, wdm->m_iCount, FvNetWatcherPacketHandler::WP_VERSION_1, true ); char *astr = wdm->m_acString; for(int i=0;i<wdm->m_iCount;i++) { char *bstr = astr + strlen(astr)+1; m_pkWRHandler->ProcessWatcherSetRequest( *packetHandler, astr,bstr ); astr = bstr + strlen(bstr)+1; } } break; case FV_NET_WATCHER_MSG_SET2: { packetHandler = new FvNetWatcherPacketHandler( m_kSocket, senderAddr, wdm->m_iCount, FvNetWatcherPacketHandler::WP_VERSION_2, true ); char *astr = wdm->m_acString; for(int i=0;i<wdm->m_iCount;i++) { m_pkWRHandler->ProcessWatcherSet2Request( *packetHandler, astr ); } } break; default: { FvNetAddress srcAddr( senderAddr.sin_addr.s_addr, senderAddr.sin_port ); FV_WARNING_MSG( "FvNetWatcherNub::ReceiveRequest: " "Unknown message %d from %s\n", wdm->m_iMessage, srcAddr.c_str() ); } break; } if (packetHandler) { packetHandler->Run(); packetHandler = NULL; } m_bInsideReceiveRequest = false; return true; }