void CTrackerMainWindow::pause(bool state) { _paused = state; if(_paused) QObject::disconnect(_Listener.get(), SIGNAL(gotPosition(FOBData)), this, SLOT(onReceive(FOBData))); else QObject::connect(_Listener.get(), SIGNAL(gotPosition(FOBData)), SLOT(onReceive(FOBData))); updateControls(); }
void Gosu::MessageSocket::update() { std::vector<char> buffer(maxMessageSize()); sockaddr_in addr; socklen_t size = sizeof addr; for (;;) { int received = ::recvfrom(pimpl->socket.handle(), &buffer.front(), buffer.size(), 0, reinterpret_cast<sockaddr*>(&addr), &size); if (received != SOCKET_ERROR && onReceive) { onReceive(ntohl(addr.sin_addr.s_addr), ntohs(addr.sin_port), &buffer.front(), received); } else switch (lastSocketError()) { // Ignore some of the errors. case GOSU_SOCK_ERR(EWOULDBLOCK): case GOSU_SOCK_ERR(ENETDOWN): case GOSU_SOCK_ERR(ENETRESET): case GOSU_SOCK_ERR(ETIMEDOUT): case GOSU_SOCK_ERR(ECONNRESET): return; // Everything else is unexpected. default: throwLastSocketError(); } } }
int WebSocketImpl::attachSocket(TcpSocketImpl&& tcp, HttpParserImpl&& parser) { is_server_ = true; ws_handler_.setDataCallback([this] (uint8_t* data, uint32_t len) { onWsData(data, len); }); ws_handler_.setHandshakeCallback([this] (int err) { onWsHandshake(err); }); tcp_socket_.setReadCallback([this] (int err) { onReceive(err); }); tcp_socket_.setWriteCallback([this] (int err) { onSend(err); }); tcp_socket_.setErrorCallback([this] (int err) { onClose(err); }); setState(STATE_HANDSHAKE); #ifdef KUMA_HAS_OPENSSL SOCKET_FD fd; SSL* ssl = nullptr; uint32_t flags = tcp.getFlags(); int ret = tcp.detachFd(fd, ssl); ret = tcp_socket_.attachFd(fd, ssl, flags); #else SOCKET_FD fd; uint32_t flags = tcp.getFlags(); int ret = tcp.detachFd(fd); ret = tcp_socket_.attachFd(fd, flags); #endif ws_handler_.setHttpParser(std::move(parser)); return ret; }
bool EReader::processNonBlockingSelect() { fd_set readSet, writeSet, errorSet; struct timeval tval; tval.tv_usec = 100 * 1000; //100 ms tval.tv_sec = 0; if( m_pClientSocket->fd() >= 0 ) { FD_ZERO( &readSet); errorSet = writeSet = readSet; FD_SET( m_pClientSocket->fd(), &readSet); if (m_needsWriteSelect) FD_SET( m_pClientSocket->fd(), &writeSet); FD_SET( m_pClientSocket->fd(), &errorSet); int ret = select( m_pClientSocket->fd() + 1, &readSet, &writeSet, &errorSet, &tval); if( ret == 0) { // timeout return false; } if( ret < 0) { // error m_pClientSocket->eDisconnect(); return false; } if( m_pClientSocket->fd() < 0) return false; if( FD_ISSET( m_pClientSocket->fd(), &errorSet)) { // error on socket m_pClientSocket->onError(); } if( m_pClientSocket->fd() < 0) return false; if( FD_ISSET( m_pClientSocket->fd(), &writeSet)) { // socket is ready for writing onSend(); } if( m_pClientSocket->fd() < 0) return false; if( FD_ISSET( m_pClientSocket->fd(), &readSet)) { // socket is ready for reading onReceive(); } return true; } return false; }
void StreamReceiver::run() { while (input.good()) { std::string line; std::getline(input, line); onReceive(line, sender); } }
void i2c_init(void) { I2C_ADDR_DDR = 0x40; // All pins input I2C_ADDR_PORT = 0x0F; // PC0 - PC3 enable pullup begin(~I2C_ADDR_PIN & 0x0F); onReceive(receiveEvent); onRequest(requestEvent); return; }
int AutoHelper::attachFd(SOCKET_FD fd, uint32_t flags) { flags_ = flags; http_parser_.setDataCallback([this] (const char* data, uint32_t len) { onHttpData(data, len); }); http_parser_.setEventCallback([this] (HttpEvent ev) { onHttpEvent(ev); }); tcp_.setReadCallback([this] (int err) { onReceive(err); }); tcp_.setErrorCallback([this] (int err) { onClose(err); }); return tcp_.attachFd(fd, flags); }
void testOneShotAttributeSubscription(const T& expectedValue, SubscribeTo subscribeTo, ChangeAttribute setAttribute, const std::string& attributeName) { MockSubscriptionListenerOneType<T>* mockListener = new MockSubscriptionListenerOneType<T>(); // Use a semaphore to count and wait on calls to the mock listener ON_CALL(*mockListener, onReceive(Eq(expectedValue))) .WillByDefault(ReleaseSemaphore(&semaphore)); std::shared_ptr<ISubscriptionListener<T>> subscriptionListener( mockListener); std::shared_ptr<tests::DefaulttestProvider> testProvider(new tests::DefaulttestProvider()); runtime1->registerProvider<tests::testProvider>(domainName, testProvider); //This wait is necessary, because registerProvider is async, and a lookup could occur // before the register has finished. std::this_thread::sleep_for(std::chrono::milliseconds(registerProviderWait)); (*testProvider.*setAttribute)(expectedValue, [](){}, [](const joynr::exceptions::ProviderRuntimeException&) {}); ProxyBuilder<tests::testProxy>* testProxyBuilder = runtime2->createProxyBuilder<tests::testProxy>(domainName); DiscoveryQos discoveryQos; discoveryQos.setArbitrationStrategy(DiscoveryQos::ArbitrationStrategy::HIGHEST_PRIORITY); discoveryQos.setDiscoveryTimeout(1000); discoveryQos.setRetryInterval(250); std::int64_t qosRoundTripTTL = 500; // Send a message and expect to get a result tests::testProxy* testProxy = testProxyBuilder ->setMessagingQos(MessagingQos(qosRoundTripTTL)) ->setCached(false) ->setDiscoveryQos(discoveryQos) ->build(); std::int64_t minInterval_ms = 50; OnChangeSubscriptionQos subscriptionQos( 500000, // validity_ms minInterval_ms); // minInterval_ms subscribeTo(testProxy, subscriptionListener, subscriptionQos); waitForAttributeSubscriptionArrivedAtProvider(testProvider, attributeName); // Wait for a subscription message to arrive ASSERT_TRUE(semaphore.waitFor(std::chrono::seconds(3))); delete testProxyBuilder; delete testProxy; }
void ClientSocket::selectEvent() { WSANETWORKEVENTS netEvent; ::ZeroMemory( &netEvent, sizeof( netEvent ) ); ::WSAEventSelect( m_SocketValue, m_RecvEvent, FD_READ | FD_CLOSE ); ::WSAEnumNetworkEvents( m_SocketValue, m_RecvEvent, &netEvent ); if( ( netEvent.lNetworkEvents & FD_READ ) == FD_READ ) onReceive(); else if( ( netEvent.lNetworkEvents & FD_CLOSE ) == FD_CLOSE ) throw NetworkException("ClientSocket::SelectEvent() : 패킷이 닫혔다네"); }
void ISend::msg_handler(unsigned char *dat, unsigned char len) { unsigned char ret; ret = strncmp(item, (const char *)&dat[4], strlen(item)); if (ret == 0) if (getStatus() == S_S) { setStatus(S_A); memcpy(strRec, dat, len); strRecLen = len; onReceive(dat, len); } }
bool Form1::qt_invoke( int _id, QUObject* _o ) { switch ( _id - staticMetaObject()->slotOffset() ) { case 0: init_var(); break; case 1: btnConnect_clicked(); break; case 2: onReceive(); break; case 3: btnInit_clicked(); break; case 4: btnSave_clicked(); break; case 5: languageChange(); break; case 6: onTimer(); break; default: return QDialog::qt_invoke( _id, _o ); } return TRUE; }
int WebSocketImpl::attachFd(SOCKET_FD fd, uint32_t flags, const uint8_t* init_data, uint32_t init_len) { is_server_ = true; if(init_data && init_len > 0) { init_data = new uint8_t(init_len); memcpy(init_data_, init_data, init_len); init_len_ = init_len; } ws_handler_.setDataCallback([this] (uint8_t* data, uint32_t len) { onWsData(data, len); }); ws_handler_.setHandshakeCallback([this] (int err) { onWsHandshake(err); }); tcp_socket_.setReadCallback([this] (int err) { onReceive(err); }); tcp_socket_.setWriteCallback([this] (int err) { onSend(err); }); tcp_socket_.setErrorCallback([this] (int err) { onClose(err); }); setState(STATE_HANDSHAKE); return tcp_socket_.attachFd(fd, flags); }
FileConveyor::FileConveyor(QWidget *parent) : QWidget(parent), ui(new Ui::FileConveyor) { ui->setupUi(this); sender = new Sender; ui->stackedWidget->addWidget(sender); receiver = new Receiver; ui->stackedWidget->addWidget(receiver); connect(ui->sendPushButton, SIGNAL(clicked()), this, SLOT(onSending())); connect(sender, SIGNAL(finished()), this, SLOT(onFinished())); connect(sender, SIGNAL(error()), this, SLOT(onError())); connect(ui->recvPushButton, SIGNAL(clicked()), this, SLOT(onReceive())); connect(receiver, SIGNAL(finished()), this, SLOT(onFinished())); connect(receiver, SIGNAL(error()), this, SLOT(onError())); }
CTrackerMainWindow::CTrackerMainWindow(QWidget *parent, Qt::WFlags flags): QMainWindow(parent, flags), _paused(false), _muted(false), _UDP(IP, PORT), _Listener(new CTrackerFOBListener()) { ui.setupUi(this); QHBoxLayout *hLayout = new QHBoxLayout(ui.fRotation); hLayout->setSpacing(0); hLayout->setMargin(0); _RotationPreview = new CRotationPreview(); QPalette palette; palette.setColor(_RotationPreview->backgroundRole(), Qt::black); _RotationPreview->setAutoFillBackground(true); _RotationPreview->setPalette(palette); hLayout->addWidget(_RotationPreview); ui.cbHemisphere->clear(); ui.cbHemisphere->addItem("Front", QVariant(BHC_FRONT)); ui.cbHemisphere->addItem("Rear", QVariant(BHC_REAR)); ui.cbHemisphere->addItem("Upper", QVariant(BHC_UPPER)); ui.cbHemisphere->addItem("Lower", QVariant(BHC_LOWER)); ui.cbHemisphere->addItem("Left", QVariant(BHC_LEFT)); ui.cbHemisphere->addItem("Right", QVariant(BHC_RIGHT)); ui.cbHemisphere->setCurrentIndex(3); ui.cbBaudRate->setCurrentIndex(ui.cbBaudRate->count() - 1); ui.tRotation->horizontalHeader()->hide(); ui.tRotation->verticalHeader()->hide(); ui.tRotation->setColumnWidth(0, 75); ui.tRotation->setColumnWidth(1, 75); ui.tRotation->setColumnWidth(2, 75); ui.tRotation->setRowHeight(0, 20); ui.tRotation->setRowHeight(1, 20); ui.tRotation->setRowHeight(2, 20); for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) ui.tRotation->setItem(i, j, new QTableWidgetItem(QString::number(i == j? 1.0 : 0.0), 0)); updateControls(); QObject::connect(_Listener.get(), SIGNAL(gotPosition(FOBData)), SLOT(onReceive(FOBData))); QObject::connect(_Listener.get(), SIGNAL(Error(QString)), SLOT(onError(QString))); }
bool P2pRpcNetwork::handleMessage(PeerId peerId, const ACE_INET_Addr& peerAddr) { const P2pPeerHint hint(peerId, &peerAddr); try { onReceive(*istream_, &hint); } catch (const srpc::Exception& e) { NSRPC_LOG_DEBUG3( ACE_TEXT("P2pRpcNetwork::handleMessage(P%u) FAILED(%s)."), peerId, e.what()); return false; } istream_->reset(true); return true; }
void XYTCPSocketLayer::ReadSocket() { while(_IsReadThreadRunning) { usleep(5000); if(!_IsReadThreadRunning) { break; } char* pOut = new char[MAX_BYTE_READ_ONCE]; ssize_t readSize = Readn(_fd, pOut, MAX_BYTE_READ_ONCE); if(readSize > 0) { //dispatch data onReceive(pOut, readSize); bzero(pOut, MAX_BYTE_READ_ONCE); delete [] pOut; } else if(readSize == 0) { //dispatch disconnect onDisconnect(XYNetworkErrorCode(XYNetworkErrorCode::eXYNetworkErrorCode::SERVER_DISCONNECT)); bzero(pOut, MAX_BYTE_READ_ONCE); delete [] pOut; _IsReadThreadRunning = false; _stat = States_Disconnected; break; } else { //dispatch read error onError(XYNetworkErrorCode(XYNetworkErrorCode::eXYNetworkErrorCode::READ_ERROR)); bzero(pOut, MAX_BYTE_READ_ONCE); delete [] pOut; } } return; }
void ISend::msg_handler(unsigned char *dat, unsigned char len) { unsigned char ret; // ret = strncmp((char *)&item[1], (const char *)&dat[4], item_len-1); ret = compare_keyword(dat); if (ret == 0) { if (getStatus() == S_S) { setStatus(S_A); /*返回结果,打出来*/ /*处理所有接收回来的应答码*/ clearAckData(); strncpy((char *)strAck, (const char *)&dat[4+item_len], len-4-item_len); strAckLen = len -4-item_len; onReceive(dat, len); } } }
void ClientSocket::handleReceive() { memset(m_packetBuf, 0, m_maxPacketSize); int ret = 0; ret = recv(m_socket, m_packetBuf, m_maxPacketSize, 0); if(ret< 0) { printf("recv() failed! error:%d\n", WSAGetLastError()); m_socketState = InvalidState; closesocket(m_socket); return; } if(ret == 0) return; //把数据写入缓存里 onReceive(m_packetBuf, ret); }
void Server::update() { if (!mNewSocket) { mNewSocket = std::make_unique<sf::TcpSocket>(); } if (mListener.accept(*mNewSocket) == sf::TcpListener::Done) { if (onConnect) onConnect(*this, mSocketId); mNewSocket->setBlocking(false); mSockets[mSocketId++].reset(mNewSocket.release()); } sf::Packet packet; for (auto it = mSockets.begin(); it != mSockets.end();) { auto& socket = *it->second; const auto status = socket.receive(packet); if (status == sf::TcpSocket::Done) { if (onReceive) onReceive(*this, it->first, packet); } else if (status == sf::TcpSocket::Disconnected) { if (onDisonnect) onDisonnect(*this, it->first); socket.disconnect(); mSockets.erase(it++); continue; } ++it; } }
int WebSocketImpl::connect_i(const std::string& ws_url) { if(!uri_.parse(ws_url)) { return false; } tcp_socket_.setReadCallback([this] (int err) { onReceive(err); }); tcp_socket_.setWriteCallback([this] (int err) { onSend(err); }); tcp_socket_.setErrorCallback([this] (int err) { onClose(err); }); setState(STATE_CONNECTING); std::string str_port = uri_.getPort(); uint16_t port = 80; uint32_t flag = 0; if(is_equal("wss", uri_.getScheme())) { port = 443; flag = FLAG_HAS_SSL; } if(!str_port.empty()) { port = atoi(str_port.c_str()); } return tcp_socket_.connect(uri_.getHost().c_str(), port, [this] (int err) { onConnect(err); }, flag); }
void ServerClient::tick() { if(m_server) for (RakNet::Packet* p = m_server->Receive(); p; m_server->DeallocatePacket(p), p=m_server->Receive()) { // We got a packet, get the identifier with our handy function unsigned char packetIdentifier = GetPacketIdentifierC(p); //std::cout << (int)packetIdentifier << std::endl; // Check if this is a network message packet if(m_bgMode) { m_packets.push_back(ServerPacket()); m_packets.back().packetID = packetIdentifier; for(int i = 0; i < p->length; i++) { m_packets.back().message.push_back(p->data[i]); } continue; } switch (packetIdentifier) { case ID_DISCONNECTION_NOTIFICATION: case ID_CONNECTION_LOST: // Connection lost normally printf("ID_DISCONNECTION_NOTIFICATION\n"); m_connected = false; m_connecting = false; onDisconnect(); if(m_needsToConnect) { connect(); m_needsToConnect = false; } break; case ID_ALREADY_CONNECTED: // Connection lost normally printf("ID_ALREADY_CONNECTED with guid %" PRINTF_64_BIT_MODIFIER "u\n", p->guid); onFailedToConnect(false); break; case ID_INCOMPATIBLE_PROTOCOL_VERSION: printf("ID_INCOMPATIBLE_PROTOCOL_VERSION\n"); break; case ID_CONNECTION_BANNED: // Banned from this server printf("We are banned from this server.\n"); break; case ID_CONNECTION_ATTEMPT_FAILED: printf("Connection attempt failed\n"); m_connecting = false; m_connected = false; onFailedToConnect(false); break; case ID_NO_FREE_INCOMING_CONNECTIONS: // Sorry, the server is full. I don't do anything here but // A real app should tell the user printf("ID_NO_FREE_INCOMING_CONNECTIONS\n"); break; case ID_INVALID_PASSWORD: printf("ID_INVALID_PASSWORD\n"); break; case ID_CONNECTION_REQUEST_ACCEPTED: // This tells the client they have connected m_connecting = false; m_connected = true; m_needsToConnect = false; m_client.initClient(m_server,p->guid,p->systemAddress); onConnect(); break; case ID_CONNECTED_PING: case ID_UNCONNECTED_PING: printf("Ping from %s\n", p->systemAddress.ToString(true)); break; case ID_USER_PACKET_ENUM: { RakNet::RakString rs; RakNet::BitStream bsIn(p->data,p->length,false); bsIn.IgnoreBytes(sizeof(RakNet::MessageID)); bsIn.Read(rs); onReceive(rs.C_String(),rs.GetLength()); } break; default: break; } } }
void RTCPInstance::incomingReportHandler1() { do { Boolean callByeHandler = False; int tcpReadStreamSocketNum = fRTCPInterface.nextTCPReadStreamSocketNum(); unsigned char tcpReadStreamChannelId = fRTCPInterface.nextTCPReadStreamChannelId(); unsigned packetSize = 0; unsigned numBytesRead; struct sockaddr_in fromAddress; Boolean packetReadWasIncomplete; if (fNumBytesAlreadyRead >= maxRTCPPacketSize) { envir() << "RTCPInstance error: Hit limit when reading incoming packet over TCP. Increase \"maxRTCPPacketSize\"\n"; break; } Boolean readResult = fRTCPInterface.handleRead(&fInBuf[fNumBytesAlreadyRead], maxRTCPPacketSize - fNumBytesAlreadyRead, numBytesRead, fromAddress, packetReadWasIncomplete); if (packetReadWasIncomplete) { fNumBytesAlreadyRead += numBytesRead; return; // more reads are needed to get the entire packet } else { // normal case: We've read the entire packet packetSize = fNumBytesAlreadyRead + numBytesRead; fNumBytesAlreadyRead = 0; // for next time } if (!readResult) break; // Ignore the packet if it was looped-back from ourself: Boolean packetWasFromOurHost = False; if (RTCPgs()->wasLoopedBackFromUs(envir(), fromAddress)) { packetWasFromOurHost = True; // However, we still want to handle incoming RTCP packets from // *other processes* on the same machine. To distinguish this // case from a true loop-back, check whether we've just sent a // packet of the same size. (This check isn't perfect, but it seems // to be the best we can do.) if (fHaveJustSentPacket && fLastPacketSentSize == packetSize) { // This is a true loop-back: fHaveJustSentPacket = False; break; // ignore this packet } } unsigned char* pkt = fInBuf; if (fIsSSMSource && !packetWasFromOurHost) { // This packet is assumed to have been received via unicast (because we're a SSM source, and SSM receivers send back RTCP "RR" // packets via unicast). 'Reflect' the packet by resending it to the multicast group, so that any other receivers can also // get to see it. // NOTE: Denial-of-service attacks are possible here. // Users of this software may wish to add their own, // application-specific mechanism for 'authenticating' the // validity of this packet before reflecting it. // NOTE: The test for "!packetWasFromOurHost" means that we won't reflect RTCP packets that come from other processes on // the same host as us. The reason for this is that the 'packet size' test above is not 100% reliable; some packets // that were truly looped back from us might not be detected as such, and this might lead to infinite forwarding/receiving // of some packets. To avoid this possibility, we only reflect RTCP packets that we know for sure originated elsewhere. // (Note, though, that if we ever re-enable the code in "Groupsock::multicastSendOnly()", then we could remove the test for // "!packetWasFromOurHost".) fRTCPInterface.sendPacket(pkt, packetSize); fHaveJustSentPacket = True; fLastPacketSentSize = packetSize; } #ifdef DEBUG fprintf(stderr, "[%p]saw incoming RTCP packet", this); if (tcpReadStreamSocketNum < 0) { // Note that "fromAddress" is valid only if we're receiving over UDP (not over TCP): fprintf(stderr, " (from address %s, port %d)", AddressString(fromAddress).val(), ntohs(fromAddress.sin_port)); } fprintf(stderr, "\n"); for (unsigned i = 0; i < packetSize; ++i) { if (i%4 == 0) fprintf(stderr, " "); fprintf(stderr, "%02x", pkt[i]); } fprintf(stderr, "\n"); #endif int totPacketSize = IP_UDP_HDR_SIZE + packetSize; // Check the RTCP packet for validity: // It must at least contain a header (4 bytes), and this header // must be version=2, with no padding bit, and a payload type of // SR (200) or RR (201): if (packetSize < 4) break; unsigned rtcpHdr = ntohl(*(u_int32_t*)pkt); if ((rtcpHdr & 0xE0FE0000) != (0x80000000 | (RTCP_PT_SR<<16))) { #ifdef DEBUG fprintf(stderr, "rejected bad RTCP packet: header 0x%08x\n", rtcpHdr); #endif break; } // Process each of the individual RTCP 'subpackets' in (what may be) // a compound RTCP packet. int typeOfPacket = PACKET_UNKNOWN_TYPE; unsigned reportSenderSSRC = 0; Boolean packetOK = False; while (1) { unsigned rc = (rtcpHdr>>24)&0x1F; unsigned pt = (rtcpHdr>>16)&0xFF; unsigned length = 4*(rtcpHdr&0xFFFF); // doesn't count hdr ADVANCE(4); // skip over the header if (length > packetSize) break; // Assume that each RTCP subpacket begins with a 4-byte SSRC: if (length < 4) break; length -= 4; reportSenderSSRC = ntohl(*(u_int32_t*)pkt); ADVANCE(4); Boolean subPacketOK = False; switch (pt) { case RTCP_PT_SR: { #ifdef DEBUG fprintf(stderr, "SR\n"); #endif if (length < 20) break; length -= 20; // Extract the NTP timestamp, and note this: unsigned NTPmsw = ntohl(*(u_int32_t*)pkt); ADVANCE(4); unsigned NTPlsw = ntohl(*(u_int32_t*)pkt); ADVANCE(4); unsigned rtpTimestamp = ntohl(*(u_int32_t*)pkt); ADVANCE(4); if (fSource != NULL) { RTPReceptionStatsDB& receptionStats = fSource->receptionStatsDB(); receptionStats.noteIncomingSR(reportSenderSSRC, NTPmsw, NTPlsw, rtpTimestamp); } ADVANCE(8); // skip over packet count, octet count // If a 'SR handler' was set, call it now: if (fSRHandlerTask != NULL) (*fSRHandlerTask)(fSRHandlerClientData); // The rest of the SR is handled like a RR (so, no "break;" here) } case RTCP_PT_RR: { #ifdef DEBUG fprintf(stderr, "RR\n"); #endif unsigned reportBlocksSize = rc*(6*4); if (length < reportBlocksSize) break; length -= reportBlocksSize; if (fSink != NULL) { // Use this information to update stats about our transmissions: RTPTransmissionStatsDB& transmissionStats = fSink->transmissionStatsDB(); for (unsigned i = 0; i < rc; ++i) { unsigned senderSSRC = ntohl(*(u_int32_t*)pkt); ADVANCE(4); // We care only about reports about our own transmission, not others' if (senderSSRC == fSink->SSRC()) { unsigned lossStats = ntohl(*(u_int32_t*)pkt); ADVANCE(4); unsigned highestReceived = ntohl(*(u_int32_t*)pkt); ADVANCE(4); unsigned jitter = ntohl(*(u_int32_t*)pkt); ADVANCE(4); unsigned timeLastSR = ntohl(*(u_int32_t*)pkt); ADVANCE(4); unsigned timeSinceLastSR = ntohl(*(u_int32_t*)pkt); ADVANCE(4); transmissionStats.noteIncomingRR(reportSenderSSRC, fromAddress, lossStats, highestReceived, jitter, timeLastSR, timeSinceLastSR); } else { ADVANCE(4*5); } } } else { ADVANCE(reportBlocksSize); } if (pt == RTCP_PT_RR) { // i.e., we didn't fall through from 'SR' // If a 'RR handler' was set, call it now: // Specific RR handler: if (fSpecificRRHandlerTable != NULL) { netAddressBits fromAddr; portNumBits fromPortNum; if (tcpReadStreamSocketNum < 0) { // Normal case: We read the RTCP packet over UDP fromAddr = fromAddress.sin_addr.s_addr; fromPortNum = ntohs(fromAddress.sin_port); } else { // Special case: We read the RTCP packet over TCP (interleaved) // Hack: Use the TCP socket and channel id to look up the handler fromAddr = tcpReadStreamSocketNum; fromPortNum = tcpReadStreamChannelId; } Port fromPort(fromPortNum); RRHandlerRecord* rrHandler = (RRHandlerRecord*)(fSpecificRRHandlerTable->Lookup(fromAddr, (~0), fromPort)); if (rrHandler != NULL) { if (rrHandler->rrHandlerTask != NULL) { (*(rrHandler->rrHandlerTask))(rrHandler->rrHandlerClientData); } } } // General RR handler: if (fRRHandlerTask != NULL) (*fRRHandlerTask)(fRRHandlerClientData); } subPacketOK = True; typeOfPacket = PACKET_RTCP_REPORT; break; } case RTCP_PT_BYE: { #ifdef DEBUG fprintf(stderr, "BYE\n"); #endif // If a 'BYE handler' was set, arrange for it to be called at the end of this routine. // (Note: We don't call it immediately, in case it happens to cause "this" to be deleted.) if (fByeHandlerTask != NULL && (!fByeHandleActiveParticipantsOnly || (fSource != NULL && fSource->receptionStatsDB().lookup(reportSenderSSRC) != NULL) || (fSink != NULL && fSink->transmissionStatsDB().lookup(reportSenderSSRC) != NULL))) { callByeHandler = True; } // We should really check for & handle >1 SSRCs being present ##### subPacketOK = True; typeOfPacket = PACKET_BYE; break; } // Later handle SDES, APP, and compound RTCP packets ##### default: #ifdef DEBUG fprintf(stderr, "UNSUPPORTED TYPE(0x%x)\n", pt); #endif subPacketOK = True; break; } if (!subPacketOK) break; // need to check for (& handle) SSRC collision! ##### #ifdef DEBUG fprintf(stderr, "validated RTCP subpacket (type %d): %d, %d, %d, 0x%08x\n", typeOfPacket, rc, pt, length, reportSenderSSRC); #endif // Skip over any remaining bytes in this subpacket: ADVANCE(length); // Check whether another RTCP 'subpacket' follows: if (packetSize == 0) { packetOK = True; break; } else if (packetSize < 4) { #ifdef DEBUG fprintf(stderr, "extraneous %d bytes at end of RTCP packet!\n", packetSize); #endif break; } rtcpHdr = ntohl(*(u_int32_t*)pkt); if ((rtcpHdr & 0xC0000000) != 0x80000000) { #ifdef DEBUG fprintf(stderr, "bad RTCP subpacket: header 0x%08x\n", rtcpHdr); #endif break; } } if (!packetOK) { #ifdef DEBUG fprintf(stderr, "rejected bad RTCP subpacket: header 0x%08x\n", rtcpHdr); #endif break; } else { #ifdef DEBUG fprintf(stderr, "validated entire RTCP packet\n"); #endif } onReceive(typeOfPacket, totPacketSize, reportSenderSSRC); // Finally, if we need to call a "BYE" handler, do so now (in case it causes "this" to get deleted): if (callByeHandler && fByeHandlerTask != NULL/*sanity check*/) { TaskFunc* byeHandler = fByeHandlerTask; fByeHandlerTask = NULL; // because we call the handler only once, by default (*byeHandler)(fByeHandlerClientData); } } while (0); }
void ServerClient::execBG() { if(m_server) for (int i = 0; i < m_packets.size(); ++i) { // We got a packet, get the identifier with our handy function unsigned char packetIdentifier = m_packets[i].packetID; //std::cout << (int)packetIdentifier << std::endl; // Check if this is a network message packet switch (packetIdentifier) { case ID_DISCONNECTION_NOTIFICATION: case ID_CONNECTION_LOST: // Connection lost normally printf("ID_DISCONNECTION_NOTIFICATION\n"); m_connected = false; m_connecting = false; onDisconnect(); if(m_needsToConnect) { connect(); m_needsToConnect = false; } break; case ID_ALREADY_CONNECTED: // Connection lost normally onFailedToConnect(false); break; case ID_INCOMPATIBLE_PROTOCOL_VERSION: printf("ID_INCOMPATIBLE_PROTOCOL_VERSION\n"); break; case ID_CONNECTION_BANNED: // Banned from this server printf("We are banned from this server.\n"); break; case ID_CONNECTION_ATTEMPT_FAILED: printf("Connection attempt failed\n"); m_connecting = false; m_connected = false; onFailedToConnect(false); break; case ID_NO_FREE_INCOMING_CONNECTIONS: // Sorry, the server is full. I don't do anything here but // A real app should tell the user printf("ID_NO_FREE_INCOMING_CONNECTIONS\n"); break; case ID_INVALID_PASSWORD: printf("ID_INVALID_PASSWORD\n"); break; case ID_CONNECTION_REQUEST_ACCEPTED: // This tells the client they have connected // m_connecting = false; // m_connected = true; //m_needsToConnect = false; //m_client.initClient(m_server,p->guid,p->systemAddress); // onConnect(); break; case ID_CONNECTED_PING: case ID_UNCONNECTED_PING: // printf("Ping from %s\n", p->systemAddress.ToString(true)); break; case ID_USER_PACKET_ENUM: { RakNet::RakString rs; RakNet::BitStream bsIn(&m_packets[i].message[0],m_packets[i].message.size(),false); bsIn.IgnoreBytes(sizeof(RakNet::MessageID)); bsIn.Read(rs); onReceive(rs.C_String(),rs.GetLength()); } break; default: break; } } m_packets.clear(); m_bgMode = false; }
void RTCPInstance ::processIncomingReport(unsigned packetSize, struct sockaddr_in const& fromAddress, int tcpSocketNum, unsigned char tcpStreamChannelId) { do { Boolean callByeHandler = False; unsigned char* pkt = fInBuf; #ifdef DEBUG fprintf(stderr, "[%p]saw incoming RTCP packet (from ", this); if (tcpSocketNum < 0) { // Note that "fromAddress" is valid only if we're receiving over UDP (not over TCP): fprintf(stderr, "address %s, port %d", AddressString(fromAddress).val(), ntohs(fromAddress.sin_port)); } else { fprintf(stderr, "TCP socket #%d, stream channel id %d", tcpSocketNum, tcpStreamChannelId); } fprintf(stderr, ")\n"); for (unsigned i = 0; i < packetSize; ++i) { if (i%4 == 0) fprintf(stderr, " "); fprintf(stderr, "%02x", pkt[i]); } fprintf(stderr, "\n"); #endif int totPacketSize = IP_UDP_HDR_SIZE + packetSize; // Check the RTCP packet for validity: // It must at least contain a header (4 bytes), and this header // must be version=2, with no padding bit, and a payload type of // SR (200) or RR (201): if (packetSize < 4) break; unsigned rtcpHdr = ntohl(*(u_int32_t*)pkt); if ((rtcpHdr & 0xE0FE0000) != (0x80000000 | (RTCP_PT_SR<<16))) { #ifdef DEBUG fprintf(stderr, "rejected bad RTCP packet: header 0x%08x\n", rtcpHdr); #endif break; } // Process each of the individual RTCP 'subpackets' in (what may be) // a compound RTCP packet. int typeOfPacket = PACKET_UNKNOWN_TYPE; unsigned reportSenderSSRC = 0; Boolean packetOK = False; while (1) { unsigned rc = (rtcpHdr>>24)&0x1F; unsigned pt = (rtcpHdr>>16)&0xFF; unsigned length = 4*(rtcpHdr&0xFFFF); // doesn't count hdr ADVANCE(4); // skip over the header if (length > packetSize) break; // Assume that each RTCP subpacket begins with a 4-byte SSRC: if (length < 4) break; length -= 4; reportSenderSSRC = ntohl(*(u_int32_t*)pkt); ADVANCE(4); Boolean subPacketOK = False; switch (pt) { case RTCP_PT_SR: { #ifdef DEBUG fprintf(stderr, "SR\n"); #endif if (length < 20) break; length -= 20; // Extract the NTP timestamp, and note this: unsigned NTPmsw = ntohl(*(u_int32_t*)pkt); ADVANCE(4); unsigned NTPlsw = ntohl(*(u_int32_t*)pkt); ADVANCE(4); unsigned rtpTimestamp = ntohl(*(u_int32_t*)pkt); ADVANCE(4); if (fSource != NULL) { RTPReceptionStatsDB& receptionStats = fSource->receptionStatsDB(); receptionStats.noteIncomingSR(reportSenderSSRC, NTPmsw, NTPlsw, rtpTimestamp); } ADVANCE(8); // skip over packet count, octet count // If a 'SR handler' was set, call it now: if (fSRHandlerTask != NULL) (*fSRHandlerTask)(fSRHandlerClientData); // The rest of the SR is handled like a RR (so, no "break;" here) } case RTCP_PT_RR: { #ifdef DEBUG fprintf(stderr, "RR\n"); #endif unsigned reportBlocksSize = rc*(6*4); if (length < reportBlocksSize) break; length -= reportBlocksSize; if (fSink != NULL) { // Use this information to update stats about our transmissions: RTPTransmissionStatsDB& transmissionStats = fSink->transmissionStatsDB(); for (unsigned i = 0; i < rc; ++i) { unsigned senderSSRC = ntohl(*(u_int32_t*)pkt); ADVANCE(4); // We care only about reports about our own transmission, not others' if (senderSSRC == fSink->SSRC()) { unsigned lossStats = ntohl(*(u_int32_t*)pkt); ADVANCE(4); unsigned highestReceived = ntohl(*(u_int32_t*)pkt); ADVANCE(4); unsigned jitter = ntohl(*(u_int32_t*)pkt); ADVANCE(4); unsigned timeLastSR = ntohl(*(u_int32_t*)pkt); ADVANCE(4); unsigned timeSinceLastSR = ntohl(*(u_int32_t*)pkt); ADVANCE(4); transmissionStats.noteIncomingRR(reportSenderSSRC, fromAddress, lossStats, highestReceived, jitter, timeLastSR, timeSinceLastSR); } else { ADVANCE(4*5); } } } else { ADVANCE(reportBlocksSize); } if (pt == RTCP_PT_RR) { // i.e., we didn't fall through from 'SR' // If a 'RR handler' was set, call it now: // Specific RR handler: if (fSpecificRRHandlerTable != NULL) { netAddressBits fromAddr; portNumBits fromPortNum; if (tcpSocketNum < 0) { // Normal case: We read the RTCP packet over UDP fromAddr = fromAddress.sin_addr.s_addr; fromPortNum = ntohs(fromAddress.sin_port); } else { // Special case: We read the RTCP packet over TCP (interleaved) // Hack: Use the TCP socket and channel id to look up the handler fromAddr = tcpSocketNum; fromPortNum = tcpStreamChannelId; } Port fromPort(fromPortNum); RRHandlerRecord* rrHandler = (RRHandlerRecord*)(fSpecificRRHandlerTable->Lookup(fromAddr, (~0), fromPort)); if (rrHandler != NULL) { if (rrHandler->rrHandlerTask != NULL) { (*(rrHandler->rrHandlerTask))(rrHandler->rrHandlerClientData); } } } // General RR handler: if (fRRHandlerTask != NULL) (*fRRHandlerTask)(fRRHandlerClientData); } subPacketOK = True; typeOfPacket = PACKET_RTCP_REPORT; break; } case RTCP_PT_BYE: { #ifdef DEBUG fprintf(stderr, "BYE\n"); #endif // If a 'BYE handler' was set, arrange for it to be called at the end of this routine. // (Note: We don't call it immediately, in case it happens to cause "this" to be deleted.) if (fByeHandlerTask != NULL && (!fByeHandleActiveParticipantsOnly || (fSource != NULL && fSource->receptionStatsDB().lookup(reportSenderSSRC) != NULL) || (fSink != NULL && fSink->transmissionStatsDB().lookup(reportSenderSSRC) != NULL))) { callByeHandler = True; } // We should really check for & handle >1 SSRCs being present ##### subPacketOK = True; typeOfPacket = PACKET_BYE; break; } // Other RTCP packet types that we don't yet handle: case RTCP_PT_SDES: { #ifdef DEBUG // 'Handle' SDES packets only in debugging code, by printing out the 'SDES items': fprintf(stderr, "SDES\n"); // Process each 'chunk': Boolean chunkOK = False; ADVANCE(-4); length += 4; // hack so that we see the first SSRC/CSRC again while (length >= 8) { // A valid chunk must be at least 8 bytes long chunkOK = False; // until we learn otherwise u_int32_t SSRC_CSRC = ntohl(*(u_int32_t*)pkt); ADVANCE(4); length -= 4; fprintf(stderr, "\tSSRC/CSRC: 0x%08x\n", SSRC_CSRC); // Process each 'SDES item' in the chunk: u_int8_t itemType = *pkt; ADVANCE(1); --length; while (itemType != 0) { unsigned itemLen = *pkt; ADVANCE(1); --length; // Make sure "itemLen" allows for at least 1 zero byte at the end of the chunk: if (itemLen + 1 > length || pkt[itemLen] != 0) break; fprintf(stderr, "\t\t%s:%s\n", itemType == 1 ? "CNAME" : itemType == 2 ? "NAME" : itemType == 3 ? "EMAIL" : itemType == 4 ? "PHONE" : itemType == 5 ? "LOC" : itemType == 6 ? "TOOL" : itemType == 7 ? "NOTE" : itemType == 8 ? "PRIV" : "(unknown)", itemType < 8 ? (char*)pkt // hack, because we know it's '\0'-terminated : "???"/* don't try to print out PRIV or unknown items */); ADVANCE(itemLen); length -= itemLen; itemType = *pkt; ADVANCE(1); --length; } if (itemType != 0) break; // bad 'SDES item' // Thus, itemType == 0. This zero 'type' marks the end of the list of SDES items. // Skip over remaining zero padding bytes, so that this chunk ends on a 4-byte boundary: while (length%4 > 0 && *pkt == 0) { ADVANCE(1); --length; } if (length%4 > 0) break; // Bad (non-zero) padding byte chunkOK = True; } if (!chunkOK || length > 0) break; // bad chunk, or not enough bytes for the last chunk #endif subPacketOK = True; break; } case RTCP_PT_APP: { #ifdef DEBUG fprintf(stderr, "APP(unhandled)\n"); #endif subPacketOK = True; break; } case RTCP_PT_RTPFB: { #ifdef DEBUG fprintf(stderr, "RTPFB(unhandled)\n"); #endif subPacketOK = True; break; } case RTCP_PT_PSFB: { #ifdef DEBUG fprintf(stderr, "PSFB(unhandled)\n"); // Temporary code to show "Receiver Estimated Maximum Bitrate" (REMB) feedback reports: //##### if (length >= 12 && pkt[4] == 'R' && pkt[5] == 'E' && pkt[6] == 'M' && pkt[7] == 'B') { u_int8_t exp = pkt[9]>>2; u_int32_t mantissa = ((pkt[9]&0x03)<<16)|(pkt[10]<<8)|pkt[11]; double remb = (double)mantissa; while (exp > 0) { remb *= 2.0; exp /= 2; } fprintf(stderr, "\tReceiver Estimated Max Bitrate (REMB): %g bps\n", remb); } #endif subPacketOK = True; break; } case RTCP_PT_XR: { #ifdef DEBUG fprintf(stderr, "XR(unhandled)\n"); #endif subPacketOK = True; break; } case RTCP_PT_AVB: { #ifdef DEBUG fprintf(stderr, "AVB(unhandled)\n"); #endif subPacketOK = True; break; } case RTCP_PT_RSI: { #ifdef DEBUG fprintf(stderr, "RSI(unhandled)\n"); #endif subPacketOK = True; break; } case RTCP_PT_TOKEN: { #ifdef DEBUG fprintf(stderr, "TOKEN(unhandled)\n"); #endif subPacketOK = True; break; } case RTCP_PT_IDMS: { #ifdef DEBUG fprintf(stderr, "IDMS(unhandled)\n"); #endif subPacketOK = True; break; } default: { #ifdef DEBUG fprintf(stderr, "UNKNOWN TYPE(0x%x)\n", pt); #endif subPacketOK = True; break; } } if (!subPacketOK) break; // need to check for (& handle) SSRC collision! ##### #ifdef DEBUG fprintf(stderr, "validated RTCP subpacket: rc:%d, pt:%d, bytes remaining:%d, report sender SSRC:0x%08x\n", rc, pt, length, reportSenderSSRC); #endif // Skip over any remaining bytes in this subpacket: ADVANCE(length); // Check whether another RTCP 'subpacket' follows: if (packetSize == 0) { packetOK = True; break; } else if (packetSize < 4) { #ifdef DEBUG fprintf(stderr, "extraneous %d bytes at end of RTCP packet!\n", packetSize); #endif break; } rtcpHdr = ntohl(*(u_int32_t*)pkt); if ((rtcpHdr & 0xC0000000) != 0x80000000) { #ifdef DEBUG fprintf(stderr, "bad RTCP subpacket: header 0x%08x\n", rtcpHdr); #endif break; } } if (!packetOK) { #ifdef DEBUG fprintf(stderr, "rejected bad RTCP subpacket: header 0x%08x\n", rtcpHdr); #endif break; } else { #ifdef DEBUG fprintf(stderr, "validated entire RTCP packet\n"); #endif } onReceive(typeOfPacket, totPacketSize, reportSenderSSRC); // Finally, if we need to call a "BYE" handler, do so now (in case it causes "this" to get deleted): if (callByeHandler && fByeHandlerTask != NULL/*sanity check*/) { TaskFunc* byeHandler = fByeHandlerTask; fByeHandlerTask = NULL; // because we call the handler only once, by default (*byeHandler)(fByeHandlerClientData); } } while (0);
void RTCPInstance ::processIncomingReport(unsigned packetSize, struct sockaddr_in const& fromAddress) { do { Boolean callByeHandler = False; int tcpReadStreamSocketNum = fRTCPInterface.nextTCPReadStreamSocketNum(); unsigned char tcpReadStreamChannelId = fRTCPInterface.nextTCPReadStreamChannelId(); unsigned char* pkt = fInBuf; #ifdef DEBUG fprintf(stderr, "[%p]saw incoming RTCP packet", this); if (tcpReadStreamSocketNum < 0) { // Note that "fromAddress" is valid only if we're receiving over UDP (not over TCP): fprintf(stderr, " (from address %s, port %d)", AddressString(fromAddress).val(), ntohs(fromAddress.sin_port)); } fprintf(stderr, "\n"); for (unsigned i = 0; i < packetSize; ++i) { if (i%4 == 0) fprintf(stderr, " "); fprintf(stderr, "%02x", pkt[i]); } fprintf(stderr, "\n"); #endif int totPacketSize = IP_UDP_HDR_SIZE + packetSize; // Check the RTCP packet for validity: // It must at least contain a header (4 bytes), and this header // must be version=2, with no padding bit, and a payload type of // SR (200) or RR (201): if (packetSize < 4) break; unsigned rtcpHdr = ntohl(*(u_int32_t*)pkt); if ((rtcpHdr & 0xE0FE0000) != (0x80000000 | (RTCP_PT_SR<<16))) { #ifdef DEBUG fprintf(stderr, "rejected bad RTCP packet: header 0x%08x\n", rtcpHdr); #endif break; } // Process each of the individual RTCP 'subpackets' in (what may be) // a compound RTCP packet. int typeOfPacket = PACKET_UNKNOWN_TYPE; unsigned reportSenderSSRC = 0; Boolean packetOK = False; while (1) { unsigned rc = (rtcpHdr>>24)&0x1F; unsigned pt = (rtcpHdr>>16)&0xFF; unsigned length = 4*(rtcpHdr&0xFFFF); // doesn't count hdr ADVANCE(4); // skip over the header if (length > packetSize) break; // Assume that each RTCP subpacket begins with a 4-byte SSRC: if (length < 4) break; length -= 4; reportSenderSSRC = ntohl(*(u_int32_t*)pkt); ADVANCE(4); Boolean subPacketOK = False; switch (pt) { case RTCP_PT_SR: { #ifdef DEBUG fprintf(stderr, "SR\n"); #endif if (length < 20) break; length -= 20; // Extract the NTP timestamp, and note this: unsigned NTPmsw = ntohl(*(u_int32_t*)pkt); ADVANCE(4); unsigned NTPlsw = ntohl(*(u_int32_t*)pkt); ADVANCE(4); unsigned rtpTimestamp = ntohl(*(u_int32_t*)pkt); ADVANCE(4); if (fSource != NULL) { RTPReceptionStatsDB& receptionStats = fSource->receptionStatsDB(); receptionStats.noteIncomingSR(reportSenderSSRC, NTPmsw, NTPlsw, rtpTimestamp); } ADVANCE(8); // skip over packet count, octet count // If a 'SR handler' was set, call it now: if (fSRHandlerTask != NULL) (*fSRHandlerTask)(fSRHandlerClientData); // The rest of the SR is handled like a RR (so, no "break;" here) } case RTCP_PT_RR: { #ifdef DEBUG fprintf(stderr, "RR\n"); #endif unsigned reportBlocksSize = rc*(6*4); if (length < reportBlocksSize) break; length -= reportBlocksSize; if (fSink != NULL) { // Use this information to update stats about our transmissions: RTPTransmissionStatsDB& transmissionStats = fSink->transmissionStatsDB(); for (unsigned i = 0; i < rc; ++i) { unsigned senderSSRC = ntohl(*(u_int32_t*)pkt); ADVANCE(4); // We care only about reports about our own transmission, not others' if (senderSSRC == fSink->SSRC()) { unsigned lossStats = ntohl(*(u_int32_t*)pkt); ADVANCE(4); unsigned highestReceived = ntohl(*(u_int32_t*)pkt); ADVANCE(4); unsigned jitter = ntohl(*(u_int32_t*)pkt); ADVANCE(4); unsigned timeLastSR = ntohl(*(u_int32_t*)pkt); ADVANCE(4); unsigned timeSinceLastSR = ntohl(*(u_int32_t*)pkt); ADVANCE(4); transmissionStats.noteIncomingRR(reportSenderSSRC, fromAddress, lossStats, highestReceived, jitter, timeLastSR, timeSinceLastSR); } else { ADVANCE(4*5); } } } else { ADVANCE(reportBlocksSize); } if (pt == RTCP_PT_RR) { // i.e., we didn't fall through from 'SR' // If a 'RR handler' was set, call it now: // Specific RR handler: if (fSpecificRRHandlerTable != NULL) { netAddressBits fromAddr; portNumBits fromPortNum; if (tcpReadStreamSocketNum < 0) { // Normal case: We read the RTCP packet over UDP fromAddr = fromAddress.sin_addr.s_addr; fromPortNum = ntohs(fromAddress.sin_port); } else { // Special case: We read the RTCP packet over TCP (interleaved) // Hack: Use the TCP socket and channel id to look up the handler fromAddr = tcpReadStreamSocketNum; fromPortNum = tcpReadStreamChannelId; } Port fromPort(fromPortNum); RRHandlerRecord* rrHandler = (RRHandlerRecord*)(fSpecificRRHandlerTable->Lookup(fromAddr, (~0), fromPort)); if (rrHandler != NULL) { if (rrHandler->rrHandlerTask != NULL) { (*(rrHandler->rrHandlerTask))(rrHandler->rrHandlerClientData); } } } // General RR handler: if (fRRHandlerTask != NULL) (*fRRHandlerTask)(fRRHandlerClientData); } subPacketOK = True; typeOfPacket = PACKET_RTCP_REPORT; break; } case RTCP_PT_BYE: { #ifdef DEBUG fprintf(stderr, "BYE\n"); #endif // If a 'BYE handler' was set, arrange for it to be called at the end of this routine. // (Note: We don't call it immediately, in case it happens to cause "this" to be deleted.) if (fByeHandlerTask != NULL && (!fByeHandleActiveParticipantsOnly || (fSource != NULL && fSource->receptionStatsDB().lookup(reportSenderSSRC) != NULL) || (fSink != NULL && fSink->transmissionStatsDB().lookup(reportSenderSSRC) != NULL))) { callByeHandler = True; } // We should really check for & handle >1 SSRCs being present ##### subPacketOK = True; typeOfPacket = PACKET_BYE; break; } // Later handle SDES, APP, and compound RTCP packets ##### default: #ifdef DEBUG fprintf(stderr, "UNSUPPORTED TYPE(0x%x)\n", pt); #endif subPacketOK = True; break; } if (!subPacketOK) break; // need to check for (& handle) SSRC collision! ##### #ifdef DEBUG fprintf(stderr, "validated RTCP subpacket (type %d): %d, %d, %d, 0x%08x\n", typeOfPacket, rc, pt, length, reportSenderSSRC); #endif // Skip over any remaining bytes in this subpacket: ADVANCE(length); // Check whether another RTCP 'subpacket' follows: if (packetSize == 0) { packetOK = True; break; } else if (packetSize < 4) { #ifdef DEBUG fprintf(stderr, "extraneous %d bytes at end of RTCP packet!\n", packetSize); #endif break; } rtcpHdr = ntohl(*(u_int32_t*)pkt); if ((rtcpHdr & 0xC0000000) != 0x80000000) { #ifdef DEBUG fprintf(stderr, "bad RTCP subpacket: header 0x%08x\n", rtcpHdr); #endif break; } } if (!packetOK) { #ifdef DEBUG fprintf(stderr, "rejected bad RTCP subpacket: header 0x%08x\n", rtcpHdr); #endif break; } else { #ifdef DEBUG fprintf(stderr, "validated entire RTCP packet\n"); #endif } onReceive(typeOfPacket, totPacketSize, reportSenderSSRC); // Finally, if we need to call a "BYE" handler, do so now (in case it causes "this" to get deleted): if (callByeHandler && fByeHandlerTask != NULL/*sanity check*/) { TaskFunc* byeHandler = fByeHandlerTask; fByeHandlerTask = NULL; // because we call the handler only once, by default (*byeHandler)(fByeHandlerClientData); } } while (0); }
void ServerHost::doTick() { // Get a packet from either the server or the client for (RakNet::Packet* p = m_server->Receive(); p; m_server->DeallocatePacket(p), p=m_server->Receive()) { // We got a packet, get the identifier with our handy function unsigned char packetIdentifier = GetPacketIdentifier(p); // Check if this is a network message packet switch (packetIdentifier) { case ID_DISCONNECTION_NOTIFICATION: // Connection lost normally printf("ID_DISCONNECTION_NOTIFICATION\n"); m_peer.initServer(m_server,p->guid,p->systemAddress); onDisconnect(&m_peer); break; case ID_ALREADY_CONNECTED: // Connection lost normally printf("ID_ALREADY_CONNECTED with guid %" PRINTF_64_BIT_MODIFIER "u\n", p->guid); break; case ID_INCOMPATIBLE_PROTOCOL_VERSION: printf("ID_INCOMPATIBLE_PROTOCOL_VERSION\n"); break; case ID_CONNECTION_BANNED: // Banned from this server printf("We are banned from this server.\n"); break; case ID_CONNECTION_ATTEMPT_FAILED: printf("Connection attempt failed\n"); break; case ID_NO_FREE_INCOMING_CONNECTIONS: // Sorry, the server is full. I don't do anything here but // A real app should tell the user printf("ID_NO_FREE_INCOMING_CONNECTIONS\n"); break; case ID_INVALID_PASSWORD: printf("ID_INVALID_PASSWORD\n"); break; case ID_CONNECTION_LOST: // Couldn't deliver a reliable packet - i.e. the other system was abnormally // terminated printf("ID_CONNECTION_LOST\n"); m_peer.initServer(m_server,p->guid,p->systemAddress); onDisconnect(&m_peer); break; case ID_NEW_INCOMING_CONNECTION: // This tells the client they have connected m_peer.initServer(m_server,p->guid,p->systemAddress); onConnect(&m_peer); break; case ID_CONNECTED_PING: case ID_UNCONNECTED_PING: printf("Ping from %s\n", p->systemAddress.ToString(true)); break; case ID_USER_PACKET_ENUM: { RakNet::RakString rs; RakNet::BitStream bsIn(p->data,p->length,false); bsIn.IgnoreBytes(sizeof(RakNet::MessageID)); bsIn.Read(rs); m_peer.initServer(m_server,p->guid,p->systemAddress); onReceive(&m_peer,rs.C_String(),rs.GetLength()); } break; default: break; } } }
void RTCPInstance::incomingReportHandler1() { unsigned char* pkt = fInBuf; unsigned packetSize; struct sockaddr_in fromAddress; int typeOfPacket = PACKET_UNKNOWN_TYPE; do { int tcpReadStreamSocketNum = fRTCPInterface.nextTCPReadStreamSocketNum(); unsigned char tcpReadStreamChannelId = fRTCPInterface.nextTCPReadStreamChannelId(); if (!fRTCPInterface.handleRead(pkt, maxPacketSize, packetSize, fromAddress)) { break; } // Ignore the packet if it was looped-back from ourself: if (RTCPgs()->wasLoopedBackFromUs(envir(), fromAddress)) { // However, we still want to handle incoming RTCP packets from // *other processes* on the same machine. To distinguish this // case from a true loop-back, check whether we've just sent a // packet of the same size. (This check isn't perfect, but it seems // to be the best we can do.) if (fHaveJustSentPacket && fLastPacketSentSize == packetSize) { // This is a true loop-back: fHaveJustSentPacket = False; break; // ignore this packet } } if (fIsSSMSource) { // This packet was received via unicast. 'Reflect' it by resending // it to the multicast group. // NOTE: Denial-of-service attacks are possible here. // Users of this software may wish to add their own, // application-specific mechanism for 'authenticating' the // validity of this packet before reflecting it. fRTCPInterface.sendPacket(pkt, packetSize); fHaveJustSentPacket = True; fLastPacketSentSize = packetSize; } #ifdef DEBUG fprintf(stderr, "[%p]saw incoming RTCP packet (from address %s, port %d)\n", this, our_inet_ntoa(fromAddress.sin_addr), ntohs(fromAddress.sin_port)); unsigned char* p = pkt; for (unsigned i = 0; i < packetSize; ++i) { if (i%4 == 0) fprintf(stderr, " "); fprintf(stderr, "%02x", p[i]); } fprintf(stderr, "\n"); #endif int totPacketSize = IP_UDP_HDR_SIZE + packetSize; // Check the RTCP packet for validity: // It must at least contain a header (4 bytes), and this header // must be version=2, with no padding bit, and a payload type of // SR (200) or RR (201): if (packetSize < 4) break; unsigned rtcpHdr = ntohl(*(unsigned*)pkt); if ((rtcpHdr & 0xE0FE0000) != (0x80000000 | (RTCP_PT_SR<<16))) { #ifdef DEBUG fprintf(stderr, "rejected bad RTCP packet: header 0x%08x\n", rtcpHdr); #endif break; } // Process each of the individual RTCP 'subpackets' in (what may be) // a compound RTCP packet. unsigned reportSenderSSRC = 0; Boolean packetOK = False; while (1) { unsigned rc = (rtcpHdr>>24)&0x1F; unsigned pt = (rtcpHdr>>16)&0xFF; unsigned length = 4*(rtcpHdr&0xFFFF); // doesn't count hdr ADVANCE(4); // skip over the header if (length > packetSize) break; // Assume that each RTCP subpacket begins with a 4-byte SSRC: if (length < 4) break; length -= 4; reportSenderSSRC = ntohl(*(unsigned*)pkt); ADVANCE(4); Boolean subPacketOK = False; switch (pt) { case RTCP_PT_SR: { #ifdef DEBUG fprintf(stderr, "SR\n"); #endif if (length < 20) break; length -= 20; // Extract the NTP timestamp, and note this: unsigned NTPmsw = ntohl(*(unsigned*)pkt); ADVANCE(4); unsigned NTPlsw = ntohl(*(unsigned*)pkt); ADVANCE(4); unsigned rtpTimestamp = ntohl(*(unsigned*)pkt); ADVANCE(4); if (fSource != NULL) { RTPReceptionStatsDB& receptionStats = fSource->receptionStatsDB(); receptionStats.noteIncomingSR(reportSenderSSRC, NTPmsw, NTPlsw, rtpTimestamp); } ADVANCE(8); // skip over packet count, octet count // If a 'SR handler' was set, call it now: if (fSRHandlerTask != NULL) (*fSRHandlerTask)(fSRHandlerClientData); // The rest of the SR is handled like a RR (so, no "break;" here) } case RTCP_PT_RR: { #ifdef DEBUG fprintf(stderr, "RR\n"); #endif unsigned reportBlocksSize = rc*(6*4); if (length < reportBlocksSize) break; length -= reportBlocksSize; if (fSink != NULL) { // Use this information to update stats about our transmissions: RTPTransmissionStatsDB& transmissionStats = fSink->transmissionStatsDB(); for (unsigned i = 0; i < rc; ++i) { unsigned senderSSRC = ntohl(*(unsigned*)pkt); ADVANCE(4); // We care only about reports about our own transmission, not others' if (senderSSRC == fSink->SSRC()) { unsigned lossStats = ntohl(*(unsigned*)pkt); ADVANCE(4); unsigned highestReceived = ntohl(*(unsigned*)pkt); ADVANCE(4); unsigned jitter = ntohl(*(unsigned*)pkt); ADVANCE(4); unsigned timeLastSR = ntohl(*(unsigned*)pkt); ADVANCE(4); unsigned timeSinceLastSR = ntohl(*(unsigned*)pkt); ADVANCE(4); transmissionStats.noteIncomingRR(reportSenderSSRC, fromAddress, lossStats, highestReceived, jitter, timeLastSR, timeSinceLastSR); } else { ADVANCE(4*5); } } } else { ADVANCE(reportBlocksSize); } if (pt == RTCP_PT_RR) { // i.e., we didn't fall through from 'SR' // If a 'RR handler' was set, call it now: // Specific RR handler: if (fSpecificRRHandlerTable != NULL) { netAddressBits fromAddr; portNumBits fromPortNum; if (tcpReadStreamSocketNum < 0) { // Normal case: We read the RTCP packet over UDP fromAddr = fromAddress.sin_addr.s_addr; fromPortNum = ntohs(fromAddress.sin_port); } else { // Special case: We read the RTCP packet over TCP (interleaved) // Hack: Use the TCP socket and channel id to look up the handler fromAddr = tcpReadStreamSocketNum; fromPortNum = tcpReadStreamChannelId; } Port fromPort(fromPortNum); RRHandlerRecord* rrHandler = (RRHandlerRecord*)(fSpecificRRHandlerTable->Lookup(fromAddr, (~0), fromPort)); if (rrHandler != NULL) { if (rrHandler->rrHandlerTask != NULL) { (*(rrHandler->rrHandlerTask))(rrHandler->rrHandlerClientData); } } } // General RR handler: if (fRRHandlerTask != NULL) (*fRRHandlerTask)(fRRHandlerClientData); } subPacketOK = True; typeOfPacket = PACKET_RTCP_REPORT; break; } case RTCP_PT_BYE: { #ifdef DEBUG fprintf(stderr, "BYE\n"); #endif // If a 'BYE handler' was set, call it now: TaskFunc* byeHandler = fByeHandlerTask; if (byeHandler != NULL && (!fByeHandleActiveParticipantsOnly || (fSource != NULL && fSource->receptionStatsDB().lookup(reportSenderSSRC) != NULL) || (fSink != NULL && fSink->transmissionStatsDB().lookup(reportSenderSSRC) != NULL))) { fByeHandlerTask = NULL; // we call this only once by default (*byeHandler)(fByeHandlerClientData); } // We should really check for & handle >1 SSRCs being present ##### subPacketOK = True; typeOfPacket = PACKET_BYE; break; } // Later handle SDES, APP, and compound RTCP packets ##### default: #ifdef DEBUG fprintf(stderr, "UNSUPPORTED TYPE(0x%x)\n", pt); #endif subPacketOK = True; break; } if (!subPacketOK) break; // need to check for (& handle) SSRC collision! ##### #ifdef DEBUG fprintf(stderr, "validated RTCP subpacket (type %d): %d, %d, %d, 0x%08x\n", typeOfPacket, rc, pt, length, reportSenderSSRC); #endif // Skip over any remaining bytes in this subpacket: ADVANCE(length); // Check whether another RTCP 'subpacket' follows: if (packetSize == 0) { packetOK = True; break; } else if (packetSize < 4) { #ifdef DEBUG fprintf(stderr, "extraneous %d bytes at end of RTCP packet!\n", packetSize); #endif break; } rtcpHdr = ntohl(*(unsigned*)pkt); if ((rtcpHdr & 0xC0000000) != 0x80000000) { #ifdef DEBUG fprintf(stderr, "bad RTCP subpacket: header 0x%08x\n", rtcpHdr); #endif break; } } if (!packetOK) { #ifdef DEBUG fprintf(stderr, "rejected bad RTCP subpacket: header 0x%08x\n", rtcpHdr); #endif break; } else { #ifdef DEBUG fprintf(stderr, "validated entire RTCP packet\n"); #endif } onReceive(typeOfPacket, totPacketSize, reportSenderSSRC); } while (0); }
void TcpSocketImpl::ioReady(uint32_t events) { switch(getState()) { case ST_CONNECTING: { if(events & KUMA_EV_ERROR) { KUMA_ERRXTRACE("ioReady, KUMA_EV_ERROR, events="<<events <<", err="<<getLastError()<<", state="<<getState()); onConnect(KUMA_ERROR_POLLERR); } else { bool destroyed = false; destroy_flag_ptr_ = &destroyed; onConnect(KUMA_ERROR_NOERR); if(destroyed) { return ; } destroy_flag_ptr_ = nullptr; if((events & KUMA_EV_READ)) { onReceive(0); } } break; } case ST_OPEN: { #ifdef KUMA_HAS_OPENSSL if(ssl_handler_ && ssl_handler_->getState() == SslHandler::SslState::SSL_HANDSHAKE) { int err = KUMA_ERROR_NOERR; if(events & KUMA_EV_ERROR) { err = KUMA_ERROR_POLLERR; } else { SslHandler::SslState ssl_state = ssl_handler_->doSslHandshake(); if(SslHandler::SslState::SSL_ERROR == ssl_state) { err = KUMA_ERROR_SSL_FAILED; } else if(SslHandler::SslState::SSL_HANDSHAKE == ssl_state) { return; } } if(cb_connect_) { EventCallback cb_connect = std::move(cb_connect_); cb_connect(err); } else if(err != KUMA_ERROR_NOERR) { onClose(err); } else { events |= KUMA_EV_WRITE; // notify writable } if(err != KUMA_ERROR_NOERR) { return; } } #endif bool destroyed = false; destroy_flag_ptr_ = &destroyed; if(events & KUMA_EV_READ) {// handle EPOLLIN firstly onReceive(0); } if(destroyed) { return; } destroy_flag_ptr_ = nullptr; if((events & KUMA_EV_ERROR) && getState() == ST_OPEN) { KUMA_ERRXTRACE("ioReady, KUMA_EV_ERROR, events="<<events <<", err="<<getLastError()<<", state="<<getState()); onClose(KUMA_ERROR_POLLERR); break; } if((events & KUMA_EV_WRITE) && getState() == ST_OPEN) { onSend(0); } break; } default: //KUMA_WARNXTRACE("ioReady, invalid state="<<getState() // <<", events="<<events); break; } }