* Revision 2.7 84/11/21 12:06:30 walsh
* *** empty log message ***
* Revision 2.6 84/11/08 16:12:53 walsh
* Added code to gather statistics on RDP traffic. This makes the RDPCB
* too big unles you make mbufs 512 bytes large. RDP_CS should be turned off
* Revision 2.5 84/11/06 13:54:21 walsh
* *** empty log message ***
* Revision 2.4 84/11/05 16:25:18 walsh
* tied rdp to icmp source quenches. See icmp_quench and rdp_quench.
* Revision 2.3 84/11/05 15:55:13 walsh
* update_nulltimer() macro began to look inappropriate with recent
* changes, so its been stripped out and put in-line.
* Revision 2.2 84/11/02 18:25:47 walsh
* Protocol specifiers want NULL message to have own sequence number in
* case of slow (t>NULL msg timeout) packets. I don't see this as a problem,
* and even if happened (dubious) would only delay discovery, but I
* didn't win this one. Initially not designed for this, but fixes are
* Revision 2.1 84/11/02 10:15:35 walsh
* Fixed to include RCS comments in checked out source.
* Some subroutines for manipulating the datagram q's for RDP.
* date: 84/07/20 10:30:42; author: walsh; state: Exp; lines added/del: 21/1
* Tied RDP acknowledgements to ping reduction, just like TCP.
* date: 84/07/19 10:22:33; author: walsh; state: Exp; lines added/del: 1/17
* Organized macros and classified their definitions in rdp_macros.h.
* date: 84/07/17 22:35:26; author: walsh; state: Exp; lines added/del: 3/0
* Ensure cannot bind port number greater than RDP_pMAX.
* date: 84/07/12 10:12:48; author: walsh; state: Exp; lines added/del: 14/18
* some small optimizations.
* date: 84/07/12 09:39:06; author: walsh; state: Exp; lines added/del: 2/4
* small optimizations. ( a = (a+1)%b quicker than a++; a %= b)
* date: 84/07/10 14:58:24; author: walsh; state: Exp; lines added/del: 10/3
* Now no unecessary wakeups of the user process are done.
* date: 84/07/10 10:38:24; author: walsh; state: Exp; lines added/del: 13/13
* added register declarations.
* date: 84/07/06 14:28:53; author: wjacobso; state: Exp; lines added/del: 6/6
* *** empty log message ***
* date: 84/07/06 14:17:02; author: wjacobso; state: Exp; lines added/del: 8/8
* added register var definitions
* date: 84/07/06 09:51:12; author: root; state: Exp; lines added/del: 2/1
* This version seems to run bug-free.
* date: 84/06/26 14:18:30; author: walsh; state: Exp;
#include "../h/socketvar.h"
#include "../net/route.h"
#include "../bbnnet/in.h"
#include "../bbnnet/net.h"
#include "../bbnnet/in_pcb.h"
#include "../bbnnet/in_var.h"
#include "../bbnnet/ip.h"
#include "../bbnnet/icmp.h"
#include "../bbnnet/rdp.h"
#include "../bbnnet/seq.h"
#include "../bbnnet/rdp_macros.h"
* Called on ACK of a message we sent.
index
= msgnum
- rdpcb
->r_sendq
.rq_baseseq
;
if (index
< 0 || index
>= rdpcb
->r_sendq
.rq_maxqlen
)
* an ACK is cumulative and may be for more than one message
j
= (rdpcb
->r_sendq
.rq_front
+ i
) % rdpcb
->r_sendq
.rq_maxqlen
;
m
= rdpcb
->r_sendq
.rq_msgs
[j
];
* ignore redundant ACKs. May have been EACKed (RDP_DELIVERED).
/* and restart connection loss detection */
rdpcb
->r_timers
[RDP_tNULL
] = rdpcb
->r_tvnull
;
else if (m
!= RDP_DELIVERED
)
/* count when acked, not queued */
rdpcb
->r_sent
.r_nbytes
+= (int) m
->m_act
;
rdpcb
->r_sendq
.rq_msgs
[j
] = NULL
;
clear_rxtimer (rdpcb
, j
);
* Ensure front is always NULL or an undelivered (unacked) message.
rdpcb
->r_sendq
.rq_front
+= (index
+1);
rdpcb
->r_sendq
.rq_front
%= rdpcb
->r_sendq
.rq_maxqlen
;
rdpcb
->r_sendq
.rq_baseseq
+= (index
+1); /* bumps r_snduna */
* and, did this ack allow us to measure current round trip time?
if (SEQ_GT(rdpcb
->r_sendq
.rq_baseseq
, rdpcb
->r_rttimed
))
update_rttestimate(rdpcb
);
rdpcb
->r_rttiming
= FALSE
;
* We've sent him NEW data, perhaps by a gateway, that he
* has successfully received. If that's the case, then
* we know the route works and we don't have to ping that
register struct rtentry
*rt
;
if (rt
= rdpcb
->r_inpcb
->inp_route
.ro_rt
)
if (rt
->rt_flags
& RTF_GATEWAY
)
* and let sender send more pkts now that we have space.
* Called on EACK of a message we sent.
index
= msgnum
- rdpcb
->r_sendq
.rq_baseseq
;
if (index
< 0 || index
>= rdpcb
->r_sendq
.rq_maxqlen
)
index
= (index
+ rdpcb
->r_sendq
.rq_front
) % rdpcb
->r_sendq
.rq_maxqlen
;
m
= rdpcb
->r_sendq
.rq_msgs
[index
];
if (m
&& (m
!= RDP_DELIVERED
))
/* and restart connection loss detection */
rdpcb
->r_timers
[RDP_tNULL
] = rdpcb
->r_tvnull
;
log(KERN_RECOV
, "Incorrect ACK strategy on rdpcb 0x%x\n", rdpcb
);
rdpcb
->r_sent
.r_nbytes
+= (int) m
->m_act
;
rdpcb
->r_sendq
.rq_msgs
[index
] = RDP_DELIVERED
;
clear_rxtimer(rdpcb
, index
);
* did this eack allow us to measure current round trip time?
if (msgnum
== rdpcb
->r_rttimed
)
update_rttestimate(rdpcb
);
rdpcb
->r_rttiming
= FALSE
;
* Grab a message for passing to the user. msgq is our rcvq.
* Called on net reception if user recv q is empty.
* Called on PRU_RECV after user picks up current packet on socket.
* Only one packet is attached to the socket at a time.
MBUF
*rdp_qremove(msgq
, async
)
m
= msgq
->rq_msgs
[index
];
if (m
&& m
!= RDP_DELIVERED
)
msgq
->rq_msgs
[index
] = RDP_DELIVERED
;
index
= (index
+1) % msgq
->rq_maxqlen
;
while (async
&& (--pass
> 0));
* rdp_qremove() grabbed a message to pass to the user. When he picks it up,
* PRU_RCVD occurs. At that point, we bump front and we send an ACK.
m
= msgq
->rq_msgs
[index
];
msgq
->rq_front
= (msgq
->rq_front
+1) % msgq
->rq_maxqlen
;
msgq
->rq_msgs
[index
] = NULL
;
while (m
== RDP_DELIVERED
);
* Put a message on our send or rcv q.
* 0 internal error somewhere
rdp_qinsert(msgq
, m
, msgnum
)
index
= msgnum
- msgq
->rq_baseseq
;
if ((index
< 0) || (index
>= msgq
->rq_maxqlen
))
index
= (index
+ msgq
->rq_front
) % msgq
->rq_maxqlen
;
if (msgq
->rq_msgs
[index
] == RDP_DELIVERED
)
/* rcvd duplicate of a message the user already has on socket */
if (msgq
->rq_msgs
[index
])
m_freem(msgq
->rq_msgs
[index
]);
msgq
->rq_msgs
[index
] = m
;