ref: 314faec39447f98c0dfd96a91dbd25fd757d106d
parent: e4509d40cc9759baddf1c2571247b95d2f5b61a5
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Apr 21 09:08:19 EDT 2024
rudp: fix start generation randomization and cleanup the start generation was allocated by calling rand(), which gives a value between 0 and 2^15. Instead, make a newgen() function that returns a new generation id in the full 32-bit range, but also avoids 0 and Hangupgen special values. Cleanup and make all helper functions static.
--- a/sys/src/9/ip/rudp.c
+++ b/sys/src/9/ip/rudp.c
@@ -162,9 +162,6 @@
};
-static ulong generation = 0;
-static Rendez rend;
-
/*
* protocol specific part of Conv
*/
@@ -180,17 +177,17 @@
/*
* local functions
*/
-void relsendack(Conv*, Reliable*, int);
-int reliput(Conv*, Block*, uchar*, ushort);
-Reliable *relstate(Rudpcb*, uchar*, ushort, char*);
-void relput(Reliable*);
-void relforget(Conv *, uchar*, int, int);
-void relackproc(void *);
-void relackq(Reliable *, Block*);
-void relhangup(Conv *, Reliable*);
-void relrexmit(Conv *, Reliable*);
-void relput(Reliable*);
-void rudpkick(void *x);
+static void relsendack(Conv*, Reliable*, int);
+static int reliput(Conv*, Block*, uchar*, ushort);
+static Reliable *relstate(Rudpcb*, uchar*, ushort, char*);
+static void relput(Reliable*);
+static void relforget(Conv *, uchar*, int, int);
+static void relackproc(void *);
+static void relackq(Reliable *, Block*);
+static void relhangup(Conv *, Reliable*);
+static void relrexmit(Conv *, Reliable*);
+static void relput(Reliable*);
+static void rudpkick(void *x);
static void
rudpstartackproc(Proto *rudp)
@@ -325,7 +322,7 @@
ipoput4(f, bp, nil, ttl, tos, nil);
}
-int
+static int
flow(void *v)
{
Reliable *r = v;
@@ -333,7 +330,7 @@
return UNACKED(r) <= Maxunacked;
}
-void
+static void
rudpkick(void *x)
{
Conv *c = x;
@@ -471,7 +468,7 @@
poperror();
}
-void
+static void
rudpiput(Proto *rudp, Ipifc *ifc, Block *bp)
{
int len, olen;
@@ -598,7 +595,7 @@
static char *rudpunknown = "unknown rudp ctl request";
-char*
+static char*
rudpctl(Conv *c, char **f, int n)
{
Rudpcb *ucb;
@@ -634,7 +631,7 @@
return rudpunknown;
}
-void
+static void
rudpadvise(Proto *rudp, Block *bp, Ipifc *, char *msg)
{
Udphdr *h;
@@ -665,7 +662,7 @@
freeblist(bp);
}
-int
+static int
rudpstats(Proto *rudp, char *buf, int len)
{
Rudppriv *upriv;
@@ -711,7 +708,7 @@
/*
* Enqueue a copy of an unacked block for possible retransmissions
*/
-void
+static void
relackq(Reliable *r, Block *bp)
{
Block *np;
@@ -732,7 +729,7 @@
/*
* retransmit unacked blocks
*/
-void
+static void
relackproc(void *a)
{
Rudpcb *ucb;
@@ -766,10 +763,26 @@
goto loop;
}
+static ulong
+newgen(void)
+{
+ static Lock lk;
+ static ulong gen = 0;
+ ulong r;
+
+ lock(&lk);
+ while(gen == 0 || gen == Hangupgen)
+ gen = (nrand(1<<16)<<16)|nrand(1<<16);
+ r = gen++;
+ unlock(&lk);
+
+ return r;
+}
+
/*
* get the state record for a conversation
*/
-Reliable*
+static Reliable*
relstate(Rudpcb *ucb, uchar *addr, ushort port, char *from)
{
Reliable *r, **l;
@@ -776,8 +789,7 @@
l = &ucb->r;
for(r = *l; r; r = *l){
- if(memcmp(addr, r->addr, IPaddrlen) == 0 &&
- port == r->port)
+ if(ipcmp(addr, r->addr) == 0 && port == r->port)
break;
l = &r->next;
}
@@ -784,19 +796,11 @@
/* no state for this addr/port, create some */
if(r == nil){
- while(generation == 0)
- generation = rand();
-
- DPRINT("from %s new state %lud for %I!%ud\n",
- from, generation, addr, port);
-
r = smalloc(sizeof(Reliable));
- memmove(r->addr, addr, IPaddrlen);
+ ipmove(r->addr, addr);
r->port = port;
r->unacked = 0;
- if(generation == Hangupgen)
- generation++;
- r->sndgen = generation++;
+ r->sndgen = newgen();
r->sndseq = 0;
r->ackrcvd = 0;
r->rcvgen = 0;
@@ -807,6 +811,9 @@
r->ref = 0;
incref(r); /* one reference for being in the list */
+ DPRINT("from %s new state %lud for %I!%ud\n",
+ from, r->sndgen, r->addr, r->port);
+
*l = r;
}
@@ -814,7 +821,7 @@
return r;
}
-void
+static void
relput(Reliable *r)
{
if(decref(r) == 0)
@@ -824,7 +831,7 @@
/*
* forget a Reliable state
*/
-void
+static void
relforget(Conv *c, uchar *ip, int port, int originator)
{
Rudpcb *ucb;
@@ -852,7 +859,7 @@
*
* called with ucb locked.
*/
-int
+static int
reliput(Conv *c, Block *bp, uchar *addr, ushort port)
{
Block *nbp;
@@ -953,7 +960,7 @@
return rv;
}
-void
+static void
relsendack(Conv *c, Reliable *r, int hangup)
{
Udphdr *uh;
@@ -1007,7 +1014,7 @@
/*
* called with ucb locked (and c locked if user initiated close)
*/
-void
+static void
relhangup(Conv *c, Reliable *r)
{
int n;
@@ -1029,9 +1036,7 @@
r->rcvgen = 0;
r->rcvseq = 0;
r->acksent = 0;
- if(generation == Hangupgen)
- generation++;
- r->sndgen = generation++;
+ r->sndgen = newgen();
r->sndseq = 0;
r->ackrcvd = 0;
r->xmits = 0;
@@ -1042,7 +1047,7 @@
/*
* called with ucb locked
*/
-void
+static void
relrexmit(Conv *c, Reliable *r)
{
Rudppriv *upriv;