upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/btfrv.cpp13
-rw-r--r--src/btfrv.h13
-rw-r--r--src/net.cpp25
3 files changed, 44 insertions, 7 deletions
diff --git a/src/btfrv.cpp b/src/btfrv.cpp
index 0d02ca8..63e092e 100644
--- a/src/btfrv.cpp
+++ b/src/btfrv.cpp
@@ -250,11 +250,20 @@ RvSocket RvServiceRegister(const char* relay_host, unsigned short port,
250 hdr[0] = (unsigned char)'S'; 250 hdr[0] = (unsigned char)'S';
251 memcpy(hdr + 1, my_pubkey, 32); 251 memcpy(hdr + 1, my_pubkey, 32);
252 if (!WriteN(s, hdr, 33)) { CLOSESOCK(s); return RV_INVALID; } 252 if (!WriteN(s, hdr, 33)) { CLOSESOCK(s); return RV_INVALID; }
253 unsigned char paired = 0; 253 // Return here: registered, not yet paired. The relay lists the service as
254 if (!ReadN(s, &paired, 1) || paired != 0x01) { CLOSESOCK(s); return RV_INVALID; } 254 // soon as it reads this header. The 0x01 that used to be consumed below
255 // only arrives when somebody dials us, so blocking on it made "registered"
256 // and "already in use" indistinguishable to the caller -- and left the node
257 // unable to advertise a meeting node until after it had been reached there.
255 return (RvSocket)s; 258 return (RvSocket)s;
256} 259}
257 260
261bool RvServiceWaitPaired(RvSocket s)
262{
263 unsigned char paired = 0;
264 return ReadN((SOCKET)s, &paired, 1) && paired == 0x01;
265}
266
258RvSocket RvClientConnect(const char* relay_host, unsigned short port, 267RvSocket RvClientConnect(const char* relay_host, unsigned short port,
259 const unsigned char target_pubkey[32]) 268 const unsigned char target_pubkey[32])
260{ 269{
diff --git a/src/btfrv.h b/src/btfrv.h
index c776201..9d6756e 100644
--- a/src/btfrv.h
+++ b/src/btfrv.h
@@ -37,11 +37,20 @@ bool RvRelayRun(unsigned short port);
37void RvRelayStop(); 37void RvRelayStop();
38 38
39// ---- service side (the node being reached by its .btf address) ---- 39// ---- service side (the node being reached by its .btf address) ----
40// Register at the relay under `my_pubkey` (32 bytes) and block until a client is 40// Register at the relay under `my_pubkey` (32 bytes). Returns as soon as the
41// paired to us. Returns the paired socket, or RV_INVALID on error. 41// relay has us listed, WITHOUT waiting for anyone to dial -- the caller needs
42// that moment to start advertising this relay as its meeting node. Waiting for
43// the dial was folded into this call before, which deadlocked discovery: a node
44// could not be advertised until it had been dialled, and could not be dialled
45// until it was advertised. Returns RV_INVALID on error.
42RvSocket RvServiceRegister(const char* relay_host, unsigned short port, 46RvSocket RvServiceRegister(const char* relay_host, unsigned short port,
43 const unsigned char my_pubkey[32]); 47 const unsigned char my_pubkey[32]);
44 48
49// Block on a registered service socket until a client is paired to us. Returns
50// false if the relay drops us or errors, in which case the caller should close
51// the socket and register again.
52bool RvServiceWaitPaired(RvSocket s);
53
45// ---- client side (the node dialing a .btf address) ---- 54// ---- client side (the node dialing a .btf address) ----
46// Connect through the relay to the service registered under `target_pubkey`. 55// Connect through the relay to the service registered under `target_pubkey`.
47// Returns the paired socket, or RV_INVALID on error. 56// Returns the paired socket, or RV_INVALID on error.
diff --git a/src/net.cpp b/src/net.cpp
index 7b2ef83..b5d12d0 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -554,7 +554,10 @@ void ThreadBtfAccept(void* parg)
554 string strHost = strMeeting.substr(0, colon); 554 string strHost = strMeeting.substr(0, colon);
555 int nPort = atoi(strMeeting.substr(colon + 1).c_str()); 555 int nPort = atoi(strMeeting.substr(colon + 1).c_str());
556 556
557 // Blocks until a client is paired to us (or the relay drops us) 557 // Returns as soon as the relay has us listed -- it does not wait for a
558 // dial. That distinction is the whole point: we have to be advertised
559 // before anyone can dial us, so registering and waiting cannot be the
560 // same call.
558 btf::RvSocket rv = btf::RvServiceRegister(strHost.c_str(), (unsigned short)nPort, pk); 561 btf::RvSocket rv = btf::RvServiceRegister(strHost.c_str(), (unsigned short)nPort, pk);
559 if (fShutdown) 562 if (fShutdown)
560 { 563 {
@@ -564,13 +567,29 @@ void ThreadBtfAccept(void* parg)
564 } 567 }
565 if (rv == btf::RV_INVALID) 568 if (rv == btf::RV_INVALID)
566 { 569 {
570 LogPrint("net", "rendezvous: could not register at %s, trying another\n",
571 strMeeting.c_str());
567 iRelay++; // this relay is down/attacked -> try the next one 572 iRelay++; // this relay is down/attacked -> try the next one
568 Sleep(3000); 573 Sleep(3000);
569 continue; 574 continue;
570 } 575 }
571 // Registered OK: advertise THIS relay in our descriptor so clients dial 576
572 // us here, and keep using it (iRelay unchanged) until it fails. 577 // Registered. Advertise THIS relay now, while we are listed and before
578 // anybody dials -- a descriptor naming it is what makes a dial possible
579 // at all. Keep using it (iRelay unchanged) until it fails.
573 BtfSetActiveRelay(strMeeting); 580 BtfSetActiveRelay(strMeeting);
581 LogPrint("net", "rendezvous: registered at %s, waiting for a dial\n",
582 strMeeting.c_str());
583
584 // Now block for someone to arrive.
585 if (!btf::RvServiceWaitPaired(rv))
586 {
587 btf::RvClose(rv);
588 LogPrint("net", "rendezvous: %s dropped us before any dial, re-registering\n",
589 strMeeting.c_str());
590 continue;
591 }
592
574 btf_socket_t hSocket = btf::BtfServiceWrap(rv, sk); 593 btf_socket_t hSocket = btf::BtfServiceWrap(rv, sk);
575 if (hSocket == INVALID_SOCKET) 594 if (hSocket == INVALID_SOCKET)
576 continue; 595 continue;