| plan 9 kernel history: overview | file list | diff list |
ip/rudp.c (diff list | history)
| 1998/0630/sys/src/9/ip/rudp.c:8,14 – 1998/0726/sys/src/9/ip/rudp.c:8,15 (short | long) | ||
| 1998/0630 | #include "ip.h" | |
| 1998/0726 | #define DEBUG 0 #define DPRINT if(DEBUG)print | |
| 1998/0630 | enum { | |
| 1998/0630/sys/src/9/ip/rudp.c:22,28 – 1998/0726/sys/src/9/ip/rudp.c:23,29 | ||
| 1998/0630 | Rudprxms = 200, Rudptickms = 100, | |
| 1998/0726 | Rudpmaxxmit = 10, | |
| 1998/0630 | }; | |
| 1998/0630/sys/src/9/ip/rudp.c:105,118 – 1998/0726/sys/src/9/ip/rudp.c:106,121 | ||
| 1998/0630 | typedef struct Rudppriv Rudppriv; struct Rudppriv { | |
| 1998/0726 | Rendez vous; | |
| 1998/0630 |
| |
| 1998/0726 | ulong csumerr; /* checksum errors */ ulong lenerr; /* short packet */ ulong rxmits; /* # of retransmissions */ ulong orders; /* # of out of order pkts */ | |
| 1998/0630 | }; | |
| 1998/0630/sys/src/9/ip/rudp.c:119,124 – 1998/0726/sys/src/9/ip/rudp.c:122,132 | ||
| 1998/0630 | static ulong generation = 0; static Rendez rend; | |
| 1998/0726 | /* Used only for debugging */ static ushort drop = 0; static ushort drop_rate = 10; | |
| 1998/0630 | /* * protocol specific part of Conv */ | |
| 1998/0630/sys/src/9/ip/rudp.c:135,141 – 1998/0726/sys/src/9/ip/rudp.c:143,149 | ||
| 1998/0630 | */ void relsendack( Conv *, Reliable * ); int reliput( Conv *, Block *, uchar *, ushort ); | |
| 1998/0726 | Reliable *relstate( Rudpcb *, uchar *, ushort, char *from ); | |
| 1998/0630 | void relackproc( void * ); void relackq( Reliable *, Block * ); void relhangup( Conv *, Reliable * ); | |
| 1998/0630/sys/src/9/ip/rudp.c:157,163 – 1998/0726/sys/src/9/ip/rudp.c:165,171 | ||
| 1998/0630 | rudpstate(Conv *c, char *state, int n) { USED(c); | |
| 1998/0726 | return snprint(state, n, "%s", "Reliable UDP V0.1"); | |
| 1998/0630 | } static char* | |
| 1998/0630/sys/src/9/ip/rudp.c:264,270 – 1998/0726/sys/src/9/ip/rudp.c:272,280 | ||
| 1998/0630 | bp->rp += 4; /* Igonore local port */ break; default: | |
| 1998/0726 | ipmove( raddr, c->raddr ); ipmove( laddr, c->laddr ); rport = c->rport; | |
| 1998/0630 | break; } | |
| 1998/0630/sys/src/9/ip/rudp.c:280,285 – 1998/0726/sys/src/9/ip/rudp.c:290,296 | ||
| 1998/0630 | rh = &(uh->rhdr); | |
| 1998/0726 | ||
| 1998/0630 | ptcllen = dlen + (RUDP_HDRSIZE-RUDP_PHDRSIZE); uh->Unused = 0; uh->rudpproto = IP_RUDPPROTO; | |
| 1998/0630/sys/src/9/ip/rudp.c:308,314 – 1998/0726/sys/src/9/ip/rudp.c:319,325 | ||
| 1998/0630 | qlock( ucb ); | |
| 1998/0726 | r = relstate( ucb, raddr, rport, "kick" ); | |
| 1998/0630 | r->sndseq++; hnputl( rh->relseq, r->sndseq ); hnputl( rh->relsgen, r->sndgen ); | |
| 1998/0630/sys/src/9/ip/rudp.c:328,335 – 1998/0726/sys/src/9/ip/rudp.c:339,346 | ||
| 1998/0630 |
| |
| 1998/0726 | DPRINT( "sent: %d/%d, %d/%d, r->sndgen = %d\n", r->sndseq, r->sndgen, r->rcvseq, r->rcvgen, r->sndgen ); | |
| 1998/0630 | ipoput(f, bp, 0, c->ttl); } | |
| 1998/0630/sys/src/9/ip/rudp.c:372,377 – 1998/0726/sys/src/9/ip/rudp.c:383,389 | ||
| 1998/0630 | if(nhgets(uh->rudpcksum)) { if(ptclcsum(bp, RUDP_IPHDR, len+RUDP_PHDRSIZE)) { upriv->ustats.rudpInErrors++; | |
| 1998/0726 | upriv->csumerr++; | |
| 1998/0630 | netlog(f, Logrudp, "rudp: checksum error %I\n", raddr); DPRINT("rudp: checksum error %I\n", raddr); freeblist(bp); | |
| 1998/0630/sys/src/9/ip/rudp.c:537,547 – 1998/0726/sys/src/9/ip/rudp.c:549,561 | ||
| 1998/0630 | Rudppriv *upriv; upriv = rudp->priv; | |
| 1998/0726 | return snprint(buf, len, "%d %d %d %d %d %d\n", | |
| 1998/0630 | upriv->ustats.rudpInDatagrams, upriv->ustats.rudpNoPorts, upriv->ustats.rudpInErrors, | |
| 1998/0726 | upriv->ustats.rudpOutDatagrams, upriv->rxmits, upriv->orders); | |
| 1998/0630 | } void | |
| 1998/0630/sys/src/9/ip/rudp.c:569,575 – 1998/0726/sys/src/9/ip/rudp.c:583,589 | ||
| 1998/0630 | Fsproto(fs, rudp); | |
| 1998/0726 | kproc("relackproc", relackproc, rudp); | |
| 1998/0630 | } | |
| 1998/0630/sys/src/9/ip/rudp.c:607,624 – 1998/0726/sys/src/9/ip/rudp.c:621,640 | ||
| 1998/0630 | Proto *rudp; Reliable *r; Conv **s, *c; | |
| 1998/0726 | Rudppriv *upriv; | |
| 1998/0630 | rudp = (Proto *)a; | |
| 1998/0726 | upriv = rudp->priv; | |
| 1998/0630 | loop: | |
| 1998/0726 | tsleep(&upriv->vous, return0, 0, Rudptickms); | |
| 1998/0630 | for(s = rudp->conv; *s; s++) { c = *s; ucb = (Rudpcb*)c->ptcl; | |
| 1998/0726 | qlock(ucb); | |
| 1998/0630 |
| |
| 1998/0726 | for(r = ucb->r; r; r = r->next) { | |
| 1998/0630 | if(r->unacked != nil){ r->timeout += Rudptickms; if(r->timeout > Rudprxms*r->xmits) | |
| 1998/0630/sys/src/9/ip/rudp.c:627,633 – 1998/0726/sys/src/9/ip/rudp.c:643,649 | ||
| 1998/0630 | if(r->acksent < r->rcvseq) relsendack(c, r); } | |
| 1998/0726 | qunlock(ucb); | |
| 1998/0630 | } goto loop; } | |
| 1998/0630/sys/src/9/ip/rudp.c:636,646 – 1998/0726/sys/src/9/ip/rudp.c:652,663 | ||
| 1998/0630 | * get the state record for a conversation */ Reliable* | |
| 1998/0726 | relstate(Rudpcb *ucb, uchar *addr, ushort port, char *from ) | |
| 1998/0630 | { Reliable *r, **l; | |
| 1998/0726 | ||
| 1998/0630 | l = &ucb->r; for(r = *l; r; r = *l){ if( memcmp( addr, r->addr, IPaddrlen) == 0 && | |
| 1998/0630/sys/src/9/ip/rudp.c:651,659 – 1998/0726/sys/src/9/ip/rudp.c:668,677 | ||
| 1998/0630 | /* no state for this addr/port, create some */ if(r == nil){ | |
| 1998/0726 | DPRINT( "from %s new state %d for %I!%d\n", from, generation, addr, port ); | |
| 1998/0630 | r = smalloc( sizeof( Reliable ) ); *l = r; memmove( r->addr, addr, IPaddrlen); | |
| 1998/0630/sys/src/9/ip/rudp.c:682,687 – 1998/0726/sys/src/9/ip/rudp.c:700,706 | ||
| 1998/0630 | { Block *nbp; Rudpcb *ucb; | |
| 1998/0726 | Rudppriv *upriv; | |
| 1998/0630 | Rudphdr *uh; Reliable *r; Relhdr *rh; | |
| 1998/0630/sys/src/9/ip/rudp.c:698,719 – 1998/0726/sys/src/9/ip/rudp.c:717,738 | ||
| 1998/0630 | agen = nhgetl(rh->relagen); | |
| 1998/0726 | upriv = c->p->priv; | |
| 1998/0630 | ucb = (Rudpcb*)c->ptcl; | |
| 1998/0726 | r = relstate(ucb, addr, port, "input" ); | |
| 1998/0630 |
| |
| 1998/0726 | DPRINT("rcvd %d/%d, %d/%d, r->sndgen = %d\n", seq, sgen, ack, agen, r->sndgen); | |
| 1998/0630 | /* dequeue acked packets */ if(ack && agen == r->sndgen){ | |
| 1998/0726 | DPRINT("%d/%d acked, r->sndgen = %d\n", ack, agen, r->sndgen); | |
| 1998/0630 | freeb(nbp); r->ackrcvd++; ackreal = 1; | |
| 1998/0630/sys/src/9/ip/rudp.c:751,758 – 1998/0726/sys/src/9/ip/rudp.c:770,784 | ||
| 1998/0630 | if(seq == 0) return -1; | |
| 1998/0726 | if( DEBUG && ++drop == drop_rate ){ DPRINT( "drop pkt on purpose\n" ); drop = 0; return -1; } | |
| 1998/0630 | /* refuse out of order delivery */ if(seq != r->rcvseq + 1){ | |
| 1998/0726 | upriv->orders++; | |
| 1998/0630 | DPRINT("out of sequence %d not %d\n", seq, r->rcvseq + 1); return -1; } | |
| 1998/0630/sys/src/9/ip/rudp.c:846,853 – 1998/0726/sys/src/9/ip/rudp.c:872,882 | ||
| 1998/0630 | void relrexmit(Conv *c, Reliable *r) { | |
| 1998/0726 | Rudppriv *upriv; | |
| 1998/0630 | Block *np; Fs *f; | |
| 1998/0726 | upriv = c->p->priv; | |
| 1998/0630 | f = c->p->f; r->timeout = 0; if(r->xmits++ > Rudpmaxxmit){ | |
| 1998/0630/sys/src/9/ip/rudp.c:855,861 – 1998/0726/sys/src/9/ip/rudp.c:884,891 | ||
| 1998/0630 | return; } | |
| 1998/0726 | upriv->rxmits++; | |
| 1998/0630 | np = copyblock(r->unacked, blocklen(r->unacked)); | |
| 1998/0726 | DPRINT("rxmit r->ackrvcd+1 = %d\n", r->ackrcvd+1); | |
| 1998/0630 | ipoput(f, np, 0, c->ttl); } | |
| 1998/0726/sys/src/9/ip/rudp.c:1,4 – 1998/0728/sys/src/9/ip/rudp.c:1,7 (short | long) | ||
| 1998/0630 | ||
| 1998/0728 | /* * This protocol is compatible with UDP's packet format. * It could be done over UDP if need be. */ | |
| 1998/0630 | #include "u.h" #include "../port/lib.h" #include "mem.h" | |
| 1998/0726/sys/src/9/ip/rudp.c:13,25 – 1998/0728/sys/src/9/ip/rudp.c:16,28 | ||
| 1998/0630 | enum { | |
| 1998/0728 | UDP_HDRSIZE = 20, /* pseudo header + udp header */ UDP_PHDRSIZE = 12, /* pseudo header */ UDP_RHDRSIZE = 36, /* pseudo header + udp header + rudp header */ UDP_IPHDR = 8, /* ip header */ IP_UDPPROTO = 254, UDP_USEAD6 = 36, UDP_USEAD4 = 12, | |
| 1998/0630 | Rudprxms = 200, Rudptickms = 100, | |
| 1998/0726/sys/src/9/ip/rudp.c:27,42 – 1998/0728/sys/src/9/ip/rudp.c:30,57 | ||
| 1998/0630 | }; | |
| 1998/0728 | typedef struct Udphdr Udphdr; struct Udphdr | |
| 1998/0630 | { | |
| 1998/0728 | /* ip header */ uchar vihl; /* Version and header length */ uchar tos; /* Type of service */ uchar length[2]; /* packet length */ uchar id[2]; /* Identification */ uchar frag[2]; /* Fragment information */ /* pseudo header starts here */ uchar Unused; uchar udpproto; /* Protocol */ uchar udpplen[2]; /* Header plus data length */ uchar udpsrc[4]; /* Ip source */ uchar udpdst[4]; /* Ip destination */ /* udp header */ uchar udpsport[2]; /* Source port */ uchar udpdport[2]; /* Destination port */ uchar udplen[2]; /* data length */ uchar udpcksum[2]; /* Checksum */ | |
| 1998/0630 | }; typedef struct Rudphdr Rudphdr; | |
| 1998/0726/sys/src/9/ip/rudp.c:48,65 – 1998/0728/sys/src/9/ip/rudp.c:63,87 | ||
| 1998/0630 | uchar length[2]; /* packet length */ uchar id[2]; /* Identification */ uchar frag[2]; /* Fragment information */ | |
| 1998/0728 | /* pseudo header starts here */ uchar Unused; uchar udpproto; /* Protocol */ uchar udpplen[2]; /* Header plus data length */ uchar udpsrc[4]; /* Ip source */ uchar udpdst[4]; /* Ip destination */ /* udp header */ uchar udpsport[2]; /* Source port */ uchar udpdport[2]; /* Destination port */ uchar udplen[2]; /* data length (includes rudp header) */ uchar udpcksum[2]; /* Checksum */ | |
| 1998/0630 | /* rudp header */ | |
| 1998/0728 | uchar relseq[4]; /* id of this packet (or 0) */ uchar relsgen[4]; /* generation/time stamp */ uchar relack[4]; /* packet being acked (or 0) */ uchar relagen[4]; /* generation/time stamp */ | |
| 1998/0630 | }; | |
| 1998/0726/sys/src/9/ip/rudp.c:74,80 – 1998/0728/sys/src/9/ip/rudp.c:96,101 | ||
| 1998/0630 | uchar addr[IPaddrlen]; /* always V6 when put here */ ushort port; | |
| 1998/0726/sys/src/9/ip/rudp.c:141,153 – 1998/0728/sys/src/9/ip/rudp.c:162,174 | ||
| 1998/0630 | /* * local functions */ | |
| 1998/0726 |
| |
| 1998/0630 |
| |
| 1998/0728 | void relsendack(Conv *, Reliable *); int reliput(Conv *, Block *, uchar *, ushort); Reliable *relstate(Rudpcb *, uchar *, ushort, char *from); void relackproc(void *); void relackq(Reliable *, Block *); void relhangup(Conv *, Reliable *); void relrexmit(Conv *, Reliable *); | |
| 1998/0630 | static char* rudpconnect(Conv *c, char **argv, int argc) | |
| 1998/0726/sys/src/9/ip/rudp.c:204,218 – 1998/0728/sys/src/9/ip/rudp.c:225,239 | ||
| 1998/0630 | ucb = (Rudpcb*)c->ptcl; ucb->headers = 0; | |
| 1998/0728 | qlock(ucb); for(r = ucb->r; r; r = nr){ | |
| 1998/0630 | nr = r->next; | |
| 1998/0728 | relhangup(c, r); free(r); | |
| 1998/0630 | } ucb->r = 0; | |
| 1998/0728 | qunlock(ucb); | |
| 1998/0630 | unlock(c); } | |
| 1998/0726/sys/src/9/ip/rudp.c:220,231 – 1998/0728/sys/src/9/ip/rudp.c:241,252 | ||
| 1998/0630 | void rudpkick(Conv *c, int) { | |
| 1998/0728 | Udphdr *uh; | |
| 1998/0630 | ushort rport; uchar laddr[IPaddrlen], raddr[IPaddrlen]; Block *bp; Rudpcb *ucb; | |
| 1998/0728 | Rudphdr *rh; | |
| 1998/0630 | Reliable *r; int dlen, ptcllen; Rudppriv *upriv; | |
| 1998/0726/sys/src/9/ip/rudp.c:243,249 – 1998/0728/sys/src/9/ip/rudp.c:264,270 | ||
| 1998/0630 | switch(ucb->headers) { case 6: /* get user specified addresses */ | |
| 1998/0728 | bp = pullupblock(bp, UDP_USEAD6); | |
| 1998/0630 | if(bp == nil) return; ipmove(raddr, bp->rp); | |
| 1998/0726/sys/src/9/ip/rudp.c:258,264 – 1998/0728/sys/src/9/ip/rudp.c:279,285 | ||
| 1998/0630 | bp->rp += 4; /* Igonore local port */ break; case 4: | |
| 1998/0728 | bp = pullupblock(bp, UDP_USEAD4); | |
| 1998/0630 | if(bp == nil) return; v4tov6(raddr, bp->rp); | |
| 1998/0726/sys/src/9/ip/rudp.c:272,279 – 1998/0728/sys/src/9/ip/rudp.c:293,300 | ||
| 1998/0630 | bp->rp += 4; /* Igonore local port */ break; default: | |
| 1998/0726 |
| |
| 1998/0728 | ipmove(raddr, c->raddr); ipmove(laddr, c->laddr); | |
| 1998/0726 | rport = c->rport; | |
| 1998/0630 | break; | |
| 1998/0726/sys/src/9/ip/rudp.c:282,347 – 1998/0728/sys/src/9/ip/rudp.c:303,364 | ||
| 1998/0630 | dlen = blocklen(bp); /* Make space to fit rudp & ip header */ | |
| 1998/0728 | bp = padblock(bp, UDP_IPHDR+UDP_RHDRSIZE); | |
| 1998/0630 | if(bp == nil) return; | |
| 1998/0728 | uh = (Udphdr *)(bp->rp); | |
| 1998/0630 |
| |
| 1998/0728 | rh = (Rudphdr*)uh; | |
| 1998/0630 | ||
| 1998/0726 | ||
| 1998/0630 |
| |
| 1998/0728 | ptcllen = dlen + (UDP_RHDRSIZE-UDP_PHDRSIZE); | |
| 1998/0630 | uh->Unused = 0; | |
| 1998/0728 | uh->udpproto = IP_UDPPROTO; | |
| 1998/0630 | uh->frag[0] = 0; uh->frag[1] = 0; | |
| 1998/0728 | hnputs(uh->udpplen, ptcllen); | |
| 1998/0630 | switch(ucb->headers){ case 4: case 6: | |
| 1998/0728 | v6tov4(uh->udpdst, raddr); hnputs(uh->udpdport, rport); v6tov4(uh->udpsrc, laddr); | |
| 1998/0630 | break; default: | |
| 1998/0728 | v6tov4(uh->udpdst, c->raddr); hnputs(uh->udpdport, c->rport); | |
| 1998/0630 | if(ipcmp(c->laddr, IPnoaddr) == 0) findlocalip(f, c->laddr, c->raddr); | |
| 1998/0728 | v6tov4(uh->udpsrc, c->laddr); | |
| 1998/0630 | break; } | |
| 1998/0728 | hnputs(uh->udpsport, c->lport); hnputs(uh->udplen, ptcllen); uh->udpcksum[0] = 0; uh->udpcksum[1] = 0; | |
| 1998/0630 |
| |
| 1998/0726 |
| |
| 1998/0728 | qlock(ucb); r = relstate(ucb, raddr, rport, "kick"); | |
| 1998/0630 | r->sndseq++; | |
| 1998/0728 | hnputl(rh->relseq, r->sndseq); hnputl(rh->relsgen, r->sndgen); | |
| 1998/0630 |
| |
| 1998/0728 | hnputl(rh->relack, r->rcvseq); /* ACK last rcvd packet */ hnputl(rh->relagen, r->rcvgen); | |
| 1998/0630 | if(r->rcvseq < r->acksent) r->acksent = r->rcvseq; | |
| 1998/0728 | hnputs(uh->udpcksum, ptclcsum(bp, UDP_IPHDR, dlen+UDP_RHDRSIZE)); | |
| 1998/0630 |
| |
| 1998/0728 | relackq(r, bp); qunlock(ucb); | |
| 1998/0630 | upriv->ustats.rudpOutDatagrams++; | |
| 1998/0728 | DPRINT("sent: %d/%d, %d/%d, r->sndgen = %d\n", r->sndseq, r->sndgen, r->rcvseq, r->rcvgen, r->sndgen); | |
| 1998/0630 | ||
| 1998/0726 |
| |
| 1998/0630 |
| |
| 1998/0726/sys/src/9/ip/rudp.c:349,355 – 1998/0728/sys/src/9/ip/rudp.c:366,372 | ||
| 1998/0630 | rudpiput(Proto *rudp, uchar *ia, Block *bp) { int len, olen, ottl; | |
| 1998/0728 | Udphdr *uh; | |
| 1998/0630 | Conv *c, **p; Rudpcb *ucb; uchar raddr[IPaddrlen], laddr[IPaddrlen]; | |
| 1998/0726/sys/src/9/ip/rudp.c:362,368 – 1998/0728/sys/src/9/ip/rudp.c:379,385 | ||
| 1998/0630 | upriv->ustats.rudpInDatagrams++; | |
| 1998/0728 | uh = (Udphdr*)(bp->rp); | |
| 1998/0630 | /* Put back pseudo header for checksum * (remember old values for icmpnoconv()) | |
| 1998/0726/sys/src/9/ip/rudp.c:369,387 – 1998/0728/sys/src/9/ip/rudp.c:386,402 | ||
| 1998/0630 | */ ottl = uh->Unused; uh->Unused = 0; | |
| 1998/0728 | len = nhgets(uh->udplen); olen = nhgets(uh->udpplen); hnputs(uh->udpplen, len); | |
| 1998/0630 |
| |
| 1998/0728 | v4tov6(raddr, uh->udpsrc); v4tov6(laddr, uh->udpdst); lport = nhgets(uh->udpdport); rport = nhgets(uh->udpsport); | |
| 1998/0630 |
| |
| 1998/0728 | if(nhgets(uh->udpcksum)) { if(ptclcsum(bp, UDP_IPHDR, len+UDP_PHDRSIZE)) { | |
| 1998/0630 | upriv->ustats.rudpInErrors++; | |
| 1998/0726 | upriv->csumerr++; | |
| 1998/0630 | netlog(f, Logrudp, "rudp: checksum error %I\n", raddr); | |
| 1998/0726/sys/src/9/ip/rudp.c:397,404 – 1998/0728/sys/src/9/ip/rudp.c:412,430 | ||
| 1998/0630 | c = *p; if(c->inuse == 0) continue; | |
| 1998/0728 | if(c->lport == lport){ ucb = (Rudpcb*)c->ptcl; /* with headers turned on, descriminate only on local port */ if(ucb->headers) break; /* otherwise discriminate on lport, rport, and raddr */ if(c->rport == 0 || c->rport == rport) if(ipisbm(c->raddr) || ipcmp(c->raddr, IPnoaddr) == 0 || ipcmp(c->raddr, raddr) == 0) break; } | |
| 1998/0630 | } if(*p == nil) { | |
| 1998/0726/sys/src/9/ip/rudp.c:405,414 – 1998/0728/sys/src/9/ip/rudp.c:431,440 | ||
| 1998/0630 | upriv->ustats.rudpNoPorts++; netlog(f, Logrudp, "rudp: no conv %I!%d -> %I!%d\n", raddr, rport, laddr, lport); | |
| 1998/0728 | DPRINT("rudp: no conv %I!%d -> %I!%d\n", raddr, rport, | |
| 1998/0630 | laddr, lport); uh->Unused = ottl; | |
| 1998/0728 | hnputs(uh->udpplen, olen); | |
| 1998/0630 | icmpnoconv(f, bp); freeblist(bp); return; | |
| 1998/0726/sys/src/9/ip/rudp.c:416,425 – 1998/0728/sys/src/9/ip/rudp.c:442,451 | ||
| 1998/0630 | ucb = (Rudpcb*)c->ptcl; | |
| 1998/0728 | qlock(ucb); if(reliput(c, bp, raddr, rport) < 0){ qunlock(ucb); freeb(bp); | |
| 1998/0630 | return; } | |
| 1998/0726/sys/src/9/ip/rudp.c:427,438 – 1998/0728/sys/src/9/ip/rudp.c:453,464 | ||
| 1998/0630 | * Trim the packet down to data size */ | |
| 1998/0728 | len -= (UDP_RHDRSIZE-UDP_PHDRSIZE); bp = trimblock(bp, UDP_IPHDR+UDP_RHDRSIZE, len); | |
| 1998/0630 | if(bp == nil){ netlog(f, Logrudp, "rudp: len err %I.%d -> %I.%d\n", raddr, rport, laddr, lport); | |
| 1998/0728 | DPRINT("rudp: len err %I.%d -> %I.%d\n", | |
| 1998/0630 | raddr, rport, laddr, lport); upriv->lenerr++; return; | |
| 1998/0726/sys/src/9/ip/rudp.c:441,452 – 1998/0728/sys/src/9/ip/rudp.c:467,476 | ||
| 1998/0630 | netlog(f, Logrudpmsg, "rudp: %I.%d -> %I.%d l %d\n", raddr, rport, laddr, lport, len); | |
| 1998/0728 | bp = padblock(bp, UDP_USEAD6); | |
| 1998/0630 | ipmove(bp->rp, raddr); if(ipforme(f, laddr) == Runi) ipmove(bp->rp+IPaddrlen, laddr); | |
| 1998/0726/sys/src/9/ip/rudp.c:457,463 – 1998/0728/sys/src/9/ip/rudp.c:481,487 | ||
| 1998/0630 | break; case 4: /* pass the src address */ | |
| 1998/0728 | bp = padblock(bp, UDP_USEAD4); | |
| 1998/0630 | v6tov4(bp->rp, raddr); if(ipforme(f, laddr) == Runi) v6tov4(bp->rp+IPv4addrlen, laddr); | |
| 1998/0726/sys/src/9/ip/rudp.c:492,498 – 1998/0728/sys/src/9/ip/rudp.c:516,522 | ||
| 1998/0630 | else qpass(c->rq, bp); | |
| 1998/0728 | qunlock(ucb); | |
| 1998/0630 | } char* | |
| 1998/0726/sys/src/9/ip/rudp.c:516,532 – 1998/0728/sys/src/9/ip/rudp.c:540,556 | ||
| 1998/0630 | void rudpadvise(Proto *rudp, Block *bp, char *msg) { | |
| 1998/0728 | Udphdr *h; | |
| 1998/0630 | uchar source[IPaddrlen], dest[IPaddrlen]; ushort psource, pdest; Conv *s, **p; | |
| 1998/0728 | h = (Udphdr*)(bp->rp); | |
| 1998/0630 |
| |
| 1998/0728 | v4tov6(dest, h->udpdst); v4tov6(source, h->udpsrc); psource = nhgets(h->udpsport); pdest = nhgets(h->udpdport); | |
| 1998/0630 | /* Look for a connection */ for(p = rudp->conv; *p; p++) { | |
| 1998/0726/sys/src/9/ip/rudp.c:577,583 – 1998/0728/sys/src/9/ip/rudp.c:601,607 | ||
| 1998/0630 | rudp->rcv = rudpiput; rudp->advise = rudpadvise; rudp->stats = rudpstats; | |
| 1998/0728 | rudp->ipproto = IP_UDPPROTO; | |
| 1998/0630 | rudp->nc = 16; rudp->ptclsize = sizeof(Rudpcb); | |
| 1998/0726/sys/src/9/ip/rudp.c:652,666 – 1998/0728/sys/src/9/ip/rudp.c:676,688 | ||
| 1998/0630 | * get the state record for a conversation */ Reliable* | |
| 1998/0726 |
| |
| 1998/0728 | relstate(Rudpcb *ucb, uchar *addr, ushort port, char *from) | |
| 1998/0630 | { Reliable *r, **l; | |
| 1998/0726 | ||
| 1998/0630 | l = &ucb->r; for(r = *l; r; r = *l){ | |
| 1998/0728 | if(memcmp(addr, r->addr, IPaddrlen) == 0 && | |
| 1998/0630 | port == r->port) break; l = &r->next; | |
| 1998/0726/sys/src/9/ip/rudp.c:670,680 – 1998/0728/sys/src/9/ip/rudp.c:692,702 | ||
| 1998/0630 | if(r == nil){ if(generation == 0) generation = TK2SEC(MACHP(0)->ticks); | |
| 1998/0726 |
| |
| 1998/0630 |
| |
| 1998/0728 | DPRINT("from %s new state %d for %I!%d\n", from, generation, addr, port); r = smalloc(sizeof(Reliable)); | |
| 1998/0630 | *l = r; | |
| 1998/0728 | memmove(r->addr, addr, IPaddrlen); | |
| 1998/0630 | r->port = port; r->unacked = 0; r->sndgen = generation++; | |
| 1998/0726/sys/src/9/ip/rudp.c:701,716 – 1998/0728/sys/src/9/ip/rudp.c:723,738 | ||
| 1998/0630 | Block *nbp; Rudpcb *ucb; | |
| 1998/0726 | Rudppriv *upriv; | |
| 1998/0630 |
| |
| 1998/0728 | Udphdr *uh; | |
| 1998/0630 | Reliable *r; | |
| 1998/0728 | Rudphdr *rh; | |
| 1998/0630 | ulong seq, ack, sgen, agen, ackreal; /* get fields */ | |
| 1998/0728 | uh = (Udphdr*)(bp->rp); rh = (Rudphdr*)uh; | |
| 1998/0630 | seq = nhgetl(rh->relseq); sgen = nhgetl(rh->relsgen); ack = nhgetl(rh->relack); | |
| 1998/0726/sys/src/9/ip/rudp.c:719,725 – 1998/0728/sys/src/9/ip/rudp.c:741,747 | ||
| 1998/0630 | ||
| 1998/0726 | upriv = c->p->priv; | |
| 1998/0630 | ucb = (Rudpcb*)c->ptcl; | |
| 1998/0726 |
| |
| 1998/0728 | r = relstate(ucb, addr, port, "input"); | |
| 1998/0630 | ||
| 1998/0726 | DPRINT("rcvd %d/%d, %d/%d, r->sndgen = %d\n", | |
| 1998/0726/sys/src/9/ip/rudp.c:770,777 – 1998/0728/sys/src/9/ip/rudp.c:792,799 | ||
| 1998/0630 | if(seq == 0) return -1; | |
| 1998/0726 |
| |
| 1998/0728 | if(DEBUG && ++drop == drop_rate){ DPRINT("drop pkt on purpose\n"); | |
| 1998/0726 | drop = 0; return -1; } | |
| 1998/0726/sys/src/9/ip/rudp.c:790,828 – 1998/0728/sys/src/9/ip/rudp.c:812,846 | ||
| 1998/0630 | void relsendack(Conv *c, Reliable *r) { | |
| 1998/0728 | Udphdr *uh; | |
| 1998/0630 | Block *bp; | |
| 1998/0728 | Rudphdr *rh; | |
| 1998/0630 | int ptcllen; Fs *f; | |
| 1998/0728 | bp = allocb(UDP_IPHDR + UDP_RHDRSIZE); | |
| 1998/0630 | if(bp == nil) return; | |
| 1998/0728 | bp->wp += UDP_IPHDR + UDP_RHDRSIZE; | |
| 1998/0630 | f = c->p->f; | |
| 1998/0728 | uh = (Udphdr *)(bp->rp); rh = (Rudphdr*)uh; | |
| 1998/0630 |
| |
| 1998/0728 | ptcllen = (UDP_RHDRSIZE-UDP_PHDRSIZE); | |
| 1998/0630 | uh->Unused = 0; | |
| 1998/0728 | uh->udpproto = IP_UDPPROTO; | |
| 1998/0630 | uh->frag[0] = 0; uh->frag[1] = 0; | |
| 1998/0728 | hnputs(uh->udpplen, ptcllen); | |
| 1998/0630 |
| |
| 1998/0728 | v6tov4(uh->udpdst, r->addr); hnputs(uh->udpdport, r->port); hnputs(uh->udpsport, c->lport); | |
| 1998/0630 | if(ipcmp(c->laddr, IPnoaddr) == 0) findlocalip(f, c->laddr, c->raddr); | |
| 1998/0728 | v6tov4(uh->udpsrc, c->laddr); hnputs(uh->udplen, ptcllen); | |
| 1998/0630 |
| |
| 1998/0726/sys/src/9/ip/rudp.c:831,841 – 1998/0728/sys/src/9/ip/rudp.c:849,859 | ||
| 1998/0630 | if(r->acksent < r->rcvseq) r->acksent = r->rcvseq; | |
| 1998/0728 | uh->udpcksum[0] = 0; uh->udpcksum[1] = 0; hnputs(uh->udpcksum, ptclcsum(bp, UDP_IPHDR, UDP_RHDRSIZE)); | |
| 1998/0630 |
| |
| 1998/0728 | DPRINT("sendack: %d/%d, %d/%d\n", 0, r->sndgen, r->rcvseq, r->rcvgen); | |
| 1998/0630 | ipoput(f, bp, 0, c->ttl); } | |
| 1998/0726/sys/src/9/ip/rudp.c:843,849 – 1998/0728/sys/src/9/ip/rudp.c:861,867 | ||
| 1998/0630 | * called with ucb locked (and c locked if user initiated close) */ void | |
| 1998/0728 | relhangup(Conv *, Reliable *r) | |
| 1998/0630 | { Block *bp; | |
| 1998/0728/sys/src/9/ip/rudp.c:492,498 – 1998/0731/sys/src/9/ip/rudp.c:492,498 (short | long) | ||
| 1998/0630 | break; default: /* connection oriented rudp */ | |
| 1998/0731 | if(ipcmp(c->raddr, IPnoaddr) == 0){ | |
| 1998/0630 | /* save the src address in the conversation */ ipmove(c->raddr, raddr); c->rport = rport; | |
| 1998/0728/sys/src/9/ip/rudp.c:691,697 – 1998/0731/sys/src/9/ip/rudp.c:691,697 | ||
| 1998/0630 | /* no state for this addr/port, create some */ if(r == nil){ if(generation == 0) | |
| 1998/0731 | generation = rand(); | |
| 1998/0728 | DPRINT("from %s new state %d for %I!%d\n", from, generation, addr, port); r = smalloc(sizeof(Reliable)); | |
| 1998/0728/sys/src/9/ip/rudp.c:727,734 – 1998/0731/sys/src/9/ip/rudp.c:727,732 | ||
| 1998/0630 | Reliable *r; | |
| 1998/0728 | Rudphdr *rh; | |
| 1998/0630 | ulong seq, ack, sgen, agen, ackreal; | |
| 1998/0728 | uh = (Udphdr*)(bp->rp); | |
| 1998/0731/sys/src/9/ip/rudp.c:14,19 – 1998/0801/sys/src/9/ip/rudp.c:14,28 (short | long) | ||
| 1998/0726 | #define DEBUG 0 #define DPRINT if(DEBUG)print | |
| 1998/0630 | ||
| 1998/0801 | #define SEQDIFF(a,b) ( (a)>=(b)?\ (a)-(b):\ 0xffffffffUL-((b)-(a)) ) #define INSEQ(a,start,end) ( (start)<=(end)?\ ((a)>(start)&&(a)<=(end)):\ ((a)>(start)||(a)<=(end)) ) #define UNACKED(r) SEQDIFF(r->sndseq, r->ackrcvd) #define NEXTSEQ(a) ( (a)+1 == 0 ? 1 : (a)+1 ) | |
| 1998/0630 | enum { | |
| 1998/0728 | UDP_HDRSIZE = 20, /* pseudo header + udp header */ | |
| 1998/0731/sys/src/9/ip/rudp.c:27,33 – 1998/0801/sys/src/9/ip/rudp.c:36,42 | ||
| 1998/0630 | Rudprxms = 200, Rudptickms = 100, | |
| 1998/0726 | Rudpmaxxmit = 10, | |
| 1998/0630 | ||
| 1998/0801 | Maxunacked = 100, | |
| 1998/0630 | }; | |
| 1998/0728 | typedef struct Udphdr Udphdr; | |
| 1998/0731/sys/src/9/ip/rudp.c:93,99 – 1998/0801/sys/src/9/ip/rudp.c:102,108 | ||
| 1998/0630 | { Reliable *next; | |
| 1998/0801 | uchar addr[IPaddrlen]; /* always V6 when put here */ | |
| 1998/0630 | ushort port; Block *unacked; /* unacked msg list */ | |
| 1998/0731/sys/src/9/ip/rudp.c:110,115 – 1998/0801/sys/src/9/ip/rudp.c:119,129 | ||
| 1998/0630 | ulong acksent; /* last ack sent */ ulong ackrcvd; /* last msg for which ack was rcvd */ | |
| 1998/0801 | /* flow control */ QLock lock; Rendez vous; int blocked; | |
| 1998/0630 | }; | |
| 1998/0731/sys/src/9/ip/rudp.c:185,192 – 1998/0801/sys/src/9/ip/rudp.c:199,215 | ||
| 1998/0630 | static int rudpstate(Conv *c, char *state, int n) { | |
| 1998/0726 |
| |
| 1998/0801 | Rudpcb *ucb; Reliable *r; int m; m = snprint(state, n, "%s", c->inuse?"Open":"Closed"); ucb = (Rudpcb*)c->ptcl; qlock(ucb); for(r = ucb->r; r; r = r->next) m += snprint(state+m, n-m, " %I/%d", r->addr, UNACKED(r)); qunlock(ucb); return m; | |
| 1998/0630 | } static char* | |
| 1998/0731/sys/src/9/ip/rudp.c:238,243 – 1998/0801/sys/src/9/ip/rudp.c:261,272 | ||
| 1998/0630 | unlock(c); } | |
| 1998/0801 | int flow(Reliable *r) { return UNACKED(r) <= Maxunacked; } | |
| 1998/0630 | void rudpkick(Conv *c, int) { | |
| 1998/0731/sys/src/9/ip/rudp.c:339,345 – 1998/0801/sys/src/9/ip/rudp.c:368,374 | ||
| 1998/0630 | ||
| 1998/0728 | qlock(ucb); r = relstate(ucb, raddr, rport, "kick"); | |
| 1998/0630 |
| |
| 1998/0801 | r->sndseq = NEXTSEQ(r->sndseq); | |
| 1998/0728 | hnputl(rh->relseq, r->sndseq); hnputl(rh->relsgen, r->sndgen); | |
| 1998/0630 | ||
| 1998/0731/sys/src/9/ip/rudp.c:346,352 – 1998/0801/sys/src/9/ip/rudp.c:375,381 | ||
| 1998/0728 | hnputl(rh->relack, r->rcvseq); /* ACK last rcvd packet */ hnputl(rh->relagen, r->rcvgen); | |
| 1998/0630 |
| |
| 1998/0801 | if(r->rcvseq != r->acksent) | |
| 1998/0630 | r->acksent = r->rcvseq; | |
| 1998/0728 | hnputs(uh->udpcksum, ptclcsum(bp, UDP_IPHDR, dlen+UDP_RHDRSIZE)); | |
| 1998/0731/sys/src/9/ip/rudp.c:360,365 – 1998/0801/sys/src/9/ip/rudp.c:389,403 | ||
| 1998/0728 | r->sndseq, r->sndgen, r->rcvseq, r->rcvgen, r->sndgen); | |
| 1998/0630 | ipoput(f, bp, 0, c->ttl); | |
| 1998/0801 | /* flow control of sorts */ qlock(&r->lock); if(UNACKED(r) > Maxunacked){ r->blocked = 1; sleep(&r->vous, flow, r); r->blocked = 0; } qunlock(&r->lock); | |
| 1998/0630 | } void | |
| 1998/0731/sys/src/9/ip/rudp.c:664,670 – 1998/0801/sys/src/9/ip/rudp.c:702,708 | ||
| 1998/0630 | if(r->timeout > Rudprxms*r->xmits) relrexmit(c, r); } | |
| 1998/0801 | if(r->acksent != r->rcvseq) | |
| 1998/0630 | relsendack(c, r); } | |
| 1998/0726 | qunlock(ucb); | |
| 1998/0731/sys/src/9/ip/rudp.c:736,742 – 1998/0801/sys/src/9/ip/rudp.c:774,779 | ||
| 1998/0630 | ack = nhgetl(rh->relack); agen = nhgetl(rh->relagen); | |
| 1998/0726 | upriv = c->p->priv; | |
| 1998/0630 | ucb = (Rudpcb*)c->ptcl; | |
| 1998/0728 | r = relstate(ucb, addr, port, "input"); | |
| 1998/0731/sys/src/9/ip/rudp.c:748,763 – 1998/0801/sys/src/9/ip/rudp.c:785,804 | ||
| 1998/0630 | /* dequeue acked packets */ if(ack && agen == r->sndgen){ ackreal = 0; | |
| 1998/0801 | while(r->unacked != nil && INSEQ(ack, r->ackrcvd, r->sndseq)){ | |
| 1998/0630 | nbp = r->unacked; r->unacked = nbp->list; | |
| 1998/0726 | DPRINT("%d/%d acked, r->sndgen = %d\n", ack, agen, r->sndgen); | |
| 1998/0630 | freeb(nbp); | |
| 1998/0801 | r->ackrcvd = NEXTSEQ(r->ackrcvd); | |
| 1998/0630 | ackreal = 1; } | |
| 1998/0801 | /* flow control */ if(UNACKED(r) < Maxunacked/8 && r->blocked) wakeup(&r->vous); | |
| 1998/0630 | /* * retransmit next packet if the acked packet * was transmitted more than once | |
| 1998/0731/sys/src/9/ip/rudp.c:777,783 – 1998/0801/sys/src/9/ip/rudp.c:818,823 | ||
| 1998/0630 | if(seq != 1) return -1; | |
| 1998/0731/sys/src/9/ip/rudp.c:786,793 – 1998/0801/sys/src/9/ip/rudp.c:826,833 | ||
| 1998/0630 | r->rcvgen = sgen; } | |
| 1998/0801 | /* no message or input queue full */ if(seq == 0 || qfull(c->rq)) | |
| 1998/0630 | return -1; | |
| 1998/0728 | if(DEBUG && ++drop == drop_rate){ | |
| 1998/0731/sys/src/9/ip/rudp.c:797,805 – 1998/0801/sys/src/9/ip/rudp.c:837,845 | ||
| 1998/0726 | } | |
| 1998/0630 | /* refuse out of order delivery */ | |
| 1998/0801 | if(seq != NEXTSEQ(r->rcvseq)){ | |
| 1998/0726 | upriv->orders++; | |
| 1998/0630 |
| |
| 1998/0801 | DPRINT("out of sequence %d not %d\n", seq, NEXTSEQ(r->rcvseq)); | |
| 1998/0630 | return -1; } r->rcvseq = seq; | |
| 1998/0731/sys/src/9/ip/rudp.c:880,885 – 1998/0801/sys/src/9/ip/rudp.c:920,926 | ||
| 1998/0630 | r->ackrcvd = 0; r->xmits = 0; r->timeout = 0; | |
| 1998/0801 | wakeup(&r->vous); | |
| 1998/0630 | } /* | |
| 1998/0801/sys/src/9/ip/rudp.c:207,213 – 1998/0825/sys/src/9/ip/rudp.c:207,213 (short | long) | ||
|
Bug fix: print format.
rsc Fri Mar 4 12:44:25 2005 | ||
| 1998/0801 | ucb = (Rudpcb*)c->ptcl; qlock(ucb); for(r = ucb->r; r; r = r->next) | |
| 1998/0825 | m += snprint(state+m, n-m, " %I/%ld", r->addr, UNACKED(r)); | |
| 1998/0801 | qunlock(ucb); return m; | |
| 1998/0630 | } | |
| 1998/0801/sys/src/9/ip/rudp.c:385,392 – 1998/0825/sys/src/9/ip/rudp.c:385,392 | ||
| 1998/0630 | upriv->ustats.rudpOutDatagrams++; | |
| 1998/0728 |
| |
| 1998/0825 | DPRINT("sent: %lud/%lud, %lud/%lud\n", r->sndseq, r->sndgen, r->rcvseq, r->rcvgen); | |
| 1998/0630 | ipoput(f, bp, 0, c->ttl); | |
| 1998/0801 | ||
| 1998/0801/sys/src/9/ip/rudp.c:611,617 – 1998/0825/sys/src/9/ip/rudp.c:611,617 | ||
| 1998/0630 | Rudppriv *upriv; upriv = rudp->priv; | |
| 1998/0726 |
| |
| 1998/0825 | return snprint(buf, len, "%lud %lud %lud %lud %lud %lud\n", | |
| 1998/0630 | upriv->ustats.rudpInDatagrams, upriv->ustats.rudpNoPorts, upriv->ustats.rudpInErrors, | |
| 1998/0801/sys/src/9/ip/rudp.c:730,736 – 1998/0825/sys/src/9/ip/rudp.c:730,736 | ||
| 1998/0630 | if(r == nil){ if(generation == 0) | |
| 1998/0731 | generation = rand(); | |
| 1998/0728 |
| |
| 1998/0825 | DPRINT("from %s new state %lud for %I!%ud\n", | |
| 1998/0728 | from, generation, addr, port); r = smalloc(sizeof(Reliable)); | |
| 1998/0630 | *l = r; | |
| 1998/0801/sys/src/9/ip/rudp.c:779,785 – 1998/0825/sys/src/9/ip/rudp.c:779,785 | ||
| 1998/0728 | r = relstate(ucb, addr, port, "input"); | |
| 1998/0630 | ||
| 1998/0726 |
| |
| 1998/0825 | DPRINT("rcvd %lud/%lud, %lud/%lud, r->sndgen = %lud\n", | |
| 1998/0726 | seq, sgen, ack, agen, r->sndgen); | |
| 1998/0630 | /* dequeue acked packets */ | |
| 1998/0801/sys/src/9/ip/rudp.c:788,794 – 1998/0825/sys/src/9/ip/rudp.c:788,794 | ||
| 1998/0801 | while(r->unacked != nil && INSEQ(ack, r->ackrcvd, r->sndseq)){ | |
| 1998/0630 | nbp = r->unacked; r->unacked = nbp->list; | |
| 1998/0726 |
| |
| 1998/0825 | DPRINT("%lud/%lud acked, r->sndgen = %lud\n", | |
| 1998/0726 | ack, agen, r->sndgen); | |
| 1998/0630 | freeb(nbp); | |
| 1998/0801 | r->ackrcvd = NEXTSEQ(r->ackrcvd); | |
| 1998/0801/sys/src/9/ip/rudp.c:820,826 – 1998/0825/sys/src/9/ip/rudp.c:820,826 | ||
| 1998/0630 | /* new connection */ if(r->rcvgen != 0){ | |
| 1998/0825 | DPRINT("new con r->rcvgen = %lud, sgen = %lud\n", r->rcvgen, sgen); | |
| 1998/0630 | relhangup(c, r); } r->rcvgen = sgen; | |
| 1998/0801/sys/src/9/ip/rudp.c:839,845 – 1998/0825/sys/src/9/ip/rudp.c:839,845 | ||
| 1998/0630 | /* refuse out of order delivery */ | |
| 1998/0801 | if(seq != NEXTSEQ(r->rcvseq)){ | |
| 1998/0726 | upriv->orders++; | |
| 1998/0801 |
| |
| 1998/0825 | DPRINT("out of sequence %lud not %lud\n", seq, NEXTSEQ(r->rcvseq)); | |
| 1998/0630 | return -1; } r->rcvseq = seq; | |
| 1998/0801/sys/src/9/ip/rudp.c:891,897 – 1998/0825/sys/src/9/ip/rudp.c:891,897 | ||
| 1998/0728 | uh->udpcksum[1] = 0; hnputs(uh->udpcksum, ptclcsum(bp, UDP_IPHDR, UDP_RHDRSIZE)); | |
| 1998/0630 | ||
| 1998/0728 |
| |
| 1998/0825 | DPRINT("sendack: %lud/%lud, %lud/%lud\n", 0L, r->sndgen, r->rcvseq, r->rcvgen); | |
| 1998/0630 | ipoput(f, bp, 0, c->ttl); } | |
| 1998/0801/sys/src/9/ip/rudp.c:943,948 – 1998/0825/sys/src/9/ip/rudp.c:943,948 | ||
| 1998/0630 | ||
| 1998/0726 | upriv->rxmits++; | |
| 1998/0630 | np = copyblock(r->unacked, blocklen(r->unacked)); | |
| 1998/0726 |
| |
| 1998/0825 | DPRINT("rxmit r->ackrvcd+1 = %lud\n", r->ackrcvd+1); | |
| 1998/0630 | ipoput(f, np, 0, c->ttl); } | |
| 1998/0825/sys/src/9/ip/rudp.c:152,157 – 1998/0924/sys/src/9/ip/rudp.c:152,160 (short | long) | ||
| 1998/0726 | ulong rxmits; /* # of retransmissions */ ulong orders; /* # of out of order pkts */ | |
| 1998/0630 | ||
| 1998/0924 | /* keeping track of the ack kproc */ int ackprocstarted; QLock apl; | |
| 1998/0630 | }; | |
| 1998/0825/sys/src/9/ip/rudp.c:184,194 – 1998/0924/sys/src/9/ip/rudp.c:187,216 | ||
| 1998/0728 | void relhangup(Conv *, Reliable *); void relrexmit(Conv *, Reliable *); | |
| 1998/0630 | ||
| 1998/0924 | static void rudpstartackproc(Proto *rudp) { Rudppriv *rpriv; char kpname[NAMELEN]; rpriv = rudp->priv; if(rpriv->ackprocstarted == 0){ qlock(&rpriv->apl); if(rpriv->ackprocstarted == 0){ sprint(kpname, "#I%drudpack", rudp->f->dev); kproc(kpname, relackproc, rudp); rpriv->ackprocstarted = 1; } qunlock(&rpriv->apl); } } | |
| 1998/0630 | static char* rudpconnect(Conv *c, char **argv, int argc) { char *e; | |
| 1998/0924 | rudpstartackproc(c->p); | |
| 1998/0630 | e = Fsstdconnect(c, argv, argc); Fsconnected(c, e); | |
| 1998/0825/sys/src/9/ip/rudp.c:217,222 – 1998/0924/sys/src/9/ip/rudp.c:239,245 | ||
| 1998/0630 | { char *e; | |
| 1998/0924 | rudpstartackproc(c->p); | |
| 1998/0630 | e = Fsstdannounce(c, argv, argc); if(e != nil) return e; | |
| 1998/0825/sys/src/9/ip/rudp.c:644,652 – 1998/0924/sys/src/9/ip/rudp.c:667,672 | ||
| 1998/0630 | rudp->ptclsize = sizeof(Rudpcb); Fsproto(fs, rudp); | |
| 1998/0726 |
| |
| 1998/0630 |
| |
| 1998/0924/sys/src/9/ip/rudp.c:34,40 – 1998/1117/sys/src/9/ip/rudp.c:34,40 (short | long) | ||
| 1998/0728 | UDP_USEAD4 = 12, | |
| 1998/0630 | Rudprxms = 200, | |
| 1998/1117 | Rudptickms = 50, | |
| 1998/0726 | Rudpmaxxmit = 10, | |
| 1998/0801 | Maxunacked = 100, | |
| 1998/0630 | }; | |
| 1998/0924/sys/src/9/ip/rudp.c:858,863 – 1998/1117/sys/src/9/ip/rudp.c:858,864 | ||
| 1998/0726 | ||
| 1998/0630 | /* refuse out of order delivery */ | |
| 1998/0801 | if(seq != NEXTSEQ(r->rcvseq)){ | |
| 1998/1117 | relsendack(c, r); /* tell him we got it already */ | |
| 1998/0726 | upriv->orders++; | |
| 1998/0825 | DPRINT("out of sequence %lud not %lud\n", seq, NEXTSEQ(r->rcvseq)); | |
| 1998/0630 | return -1; | |
| 1998/1117/sys/src/9/ip/rudp.c:161,170 – 1998/1118/sys/src/9/ip/rudp.c:161,166 (short | long) | ||
| 1998/0630 | static ulong generation = 0; static Rendez rend; | |
| 1998/0726 |
| |
| 1998/0630 | /* * protocol specific part of Conv */ | |
| 1998/1117/sys/src/9/ip/rudp.c:173,178 – 1998/1118/sys/src/9/ip/rudp.c:169,175 | ||
| 1998/0630 | { QLock; uchar headers; | |
| 1998/1118 | uchar randdrop; | |
| 1998/0630 | Reliable *r; }; | |
| 1998/1117/sys/src/9/ip/rudp.c:261,266 – 1998/1118/sys/src/9/ip/rudp.c:258,272 | ||
| 1998/0630 | Rudpcb *ucb; Reliable *r, *nr; | |
| 1998/1118 | /* force out any delayed acks */ ucb = (Rudpcb*)c->ptcl; qlock(ucb); for(r = ucb->r; r; r = r->next){ if(r->acksent != r->rcvseq) relsendack(c, r); } qunlock(ucb); | |
| 1998/0630 | qclose(c->rq); qclose(c->wq); qclose(c->eq); | |
| 1998/1117/sys/src/9/ip/rudp.c:269,278 – 1998/1118/sys/src/9/ip/rudp.c:275,286 | ||
| 1998/0630 | c->lport = 0; c->rport = 0; | |
| 1998/1118 | ucb->randdrop = 0; | |
| 1998/0728 | qlock(ucb); for(r = ucb->r; r; r = nr){ | |
| 1998/1118 | if(r->acksent != r->rcvseq) relsendack(c, r); | |
| 1998/0630 | nr = r->next; | |
| 1998/0728 | relhangup(c, r); free(r); | |
| 1998/1117/sys/src/9/ip/rudp.c:284,289 – 1998/1118/sys/src/9/ip/rudp.c:292,312 | ||
| 1998/0630 | unlock(c); } | |
| 1998/1118 | /* * randomly don't send packets */ static void doipoput(Conv *c, Fs *f, Block *bp, int x, int ttl) { Rudpcb *ucb; ucb = (Rudpcb*)c->ptcl; if(ucb->randdrop && nrand(10) == 1) freeblist(bp); else ipoput(f, bp, x, ttl); } | |
| 1998/0801 | int flow(Reliable *r) { | |
| 1998/1117/sys/src/9/ip/rudp.c:411,417 – 1998/1118/sys/src/9/ip/rudp.c:434,440 | ||
| 1998/0825 | DPRINT("sent: %lud/%lud, %lud/%lud\n", r->sndseq, r->sndgen, r->rcvseq, r->rcvgen); | |
| 1998/0630 |
| |
| 1998/1118 | doipoput(c, f, bp, 0, c->ttl); | |
| 1998/0801 | /* flow control of sorts */ qlock(&r->lock); | |
| 1998/1117/sys/src/9/ip/rudp.c:593,598 – 1998/1118/sys/src/9/ip/rudp.c:616,624 | ||
| 1998/0630 | } else if(strcmp(f[0], "headers") == 0){ ucb->headers = 6; return nil; | |
| 1998/1118 | } else if(strcmp(f[0], "randdrop") == 0){ ucb->randdrop = 1; return nil; | |
| 1998/0630 | } } return "unknown control request"; | |
| 1998/1117/sys/src/9/ip/rudp.c:802,807 – 1998/1118/sys/src/9/ip/rudp.c:828,846 | ||
| 1998/0825 | DPRINT("rcvd %lud/%lud, %lud/%lud, r->sndgen = %lud\n", | |
| 1998/0726 | seq, sgen, ack, agen, r->sndgen); | |
| 1998/0630 | ||
| 1998/1118 | /* make sure we're not talking to a new remote side */ if(r->rcvgen != sgen){ if(seq != 1) return -1; /* new connection */ if(r->rcvgen != 0){ DPRINT("new con r->rcvgen = %lud, sgen = %lud\n", r->rcvgen, sgen); relhangup(c, r); } r->rcvgen = sgen; } | |
| 1998/0630 | /* dequeue acked packets */ if(ack && agen == r->sndgen){ ackreal = 0; | |
| 1998/1117/sys/src/9/ip/rudp.c:833,861 – 1998/1118/sys/src/9/ip/rudp.c:872,881 | ||
| 1998/0630 | } | |
| 1998/0825 |
| |
| 1998/0630 |
| |
| 1998/0801 | /* no message or input queue full */ if(seq == 0 || qfull(c->rq)) | |
| 1998/0630 | return -1; | |
| 1998/0728 |
| |
| 1998/0726 |
| |
| 1998/0630 | /* refuse out of order delivery */ | |
| 1998/0801 | if(seq != NEXTSEQ(r->rcvseq)){ | |
| 1998/1117 | relsendack(c, r); /* tell him we got it already */ | |
| 1998/1117/sys/src/9/ip/rudp.c:913,919 – 1998/1118/sys/src/9/ip/rudp.c:933,939 | ||
| 1998/0728 | hnputs(uh->udpcksum, ptclcsum(bp, UDP_IPHDR, UDP_RHDRSIZE)); | |
| 1998/0630 | ||
| 1998/0825 | DPRINT("sendack: %lud/%lud, %lud/%lud\n", 0L, r->sndgen, r->rcvseq, r->rcvgen); | |
| 1998/0630 |
| |
| 1998/1118 | doipoput(c, f, bp, 0, c->ttl); | |
| 1998/0630 | } /* | |
| 1998/1117/sys/src/9/ip/rudp.c:920,929 – 1998/1118/sys/src/9/ip/rudp.c:940,954 | ||
| 1998/0630 | * called with ucb locked (and c locked if user initiated close) */ void | |
| 1998/0728 |
| |
| 1998/1118 | relhangup(Conv *c, Reliable *r) | |
| 1998/0630 | { | |
| 1998/1118 | int n; | |
| 1998/0630 | Block *bp; | |
| 1998/1118 | char hup[ERRLEN]; | |
| 1998/0630 | ||
| 1998/1118 | n = snprint(hup, sizeof(hup), "hangup %I!%d", r->addr, r->port); qproduce(c->eq, hup, n); | |
| 1998/0630 | /* * dump any unacked outgoing messages */ | |
| 1998/1117/sys/src/9/ip/rudp.c:965,969 – 1998/1118/sys/src/9/ip/rudp.c:990,994 | ||
| 1998/0726 | upriv->rxmits++; | |
| 1998/0630 | np = copyblock(r->unacked, blocklen(r->unacked)); | |
| 1998/0825 | DPRINT("rxmit r->ackrvcd+1 = %lud\n", r->ackrcvd+1); | |
| 1998/0630 |
| |
| 1998/1118 | doipoput(c, f, np, 0, c->ttl); | |
| 1998/0630 | } | |
| 1998/1118/sys/src/9/ip/rudp.c:828,833 – 1998/1124/sys/src/9/ip/rudp.c:828,837 (short | long) | ||
| 1998/0825 | DPRINT("rcvd %lud/%lud, %lud/%lud, r->sndgen = %lud\n", | |
| 1998/0726 | seq, sgen, ack, agen, r->sndgen); | |
| 1998/0630 | ||
| 1998/1124 | /* if acking an incorrect generation, ignore */ if(ack && agen != r->sndgen) return -1; | |
| 1998/1118 | /* make sure we're not talking to a new remote side */ if(r->rcvgen != sgen){ if(seq != 1) | |
| 1998/1124/sys/src/9/ip/rudp.c:774,780 – 1998/1127/sys/src/9/ip/rudp.c:774,780 (short | long) | ||
| 1998/0630 | /* no state for this addr/port, create some */ if(r == nil){ | |
| 1998/1127 | while(generation == 0) | |
| 1998/0731 | generation = rand(); | |
| 1998/0825 | DPRINT("from %s new state %lud for %I!%ud\n", | |
| 1998/0728 | from, generation, addr, port); | |
| 1998/1124/sys/src/9/ip/rudp.c:834,840 – 1998/1127/sys/src/9/ip/rudp.c:834,840 | ||
| 1998/1124 | ||
| 1998/1118 | /* make sure we're not talking to a new remote side */ if(r->rcvgen != sgen){ | |
| 1998/1127 | if(seq != 0 && seq != 1) | |
| 1998/1118 | return -1; /* new connection */ | |
| 1998/1127/sys/src/9/ip/rudp.c:301,307 – 1998/1230/sys/src/9/ip/rudp.c:301,307 (short | long) | ||
| 1998/1118 | Rudpcb *ucb; ucb = (Rudpcb*)c->ptcl; | |
| 1998/1230 | if(ucb->randdrop && nrand(100) < ucb->randdrop) | |
| 1998/1118 | freeblist(bp); else ipoput(f, bp, x, ttl); | |
| 1998/1127/sys/src/9/ip/rudp.c:603,627 – 1998/1230/sys/src/9/ip/rudp.c:603,636 | ||
| 1998/0728 | qunlock(ucb); | |
| 1998/0630 | } | |
| 1998/1230 | static char *rudpunknown = "unknown rudp ctl request"; | |
| 1998/0630 | char* rudpctl(Conv *c, char **f, int n) { Rudpcb *ucb; | |
| 1998/1230 | int x; | |
| 1998/0630 | ucb = (Rudpcb*)c->ptcl; | |
| 1998/1118 |
| |
| 1998/0630 |
| |
| 1998/1230 | if(n < 1) return rudpunknown; if(strcmp(f[0], "headers4") == 0){ ucb->headers = 4; return nil; } else if(strcmp(f[0], "headers") == 0){ ucb->headers = 6; return nil; } else if(strcmp(f[0], "randdrop") == 0){ x = 10; /* default is 10% */ if(n > 1) x = atoi(f[1]); if(x > 100 || x < 0) return "illegal rudp drop rate"; ucb->randdrop = x; return nil; | |
| 1998/0630 | } | |
| 1998/1230 | return rudpunknown; | |
| 1998/0630 | } void | |
| 1998/1230/sys/src/9/ip/rudp.c:289,295 – 1999/0302/sys/src/9/ip/rudp.c:289,295 (short | long) | ||
| 1998/0630 | ||
| 1998/0728 | qunlock(ucb); | |
| 1998/0630 |
| |
| 1999/0302 | qunlock(c); | |
| 1998/0630 | } | |
| 1998/1118 | /* | |
| 1998/1230/sys/src/9/ip/rudp.c:490,495 – 1999/0302/sys/src/9/ip/rudp.c:490,497 | ||
| 1998/0630 | } } | |
| 1999/0302 | qlock(rudp); | |
| 1998/0630 | /* Look for a conversation structure for this port */ c = nil; for(p = rudp->conv; *p; p++) { | |
| 1998/1230/sys/src/9/ip/rudp.c:512,517 – 1999/0302/sys/src/9/ip/rudp.c:514,520 | ||
| 1998/0630 | } if(*p == nil) { | |
| 1999/0302 | qunlock(rudp); | |
| 1998/0630 | upriv->ustats.rudpNoPorts++; netlog(f, Logrudp, "rudp: no conv %I!%d -> %I!%d\n", raddr, rport, laddr, lport); | |
| 1998/1230/sys/src/9/ip/rudp.c:525,532 – 1999/0302/sys/src/9/ip/rudp.c:528,536 | ||
| 1998/0630 | } ucb = (Rudpcb*)c->ptcl; | |
| 1998/0728 | qlock(ucb); | |
| 1999/0302 | qunlock(rudp); | |
| 1998/0728 | if(reliput(c, bp, raddr, rport) < 0){ qunlock(ucb); freeb(bp); | |
| 1999/0302/sys/src/9/ip/rudp.c:308,315 – 1999/0320/sys/src/9/ip/rudp.c:308,317 (short | long) | ||
| 1998/1118 | } | |
| 1998/0801 | int | |
| 1999/0320 | flow(void *v) | |
| 1998/0801 | { | |
| 1999/0320 | Reliable *r = v; | |
| 1998/0801 | return UNACKED(r) <= Maxunacked; } | |
| 1999/0320/sys/src/9/ip/rudp.c:296,302 – 1999/0817/sys/src/9/ip/rudp.c:296,302 (short | long) | ||
| 1998/1118 | * randomly don't send packets */ static void | |
| 1999/0817 | doipoput(Conv *c, Fs *f, Block *bp, int x, int ttl, int tos) | |
| 1998/1118 | { Rudpcb *ucb; | |
| 1999/0320/sys/src/9/ip/rudp.c:304,310 – 1999/0817/sys/src/9/ip/rudp.c:304,310 | ||
| 1998/1230 | if(ucb->randdrop && nrand(100) < ucb->randdrop) | |
| 1998/1118 | freeblist(bp); else | |
| 1999/0817 | ipoput(f, bp, x, ttl, tos); | |
| 1998/1118 | } | |
| 1998/0801 | int | |
| 1999/0320/sys/src/9/ip/rudp.c:436,442 – 1999/0817/sys/src/9/ip/rudp.c:436,442 | ||
| 1998/0825 | DPRINT("sent: %lud/%lud, %lud/%lud\n", r->sndseq, r->sndgen, r->rcvseq, r->rcvgen); | |
| 1998/0630 | ||
| 1998/1118 |
| |
| 1999/0817 | doipoput(c, f, bp, 0, c->ttl, c->tos); | |
| 1998/0801 | /* flow control of sorts */ qlock(&r->lock); | |
| 1999/0320/sys/src/9/ip/rudp.c:952,958 – 1999/0817/sys/src/9/ip/rudp.c:952,958 | ||
| 1998/0728 | hnputs(uh->udpcksum, ptclcsum(bp, UDP_IPHDR, UDP_RHDRSIZE)); | |
| 1998/0630 | ||
| 1998/0825 | DPRINT("sendack: %lud/%lud, %lud/%lud\n", 0L, r->sndgen, r->rcvseq, r->rcvgen); | |
| 1998/1118 |
| |
| 1999/0817 | doipoput(c, f, bp, 0, c->ttl, c->tos); | |
| 1998/0630 | } /* | |
| 1999/0320/sys/src/9/ip/rudp.c:1009,1013 – 1999/0817/sys/src/9/ip/rudp.c:1009,1013 | ||
| 1998/0726 | upriv->rxmits++; | |
| 1998/0630 | np = copyblock(r->unacked, blocklen(r->unacked)); | |
| 1998/0825 | DPRINT("rxmit r->ackrvcd+1 = %lud\n", r->ackrcvd+1); | |
| 1998/1118 |
| |
| 1999/0817 | doipoput(c, f, np, 0, c->ttl, c->tos); | |
| 1998/0630 | } | |
| 1999/0817/sys/src/9/ip/rudp.c:37,44 – 2000/0317/sys/src/9/ip/rudp.c:37,47 (short | long) | ||
| 1998/1117 | Rudptickms = 50, | |
| 1998/0726 | Rudpmaxxmit = 10, | |
| 1998/0801 | Maxunacked = 100, | |
| 2000/0317 | ||
| 1998/0630 | }; | |
| 2000/0317 | #define Hangupgen 0xffffffff /* used only in hangup messages */ | |
| 1998/0728 | typedef struct Udphdr Udphdr; struct Udphdr | |
| 1998/0630 | { | |
| 1999/0817/sys/src/9/ip/rudp.c:100,105 – 2000/0317/sys/src/9/ip/rudp.c:103,110 | ||
| 1998/0630 | typedef struct Reliable Reliable; struct Reliable { | |
| 2000/0317 | Ref; | |
| 1998/0630 | Reliable *next; | |
| 1998/0801 | uchar addr[IPaddrlen]; /* always V6 when put here */ | |
| 1999/0817/sys/src/9/ip/rudp.c:121,127 – 2000/0317/sys/src/9/ip/rudp.c:126,131 | ||
| 1998/0630 | ulong ackrcvd; /* last msg for which ack was rcvd */ | |
| 1998/0801 | /* flow control */ | |
| 1998/0630 | }; | |
| 1999/0817/sys/src/9/ip/rudp.c:176,184 – 2000/0317/sys/src/9/ip/rudp.c:180,190 | ||
| 1998/0630 | /* * local functions */ | |
| 1998/0728 |
| |
| 2000/0317 | void relsendack(Conv *, Reliable *, int); | |
| 1998/0728 | int reliput(Conv *, Block *, uchar *, ushort); Reliable *relstate(Rudpcb *, uchar *, ushort, char *from); | |
| 2000/0317 | void relput(Reliable *); void relforget(Conv *, uchar *, int, int); | |
| 1998/0728 | void relackproc(void *); void relackq(Reliable *, Block *); void relhangup(Conv *, Reliable *); | |
| 1999/0817/sys/src/9/ip/rudp.c:263,269 – 2000/0317/sys/src/9/ip/rudp.c:269,275 | ||
| 1998/1118 | qlock(ucb); for(r = ucb->r; r; r = r->next){ if(r->acksent != r->rcvseq) | |
| 2000/0317 | relsendack(c, r, 0); | |
| 1998/1118 | } qunlock(ucb); | |
| 1999/0817/sys/src/9/ip/rudp.c:280,286 – 2000/0317/sys/src/9/ip/rudp.c:286,292 | ||
| 1998/0728 | qlock(ucb); for(r = ucb->r; r; r = nr){ | |
| 1998/1118 | if(r->acksent != r->rcvseq) | |
| 2000/0317 | relsendack(c, r, 0); | |
| 1998/0630 | nr = r->next; | |
| 1998/0728 | relhangup(c, r); free(r); | |
| 1999/0817/sys/src/9/ip/rudp.c:429,435 – 2000/0317/sys/src/9/ip/rudp.c:435,440 | ||
| 1998/0728 | hnputs(uh->udpcksum, ptclcsum(bp, UDP_IPHDR, dlen+UDP_RHDRSIZE)); | |
| 1998/0630 | ||
| 1998/0728 | relackq(r, bp); | |
| 1998/0630 | upriv->ustats.rudpOutDatagrams++; | |
| 1999/0817/sys/src/9/ip/rudp.c:439,451 – 2000/0317/sys/src/9/ip/rudp.c:444,456 | ||
| 1999/0817 | doipoput(c, f, bp, 0, c->ttl, c->tos); | |
| 1998/0801 | /* flow control of sorts */ | |
| 2000/0317 | relput(r); qunlock(ucb); | |
| 1998/0630 | } void | |
| 1999/0817/sys/src/9/ip/rudp.c:615,620 – 2000/0317/sys/src/9/ip/rudp.c:620,626 | ||
| 1998/0630 | rudpctl(Conv *c, char **f, int n) { Rudpcb *ucb; | |
| 2000/0317 | uchar ip[IPaddrlen]; | |
| 1998/1230 | int x; | |
| 1998/0630 | ucb = (Rudpcb*)c->ptcl; | |
| 1999/0817/sys/src/9/ip/rudp.c:627,632 – 2000/0317/sys/src/9/ip/rudp.c:633,647 | ||
| 1998/1230 | } else if(strcmp(f[0], "headers") == 0){ ucb->headers = 6; return nil; | |
| 2000/0317 | } else if(strcmp(f[0], "hangup") == 0){ if(n < 3) return "bad syntax"; parseip(ip, f[1]); x = atoi(f[2]); qlock(ucb); relforget(c, ip, x, 1); qunlock(ucb); return nil; | |
| 1998/1230 | } else if(strcmp(f[0], "randdrop") == 0){ x = 10; /* default is 10% */ if(n > 1) | |
| 1999/0817/sys/src/9/ip/rudp.c:764,770 – 2000/0317/sys/src/9/ip/rudp.c:779,785 | ||
| 1998/0630 | relrexmit(c, r); } | |
| 1998/0801 | if(r->acksent != r->rcvseq) | |
| 1998/0630 |
| |
| 2000/0317 | relsendack(c, r, 0); | |
| 1998/0630 | } | |
| 1998/0726 | qunlock(ucb); | |
| 1998/0630 | } | |
| 1999/0817/sys/src/9/ip/rudp.c:798,803 – 2000/0317/sys/src/9/ip/rudp.c:813,820 | ||
| 1998/0728 | memmove(r->addr, addr, IPaddrlen); | |
| 1998/0630 | r->port = port; r->unacked = 0; | |
| 2000/0317 | if(generation == Hangupgen) generation++; | |
| 1998/0630 | r->sndgen = generation++; r->sndseq = 0; r->ackrcvd = 0; | |
| 1999/0817/sys/src/9/ip/rudp.c:806,817 – 2000/0317/sys/src/9/ip/rudp.c:823,864 | ||
| 1998/0630 | r->acksent = 0; r->xmits = 0; r->timeout = 0; | |
| 2000/0317 | r->ref = 0; incref(r); /* one reference for being in the list */ | |
| 1998/0630 | } | |
| 2000/0317 | incref(r); | |
| 1998/0630 | return r; } | |
| 2000/0317 | void relput(Reliable *r) { if(decref(r) == 0) free(r); } | |
| 1998/0630 | ||
| 2000/0317 | void relforget(Conv *c, uchar *ip, int port, int originator) { Rudpcb *ucb; Reliable *r, **l; ucb = (Rudpcb*)c->ptcl; l = &ucb->r; for(r = *l; r; r = *l){ if(ipcmp(ip, r->addr) == 0 && port == r->port){ *l = r->next; if(originator) relsendack(c, r, 1); relhangup(c, r); relput(r); /* remove from the list */ break; } l = &r->next; } } | |
| 1998/0630 | /* * process a rcvd reliable packet. return -1 if not to be passed to user process, * 0 therwise. | |
| 1999/0817/sys/src/9/ip/rudp.c:826,831 – 2000/0317/sys/src/9/ip/rudp.c:873,879 | ||
| 1998/0630 | Reliable *r; | |
| 1998/0728 | Rudphdr *rh; | |
| 1998/0630 | ulong seq, ack, sgen, agen, ackreal; | |
| 2000/0317 | int rv = -1; | |
| 1998/0630 | /* get fields */ | |
| 1998/0728 | uh = (Udphdr*)(bp->rp); | |
| 1999/0817/sys/src/9/ip/rudp.c:837,844 – 2000/0317/sys/src/9/ip/rudp.c:885,892 | ||
| 1998/0630 | ||
| 1998/0726 | upriv = c->p->priv; | |
| 1998/0630 | ucb = (Rudpcb*)c->ptcl; | |
| 2000/0317 | qlock(ucb); | |
| 1998/0728 | r = relstate(ucb, addr, port, "input"); | |
| 1998/0630 | ||
| 1998/0825 | DPRINT("rcvd %lud/%lud, %lud/%lud, r->sndgen = %lud\n", | |
| 1998/0726 | seq, sgen, ack, agen, r->sndgen); | |
| 1999/0817/sys/src/9/ip/rudp.c:845,856 – 2000/0317/sys/src/9/ip/rudp.c:893,911 | ||
| 1998/0630 | ||
| 1998/1124 | /* if acking an incorrect generation, ignore */ if(ack && agen != r->sndgen) | |
| 2000/0317 | goto out; | |
| 1998/1124 | ||
| 2000/0317 | /* Look for a hangup */ if(sgen == Hangupgen) { if(agen == r->sndgen) relforget(c, addr, port, 0); goto out; } | |
| 1998/1118 | /* make sure we're not talking to a new remote side */ if(r->rcvgen != sgen){ | |
| 1998/1127 | if(seq != 0 && seq != 1) | |
| 1998/1118 |
| |
| 2000/0317 | goto out; | |
| 1998/1118 | /* new connection */ if(r->rcvgen != 0){ | |
| 1999/0817/sys/src/9/ip/rudp.c:893,914 – 2000/0317/sys/src/9/ip/rudp.c:948,973 | ||
| 1998/0630 | ||
| 1998/0801 | /* no message or input queue full */ if(seq == 0 || qfull(c->rq)) | |
| 1998/0630 |
| |
| 2000/0317 | goto out; | |
| 1998/0630 | /* refuse out of order delivery */ | |
| 1998/0801 | if(seq != NEXTSEQ(r->rcvseq)){ | |
| 1998/1117 |
| |
| 2000/0317 | relsendack(c, r, 0); /* tell him we got it already */ | |
| 1998/0726 | upriv->orders++; | |
| 1998/0825 | DPRINT("out of sequence %lud not %lud\n", seq, NEXTSEQ(r->rcvseq)); | |
| 1998/0630 |
| |
| 2000/0317 | goto out; | |
| 1998/0630 | } r->rcvseq = seq; | |
| 2000/0317 | rv = 0; out: relput(r); qunlock(ucb); return rv; | |
| 1998/0630 | } void | |
| 2000/0317 | relsendack(Conv *c, Reliable *r, int hangup) | |
| 1998/0630 | { | |
| 1998/0728 | Udphdr *uh; | |
| 1998/0630 | Block *bp; | |
| 1999/0817/sys/src/9/ip/rudp.c:939,945 – 2000/0317/sys/src/9/ip/rudp.c:998,1007 | ||
| 1998/0728 | v6tov4(uh->udpsrc, c->laddr); hnputs(uh->udplen, ptcllen); | |
| 1998/0630 |
| |
| 2000/0317 | if(hangup) hnputl(rh->relsgen, Hangupgen); else hnputl(rh->relsgen, r->sndgen); | |
| 1998/0630 | hnputl(rh->relseq, 0); hnputl(rh->relagen, r->rcvgen); hnputl(rh->relack, r->rcvseq); | |
| 1999/0817/sys/src/9/ip/rudp.c:955,960 – 2000/0317/sys/src/9/ip/rudp.c:1017,1023 | ||
| 1999/0817 | doipoput(c, f, bp, 0, c->ttl, c->tos); | |
| 1998/0630 | } | |
| 2000/0317 | ||
| 1998/0630 | /* * called with ucb locked (and c locked if user initiated close) */ | |
| 1999/0817/sys/src/9/ip/rudp.c:980,985 – 2000/0317/sys/src/9/ip/rudp.c:1043,1050 | ||
| 1998/0630 | r->rcvgen = 0; r->rcvseq = 0; r->acksent = 0; | |
| 2000/0317 | if(generation == Hangupgen) generation++; | |
| 1998/0630 | r->sndgen = generation++; r->sndseq = 0; r->ackrcvd = 0; | |
| 2000/0317/sys/src/9/ip/rudp.c:126,131 – 2000/0328/sys/src/9/ip/rudp.c:126,132 (short | long) | ||
| 1998/0630 | ulong ackrcvd; /* last msg for which ack was rcvd */ | |
| 1998/0801 | /* flow control */ | |
| 2000/0328 | QLock lock; | |
| 1998/0801 | Rendez vous; int blocked; | |
| 1998/0630 | }; | |
| 2000/0317/sys/src/9/ip/rudp.c:435,440 – 2000/0328/sys/src/9/ip/rudp.c:436,442 | ||
| 1998/0728 | hnputs(uh->udpcksum, ptclcsum(bp, UDP_IPHDR, dlen+UDP_RHDRSIZE)); | |
| 1998/0630 | ||
| 1998/0728 | relackq(r, bp); | |
| 2000/0328 | qunlock(ucb); | |
| 1998/0630 | upriv->ustats.rudpOutDatagrams++; | |
| 2000/0317/sys/src/9/ip/rudp.c:444,456 – 2000/0328/sys/src/9/ip/rudp.c:446,459 | ||
| 1999/0817 | doipoput(c, f, bp, 0, c->ttl, c->tos); | |
| 1998/0801 | /* flow control of sorts */ | |
| 2000/0328 | qlock(&r->lock); | |
| 1998/0801 | if(UNACKED(r) > Maxunacked){ r->blocked = 1; sleep(&r->vous, flow, r); r->blocked = 0; } | |
| 2000/0328 | qunlock(&r->lock); | |
| 2000/0317 | relput(r); | |
| 1998/0630 | } void | |
| 2000/0328/sys/src/9/ip/rudp.c:290,296 – 2000/0403/sys/src/9/ip/rudp.c:290,296 (short | long) | ||
| 2000/0317 | relsendack(c, r, 0); | |
| 1998/0630 | nr = r->next; | |
| 1998/0728 | relhangup(c, r); | |
| 2000/0403 | relput(r); | |
| 1998/0630 | } ucb->r = 0; | |
| 2000/0328/sys/src/9/ip/rudp.c:453,458 – 2000/0403/sys/src/9/ip/rudp.c:453,459 | ||
| 1998/0801 | r->blocked = 0; } | |
| 2000/0328 | qunlock(&r->lock); | |
| 2000/0403 | ||
| 2000/0317 | relput(r); | |
| 1998/0630 | } | |
| 2000/0328/sys/src/9/ip/rudp.c:811,818 – 2000/0403/sys/src/9/ip/rudp.c:812,819 | ||
| 1998/0731 | generation = rand(); | |
| 1998/0825 | DPRINT("from %s new state %lud for %I!%ud\n", | |
| 1998/0728 | from, generation, addr, port); | |
| 2000/0403 | ||
| 1998/0728 | r = smalloc(sizeof(Reliable)); | |
| 1998/0630 |
| |
| 1998/0728 | memmove(r->addr, addr, IPaddrlen); | |
| 1998/0630 | r->port = port; r->unacked = 0; | |
| 2000/0328/sys/src/9/ip/rudp.c:828,833 – 2000/0403/sys/src/9/ip/rudp.c:829,836 | ||
| 1998/0630 | r->timeout = 0; | |
| 2000/0317 | r->ref = 0; incref(r); /* one reference for being in the list */ | |
| 2000/0403 | *l = r; | |
| 1998/0630 | } | |
| 2000/0317 | incref(r); | |
| 1998/0630 | return r; | |
| 2000/0328/sys/src/9/ip/rudp.c:840,845 – 2000/0403/sys/src/9/ip/rudp.c:843,851 | ||
| 2000/0317 | free(r); } | |
| 1998/0630 | ||
| 2000/0403 | /* * forget a Reliable state */ | |
| 2000/0317 | void relforget(Conv *c, uchar *ip, int port, int originator) { | |
| 2000/0328/sys/src/9/ip/rudp.c:865,870 – 2000/0403/sys/src/9/ip/rudp.c:871,878 | ||
| 1998/0630 | /* * process a rcvd reliable packet. return -1 if not to be passed to user process, * 0 therwise. | |
| 2000/0403 | * * called with ucb locked. | |
| 1998/0630 | */ int reliput(Conv *c, Block *bp, uchar *addr, ushort port) | |
| 2000/0328/sys/src/9/ip/rudp.c:888,894 – 2000/0403/sys/src/9/ip/rudp.c:896,901 | ||
| 1998/0630 | ||
| 1998/0726 | upriv = c->p->priv; | |
| 1998/0630 | ucb = (Rudpcb*)c->ptcl; | |
| 2000/0317 |
| |
| 1998/0728 | r = relstate(ucb, addr, port, "input"); | |
| 1998/0630 | ||
| 1998/0825 | DPRINT("rcvd %lud/%lud, %lud/%lud, r->sndgen = %lud\n", | |
| 2000/0328/sys/src/9/ip/rudp.c:965,971 – 2000/0403/sys/src/9/ip/rudp.c:972,977 | ||
| 2000/0317 | rv = 0; out: relput(r); | |
| 1998/0630 | } | |
| 2000/0403/sys/src/9/ip/rudp.c:181,195 – 2000/0605/sys/src/9/ip/rudp.c:181,196 (short | long) | ||
| 1998/0630 | /* * local functions */ | |
| 2000/0317 |
| |
| 1998/0728 |
| |
| 2000/0317 |
| |
| 2000/0605 | 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); | |
| 1998/0728 | void relackproc(void *); | |
| 2000/0605 | void relackq(Reliable *, Block*); void relhangup(Conv *, Reliable*); void relrexmit(Conv *, Reliable*); void relput(Reliable*); | |
| 1998/0630 | ||
| 1998/0924 | static void rudpstartackproc(Proto *rudp) | |
| 2000/0403/sys/src/9/ip/rudp.c:295,301 – 2000/0605/sys/src/9/ip/rudp.c:296,301 | ||
| 1998/0630 | ucb->r = 0; | |
| 1998/0728 | qunlock(ucb); | |
| 1998/0630 | ||
| 1999/0302 | qunlock(c); | |
| 1998/0630 | } | |
| 2000/0403/sys/src/9/ip/rudp.c:445,450 – 2000/0605/sys/src/9/ip/rudp.c:445,456 | ||
| 1998/0630 | ||
| 1999/0817 | doipoput(c, f, bp, 0, c->ttl, c->tos); | |
| 1998/0801 | ||
| 2000/0605 | if(waserror()) { relput(r); qunlock(&r->lock); nexterror(); } | |
| 1998/0801 | /* flow control of sorts */ | |
| 2000/0328 | qlock(&r->lock); | |
| 1998/0801 | if(UNACKED(r) > Maxunacked){ | |
| 2000/0403/sys/src/9/ip/rudp.c:452,460 – 2000/0605/sys/src/9/ip/rudp.c:458,467 | ||
| 1998/0801 | sleep(&r->vous, flow, r); r->blocked = 0; } | |
| 2000/0328 |
| |
| 2000/0403 | ||
| 2000/0605 | qunlock(&r->lock); | |
| 2000/0317 | relput(r); | |
| 2000/0605 | poperror(); | |
| 1998/0630 | } void | |
| 2000/0403/sys/src/9/ip/rudp.c:554,560 – 2000/0605/sys/src/9/ip/rudp.c:561,567 | ||
| 1998/0630 | ||
| 1998/0728 | len -= (UDP_RHDRSIZE-UDP_PHDRSIZE); bp = trimblock(bp, UDP_IPHDR+UDP_RHDRSIZE, len); | |
| 1998/0630 |
| |
| 2000/0605 | if(bp == nil) { | |
| 1998/0630 | netlog(f, Logrudp, "rudp: len err %I.%d -> %I.%d\n", raddr, rport, laddr, lport); | |
| 1998/0728 | DPRINT("rudp: len err %I.%d -> %I.%d\n", | |
| 2000/0403/sys/src/9/ip/rudp.c:607,613 – 2000/0605/sys/src/9/ip/rudp.c:614,620 | ||
| 1998/0630 | if(bp->next) bp = concatblock(bp); | |
| 2000/0605 | if(qfull(c->rq)) { | |
| 1998/0630 | netlog(f, Logrudp, "rudp: qfull %I.%d -> %I.%d\n", raddr, rport, laddr, lport); freeblist(bp); | |
| 2000/0403/sys/src/9/ip/rudp.c:810,815 – 2000/0605/sys/src/9/ip/rudp.c:817,823 | ||
| 1998/0630 | if(r == nil){ | |
| 1998/1127 | while(generation == 0) | |
| 1998/0731 | generation = rand(); | |
| 2000/0605 | ||
| 1998/0825 | DPRINT("from %s new state %lud for %I!%ud\n", | |
| 1998/0728 | from, generation, addr, port); | |
| 2000/0403 | ||
| 2000/0403/sys/src/9/ip/rudp.c:832,837 – 2000/0605/sys/src/9/ip/rudp.c:840,846 | ||
| 2000/0403 | *l = r; | |
| 1998/0630 | } | |
| 2000/0605 | ||
| 2000/0317 | incref(r); | |
| 1998/0630 | return r; } | |
| 2000/0605/sys/src/9/ip/rudp.c:296,302 – 2000/1220/sys/src/9/ip/rudp.c:296,301 (short | long) | ||
| 1998/0630 | ucb->r = 0; | |
| 1998/0728 | qunlock(ucb); | |
| 1999/0302 |
| |
| 1998/0630 | } | |
| 1998/1118 | /* | |
| 2000/1220/sys/src/9/ip/rudp.c:147,152 – 2001/0301/sys/src/9/ip/rudp.c:147,153 (short | long) | ||
| 1998/0630 | struct Rudppriv { | |
| 1998/0726 | Rendez vous; | |
| 2001/0301 | Ipht ht; | |
| 1998/0630 | /* MIB counters */ Rudpstats ustats; | |
| 2000/1220/sys/src/9/ip/rudp.c:214,223 – 2001/0301/sys/src/9/ip/rudp.c:215,227 | ||
| 1998/0630 | rudpconnect(Conv *c, char **argv, int argc) { char *e; | |
| 2001/0301 | Rudppriv *upriv; | |
| 1998/0630 | ||
| 2001/0301 | upriv = c->p->priv; | |
| 1998/0924 | rudpstartackproc(c->p); | |
| 1998/0630 | e = Fsstdconnect(c, argv, argc); Fsconnected(c, e); | |
| 2001/0301 | iphtadd(&upriv->ht, c); | |
| 1998/0630 | return e; } | |
| 2000/1220/sys/src/9/ip/rudp.c:243,254 – 2001/0301/sys/src/9/ip/rudp.c:247,261 | ||
| 1998/0630 | rudpannounce(Conv *c, char** argv, int argc) { char *e; | |
| 2001/0301 | Rudppriv *upriv; | |
| 1998/0630 | ||
| 2001/0301 | upriv = c->p->priv; | |
| 1998/0924 | rudpstartackproc(c->p); | |
| 1998/0630 | e = Fsstdannounce(c, argv, argc); if(e != nil) return e; Fsconnected(c, nil); | |
| 2001/0301 | iphtadd(&upriv->ht, c); | |
| 1998/0630 | return nil; } | |
| 2000/1220/sys/src/9/ip/rudp.c:265,271 – 2001/0301/sys/src/9/ip/rudp.c:272,282 | ||
| 1998/0630 | { Rudpcb *ucb; Reliable *r, *nr; | |
| 2001/0301 | Rudppriv *upriv; | |
| 1998/0630 | ||
| 2001/0301 | upriv = c->p->priv; iphtrem(&upriv->ht, c); | |
| 1998/1118 | /* force out any delayed acks */ ucb = (Rudpcb*)c->ptcl; qlock(ucb); | |
| 2000/1220/sys/src/9/ip/rudp.c:468,474 – 2001/0301/sys/src/9/ip/rudp.c:479,485 | ||
| 1998/0630 | { int len, olen, ottl; | |
| 1998/0728 | Udphdr *uh; | |
| 1998/0630 |
| |
| 2001/0301 | Conv *c; | |
| 1998/0630 | Rudpcb *ucb; uchar raddr[IPaddrlen], laddr[IPaddrlen]; ushort rport, lport; | |
| 2000/1220/sys/src/9/ip/rudp.c:509,542 – 2001/0301/sys/src/9/ip/rudp.c:520,532 | ||
| 1998/0630 | ||
| 1999/0302 | qlock(rudp); | |
| 1998/0630 |
| |
| 1998/0728 |
| |
| 1998/0630 |
| |
| 1999/0302 |
| |
| 2001/0301 | c = iphtlook(&upriv->ht, raddr, rport, laddr, lport); if(c == nil){ /* no converstation found */ | |
| 1998/0630 | upriv->ustats.rudpNoPorts++; | |
| 2001/0301 | qunlock(rudp); netlog(f, Logudp, "udp: no conv %I!%d -> %I!%d\n", raddr, rport, | |
| 1998/0630 | laddr, lport); | |
| 1998/0728 |
| |
| 1998/0630 |
| |
| 1998/0728 | hnputs(uh->udpplen, olen); | |
| 1998/0630 | icmpnoconv(f, bp); | |
| 2000/1220/sys/src/9/ip/rudp.c:543,549 – 2001/0301/sys/src/9/ip/rudp.c:533,538 | ||
| 1998/0630 | freeblist(bp); return; } | |
| 1998/0728 | qlock(ucb); | |
| 1999/0302 | qunlock(rudp); | |
| 2001/0301/sys/src/9/ip/rudp.c:333,339 – 2001/0306/sys/src/9/ip/rudp.c:333,339 (short | long) | ||
| 1998/0801 | } | |
| 1998/0630 | void | |
| 2001/0306 | rudpkick(Conv *c) | |
| 1998/0630 | { | |
| 1998/0728 | Udphdr *uh; | |
| 1998/0630 | ushort rport; | |
| 2001/0306/sys/src/9/ip/rudp.c:475,481 – 2001/0623/sys/src/9/ip/rudp.c:475,481 (short | long) | ||
| 1998/0630 | } void | |
| 2001/0623 | rudpiput(Proto *rudp, Ipifc *ifc, Block *bp) | |
| 1998/0630 | { int len, olen, ottl; | |
| 1998/0728 | Udphdr *uh; | |
| 2001/0306/sys/src/9/ip/rudp.c:569,575 – 2001/0623/sys/src/9/ip/rudp.c:569,575 | ||
| 1998/0630 | if(ipforme(f, laddr) == Runi) ipmove(bp->rp+IPaddrlen, laddr); else | |
| 2001/0623 | ipmove(bp->rp+IPaddrlen, ifc->lifc->local); | |
| 1998/0630 | hnputs(bp->rp+2*IPaddrlen, rport); hnputs(bp->rp+2*IPaddrlen+2, lport); break; | |
| 2001/0306/sys/src/9/ip/rudp.c:580,586 – 2001/0623/sys/src/9/ip/rudp.c:580,586 | ||
| 1998/0630 | if(ipforme(f, laddr) == Runi) v6tov4(bp->rp+IPv4addrlen, laddr); else | |
| 2001/0623 | v6tov4(bp->rp+IPv4addrlen, ifc->lifc->local); | |
| 1998/0630 | hnputs(bp->rp + 2*IPv4addrlen, rport); hnputs(bp->rp + 2*IPv4addrlen + 2, lport); break; | |
| 2001/0306/sys/src/9/ip/rudp.c:595,601 – 2001/0623/sys/src/9/ip/rudp.c:595,601 | ||
| 1998/0630 | if(ipforme(f, laddr) == Runi) ipmove(c->laddr, laddr); else | |
| 2001/0623 | v4tov6(c->laddr, ifc->lifc->local); | |
| 1998/0630 | } break; } | |
| 2001/0623/sys/src/9/ip/rudp.c:197,203 – 2001/0918/sys/src/9/ip/rudp.c:197,203 (short | long) | ||
| 1998/0924 | rudpstartackproc(Proto *rudp) { Rudppriv *rpriv; | |
| 2001/0918 | char kpname[KNAMELEN]; | |
| 1998/0924 | rpriv = rudp->priv; if(rpriv->ackprocstarted == 0){ | |
| 2001/0623/sys/src/9/ip/rudp.c:1032,1038 – 2001/0918/sys/src/9/ip/rudp.c:1032,1038 | ||
| 1998/0630 | { | |
| 1998/1118 | int n; | |
| 1998/0630 | Block *bp; | |
| 1998/1118 |
| |
| 2001/0918 | char hup[ERRMAX]; | |
| 1998/0630 | ||
| 1998/1118 | n = snprint(hup, sizeof(hup), "hangup %I!%d", r->addr, r->port); qproduce(c->eq, hup, n); | |
| 2001/0918/sys/src/9/ip/rudp.c:321,327 – 2002/0507/sys/src/9/ip/rudp.c:321,327 (short | long) | ||
| 1998/1230 | if(ucb->randdrop && nrand(100) < ucb->randdrop) | |
| 1998/1118 | freeblist(bp); else | |
| 1999/0817 |
| |
| 2002/0507 | ipoput4(f, bp, x, ttl, tos); | |
| 1998/1118 | } | |
| 1998/0801 | int | |
| 2001/0918/sys/src/9/ip/rudp.c:402,407 – 2002/0507/sys/src/9/ip/rudp.c:402,408 | ||
| 1998/0630 | return; | |
| 1998/0728 | uh = (Udphdr *)(bp->rp); | |
| 2002/0507 | uh->vihl = IP_VER4; | |
| 1998/0630 | ||
| 1998/0728 | rh = (Rudphdr*)uh; | |
| 1998/0630 | ||
| 2001/0918/sys/src/9/ip/rudp.c:987,992 – 2002/0507/sys/src/9/ip/rudp.c:988,994 | ||
| 1998/0728 | bp->wp += UDP_IPHDR + UDP_RHDRSIZE; | |
| 1998/0630 | f = c->p->f; | |
| 1998/0728 | uh = (Udphdr *)(bp->rp); | |
| 2002/0507 | uh->vihl = IP_VER4; | |
| 1998/0728 | rh = (Rudphdr*)uh; | |
| 1998/0630 | ||
| 1998/0728 | ptcllen = (UDP_RHDRSIZE-UDP_PHDRSIZE); | |
| 2002/0507/sys/src/9/ip/rudp.c:263,269 – 2002/0711/sys/src/9/ip/rudp.c:263,269 (short | long) | ||
| 1998/0630 | static void rudpcreate(Conv *c) { | |
| 2002/0711 | c->rq = qopen(64*1024, Qmsg, 0, 0); | |
| 1998/0630 | c->wq = qopen(64*1024, 0, 0, 0); } | |
| Too many diffs (26 > 25). Stopping. | ||