Skip to content

Commit 1aa3fe0

Browse files
committed
UDP search traverse NAT
Change the CMD_SEARCH message, adding a reply-to-sender-port flag to allow for replies to traverse a NAT. The meaning of that flag is that the recipient should ignore the replyPort field, and instead send a reply to the apparent port which sent the request. A forwarder should overwrite the replyPort field, and clear this new MustReply flag.
1 parent b9e2d02 commit 1aa3fe0

File tree

3 files changed

+18
-5
lines changed

3 files changed

+18
-5
lines changed

src/client.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,8 +1044,12 @@ void ContextImpl::tickSearch(SearchKind kind, bool poked)
10441044
// flags and reserved.
10451045
// initially flags[7] is cleared (bcast)
10461046
auto pflags = M.save();
1047-
to_wire(M, uint8_t(kind == SearchKind::discover ?
1048-
pva_search_flags::MustReply : 0u)); // must-reply to discovery, ignore regular negative search
1047+
to_wire(M, uint8_t(
1048+
// must-reply to discovery, ignore regular negative search
1049+
(kind == SearchKind::discover ? pva_search_flags::MustReply : 0u)
1050+
| pva_search_flags::ReplySrcPort
1051+
)
1052+
);
10491053
to_wire(M, uint8_t(0u));
10501054
to_wire(M, uint16_t(0u));
10511055

src/pvaproto.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -579,8 +579,8 @@ void from_wire(Buffer& buf, shared_array<const void>& varr)
579579

580580
struct pva_version {
581581
enum {
582-
client = 2,
583-
server = 2,
582+
client = 3,
583+
server = 3,
584584
};
585585
};
586586

@@ -640,6 +640,7 @@ enum pva_app_msg_t : uint8_t {
640640
struct pva_search_flags {
641641
enum type_t : uint8_t {
642642
MustReply = 0x01,
643+
ReplySrcPort = 0x02,
643644
Unicast = 0x80,
644645
};
645646
};

src/udp_collector.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,13 @@ void UDPCollector::process_one(const uint8_t *buf, size_t nrx, origin_t origin,
369369
return;
370370
}
371371
}
372+
if((origin==Broadcast || origin==Forwarding)
373+
&& peerVersion >= 3
374+
&& (flags&pva_search_flags::ReplySrcPort))
375+
{
376+
// peer requests reply to (apparent) sender port
377+
port = src.port();
378+
}
372379
server.setPort(port);
373380

374381
if(!M.good())
@@ -383,8 +390,9 @@ void UDPCollector::process_one(const uint8_t *buf, size_t nrx, origin_t origin,
383390
*save_flags &= ~pva_search_flags::Unicast;
384391
// recipient of forwarded message must use, and trust, replyAddr in body :(
385392
{
386-
FixedBuf R(M.be, save_replyAddr, 16u);
393+
FixedBuf R(M.be, save_replyAddr, 16u + 2u);
387394
to_wire(R, server);
395+
to_wire(R, port);
388396
assert(R.good());
389397
}
390398
forwardM(buf, nrx);

0 commit comments

Comments
 (0)