This function responds to the fact that a packet has come for a socket that does not expect to receive a normal connection request. This can be then: - a normal packet of whatever kind, just to be processed by the message loop - a rendezvous connection This function then tries to manage the packet as a rendezvous connection request in ASYNC mode; when this is not applicable, it stores the packet i
| 1544 | // request in ASYNC mode; when this is not applicable, it stores the packet |
| 1545 | // in the "receiving queue" so that it will be picked up in the "main" thread. |
| 1546 | srt::EConnectStatus srt::CRcvQueue::worker_TryAsyncRend_OrStore(int32_t id, CUnit* unit, const sockaddr_any& addr) |
| 1547 | { |
| 1548 | // This 'retrieve' requires that 'id' be either one of those |
| 1549 | // stored in the rendezvous queue (see CRcvQueue::registerConnector) |
| 1550 | // or simply 0, but then at least the address must match one of these. |
| 1551 | // If the id was 0, it will be set to the actual socket ID of the returned CUDT. |
| 1552 | CUDT* u = m_pRendezvousQueue->retrieve(addr, (id)); |
| 1553 | if (!u) |
| 1554 | { |
| 1555 | // this socket is then completely unknown to the system. |
| 1556 | // Note that this situation may also happen at a very unfortunate |
| 1557 | // coincidence that the socket is already bound, but the registerConnector() |
| 1558 | // has not yet started. In case of rendezvous this may mean that the other |
| 1559 | // side just started sending its handshake packets, the local side has already |
| 1560 | // run the CRcvQueue::worker thread, and this worker thread is trying to dispatch |
| 1561 | // the handshake packet too early, before the dispatcher has a chance to see |
| 1562 | // this socket registered in the RendezvousQueue, which causes the packet unable |
| 1563 | // to be dispatched. Therefore simply treat every "out of band" packet (with socket |
| 1564 | // not belonging to the connection and not registered as rendezvous) as "possible |
| 1565 | // attack" and ignore it. This also should better protect the rendezvous socket |
| 1566 | // against a rogue connector. |
| 1567 | if (id == 0) |
| 1568 | { |
| 1569 | HLOGC(cnlog.Debug, |
| 1570 | log << CONID() << "AsyncOrRND: no sockets expect connection from " << addr.str() |
| 1571 | << " - POSSIBLE ATTACK, ignore packet"); |
| 1572 | } |
| 1573 | else |
| 1574 | { |
| 1575 | HLOGC(cnlog.Debug, |
| 1576 | log << CONID() << "AsyncOrRND: no sockets expect socket " << id << " from " << addr.str() |
| 1577 | << " - POSSIBLE ATTACK, ignore packet"); |
| 1578 | } |
| 1579 | return CONN_AGAIN; // This means that the packet should be ignored. |
| 1580 | } |
| 1581 | |
| 1582 | // asynchronous connect: call connect here |
| 1583 | // otherwise wait for the UDT socket to retrieve this packet |
| 1584 | if (!u->m_config.bSynRecving) |
| 1585 | { |
| 1586 | HLOGC(cnlog.Debug, log << "AsyncOrRND: packet RESOLVED TO @" << id << " -- continuing as ASYNC CONNECT"); |
| 1587 | // This is practically same as processConnectResponse, just this applies |
| 1588 | // appropriate mutex lock - which can't be done here because it's intentionally private. |
| 1589 | // OTOH it can't be applied to processConnectResponse because the synchronous |
| 1590 | // call to this method applies the lock by itself, and same-thread-double-locking is nonportable (crashable). |
| 1591 | EConnectStatus cst = u->processAsyncConnectResponse(unit->m_Packet); |
| 1592 | |
| 1593 | if (cst == CONN_CONFUSED) |
| 1594 | { |
| 1595 | LOGC(cnlog.Warn, log << "AsyncOrRND: PACKET NOT HANDSHAKE - re-requesting handshake from peer"); |
| 1596 | storePktClone(id, unit->m_Packet); |
| 1597 | if (!u->processAsyncConnectRequest(RST_AGAIN, CONN_CONTINUE, &unit->m_Packet, u->m_PeerAddr)) |
| 1598 | { |
| 1599 | // Reuse previous behavior to reject a packet |
| 1600 | cst = CONN_REJECT; |
| 1601 | } |
| 1602 | else |
| 1603 | { |
nothing calls this directly
no test coverage detected