|
|
1.1 root 1: #include "ch.h"
2: #if NCH > 0
3: #include "../h/param.h"
4: #include "../h/systm.h"
5: #include "../h/chaos.h"
6: #include "../chaosld/types.h"
7: #include "../chaosld/constants.h"
8: #include "../chaosld/globals.h"
9:
10: /*
11: * Clock level processing.
12: * ch_timer should be called each clock tick (HZ per second)
13: * at a priority equal to or higher than LOCK.
14: *
15: * Terminology:
16: * Packet aging: Retransmitting packets that are not acked within
17: * AGERATE ticks
18: *
19: * Probe: The sending of a SNS packet if not all of the packets
20: * we have sent have been acknowledged
21: *
22: * Responding: Send a SNS every so often to see if the guy is still
23: * alive (after NRESPONDS we declare him dead)
24: *
25: * RFC aging: The retransmission of RFC packets
26: *
27: * These rates might want to vary with the cost of getting to the host.
28: *
29: * Since these rates are dependent on a run-time variable
30: * (This is a good idea if you think about it long enough),
31: * We might want to initialize specific variables at run-time to
32: * avoid recalculation if the profile of chclock is disturbing.
33: */
34: #define MINRATE ORATE /* Minimum of following rates */
35:
36: #define AGERATE (hz) /* Re-xmit pkt if not rcptd in time */
37: #define PROBERATE (hz<<3) /* Send SNS to get STS for receipts or
38: to make sure the conn. is alive */
39: #define ORATE (hz>>1) /* Xmit current (stream) output packet
40: if not touched in this time */
41: #define TESTRATE (hz*45) /* Respond testing rate */
42: #define NRESPONDS 3 /* Test this many times before timing
43: out the connection */
44: #define UPTIME (NRESPONDS*TESTRATE) /* Nothing in this time and
45: the connection is flushed */
46: #define RFCTIME (hz*15) /* Time before giving up on RFC */
47:
48: extern int NChopen;
49:
50:
51: ch_timer()
52: {
53: register struct connection *conn;
54: register struct connection **connp;
55: register struct packet *pkt;
56: chtime inactive;
57: int probing; /* are we probing this time ? */
58: static chtime nextclk = 1; /* next time to do anything */
59: static chtime nextprobe = 1; /* next time to probe */
60:
61: Chtimer = 1;
62: ++Chclock;
63: if (ch_busy)
64: goto leave;
65: if (cmp_le(Chclock, nextclk))
66: goto leave;
67: nextclk += MINRATE;
68: if (cmp_gt(Chclock, nextprobe)) {
69: probing = 1;
70: nextprobe += PROBERATE;
71: } else
72: probing = 0;
73: debug(DNOCLK,goto leave);
74:
75: for (connp = &Chconn[0]; connp < &Chconn[NCH]; connp++) {
76: if ((conn = *connp) == NOCONN ||
77: (conn->cn_state != CSOPEN && conn->cn_state != CSRFCSENT))
78: continue;
79: if ((pkt = conn->cn_toutput) != NOPKT &&
80: (inactive = Chclock - pkt->time) >= ORATE &&
81: !chtfull(conn)) {
82: conn->cn_toutput = NOPKT;
83: (void)chld_write(conn, pkt);
84: }
85: if (conn->cn_thead != NOPKT)
86: chretran(conn, AGERATE);
87: if (probing) {
88: inactive = Chclock - conn->cn_time;
89: if (inactive >= (conn->cn_state == CSOPEN ? UPTIME : RFCTIME)) {
90: debug(DCONN|DABNOR,
91: printf("Conn #%x: Timeout\n", conn->cn_lidx.ci_tidx));
92: close_conn(conn, CSINCT, NOPKT);
93: } else if (conn->cn_state == CSOPEN &&
94: (conn->cn_tacked != conn->cn_tlast ||
95: chtfull(conn) || inactive >= TESTRATE)) {
96: debug(DCONN, printf("Conn #%x: Probe: %D\n",
97: conn->cn_lidx.ci_tidx, inactive));
98: sendsns(conn);
99: }
100: }
101: }
102:
103: leave:
104: if (NChopen == 0)
105: Chtimer = 0;
106: else
107: timeout(ch_timer, (caddr_t)0, 1);
108: }
109:
110: chretran(conn, age)
111: struct connection *conn;
112: {
113: register struct packet *pkt, **opkt;
114: register struct packet *lastpkt;
115: register chtime inactive;
116: struct packet *firstpkt = NOPKT;
117:
118: ch_busy++;
119:
120: for (opkt = &conn->cn_thead; pkt = *opkt;) {
121: inactive = Chclock - pkt->time;
122: if (inactive >= age) {
123: if (firstpkt == NOPKT)
124: firstpkt = pkt;
125: else
126: lastpkt->next = pkt;
127: lastpkt = pkt;
128: *opkt = pkt->next;
129: pkt->next = NOPKT;
130: setack(conn, pkt);
131: } else
132: opkt = &pkt->next;
133: }
134:
135: --ch_busy;
136:
137: if (firstpkt != NOPKT) {
138: debug(DCONN|DABNOR,
139: printf("Conn #%x: Rexmit (op:%d, pkn:%d)\n",
140: conn->cn_lidx.ci_tidx, firstpkt->pk_op,
141: firstpkt->pk_pkn));
142: senddata(firstpkt);
143: }
144: }
145:
146: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.