|
|
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.