/* * Copyright (c) 1995, 1998 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * * Declarations and data structures used by the Berkeley Snoop protocol. */ #ifndef SNOOP_H #define SNOOP_H #include #include #include #include #include #include #include #ifndef NOMIP #include #endif #define SNOOP_MAXWIND 40 #define SNOOP_MAXBLKS 16 #define SNOOP_MAXMOBILE 32 #define SNOOP_MAXCONN 64 #define SNOOP_HIGH_THRESH (9*SNOOP_MAXWIND/10) #define SNOOP_MAXPERSIST 4 /* persist timeouts */ #define SNOOP_RTTDEFAULT 250000 /* this is "tuned" for the wavelan */ #define SNOOP_RTTDEVDEFAULT 50000/* this is "tuned" for the wavelan */ #define SNOOP_TIMERGRAN 200 /* Snoop timer granularity */ #define SNOOP_MIN_TIMO 250000 #define SNOOP_MAX_RXMIT 4 #define SNOOP_PERSIST_TIMO 1000000 #define SNOOP_GARBAGE_TIMO 20000000 /* Snoop states */ #define SNOOP_WIRED_ALIVE 0x0001 /* connection active (wired side) */ #define SNOOP_WLESS_ALIVE 0x0002 /* connection active (wless side) */ #define SNOOP_CLOSED 0x0004 /* connection closed */ #define SNOOP_FULL 0x0008 /* snoop cache full */ #define SNOOP_HIGHWATER 0x0010 /* snoop highwater mark reached */ #define SNOOP_RTTFLAG 0x0020 /* can compute RTT if this is set */ #define SNOOP_WLEMPTY 0x0040 /* no unack'd data from wireless side */ /* forwarding and buffering states in the multicast-based mobility algorithm */ #define SNOOP_FWD 0 /* forward packet */ #define SNOOP_BUF 1 /* buffer, don't forward */ #define FROM_WIRED 0x01 /* segment from wired side */ #define FROM_WLESS 0x10 /* from wireless side */ #define SNOOP_INSEQ 1 #define SNOOP_OUTSEQ 2 struct iphdr { short len; /* ip header length */ u_short id; /* ip id */ short off; /* ip header offset */ u_char ttl; /* ttl of datagram */ char padding; /* to make it word aligned */ }; typedef struct timeval timev; #define TIMEV typedef struct packet { struct mbuf *mb; /* mbuf chain of data */ struct iphdr iph; /* some fields of IP header */ int tcp_sum; /* tcp chksum */ tcp_seq seq; /* sequence number of first byte */ int size; /* amount of actual TCP data */ timev snd_time; /* local xmit time */ int num_rxmit; /* number of local rexmits */ int sender_rxmit; /* sender rexmitted this pkt? */ } packet_t; typedef struct seq { tcp_seq seq; int size; } seq_t; typedef struct conn_state { int alloc; /* XXX temp */ u_short conn_id; /* which connection -- unique from dst:port */ u_short wi_state; /* state of snoop (wired sender) */ u_short wl_state; /* state of snoop (wireless sender) */ u_long addr; /* wired addr */ u_long wladdr; /* wireless addr */ u_short port; /* wired port */ u_short wlport; /* wireless port */ u_short last_win; /* last flow control window size from sender */ tcp_seq last_seen; /* first byte of last packet buffered */ int last_size; /* size of last cached segment */ tcp_seq last_ack; /* last byte recd. by mh for sure */ tcp_seq iss; /* initial seq no for this connection */ tcp_seq expected_next_ack; /* expected next ack after dup sequence */ short expected_dacks; /* expected number of dup acks */ long srtt; /* smoothed rtt estimate */ long rttdev; /* smoothed rtt linear dev */ short bufhead; /* next pkt goes here */ short buftail; /* first unack'd pkt */ #ifdef SMART_SNOOP tcp_seq smart_start; /* start of out-of-order recd. block */ tcp_seq smart_end; /* end of block at receiver */ #endif /* SMART_SNOOP */ packet_t *pkts[SNOOP_MAXWIND]; /* ringbuf of cached mbufs */ short timeout_pending; /* # pending timeouts */ /* Variables for connection with sender on wireless side */ tcp_seq wl_last_seen; tcp_seq wl_last_ack; short wl_bufhead; short wl_buftail; seq_t *wlseqs[SNOOP_MAXWIND]; /* ringbuf of seq #s and sizes */ } conn_state_t; typedef struct snoop_state { short num_connections; /* number of active connections */ int disable; /* to disable snoop for experiments */ conn_state_t *cstate[SNOOP_MAXCONN]; /* array of per-connection state*/ } snoop_state_t; #define NEXT(j) ((j)+1) % SNOOP_MAXWIND /* next element in ring */ #define PREV(j) ((j) == 0) ? SNOOP_MAXWIND - 1 : (j) - 1 /* previous element */ #define WL_NEXT(j) ((j)+1) % SNOOP_MAXBLKS #define WL_PREV(j) ((j) == 0) ? SNOOP_MAXBLKS - 1 : (j) - 1 #ifndef TIMERDIFF #define TIMERDIFF #define timerdiff(nowp, thenp) \ (((nowp)->tv_sec - (thenp)->tv_sec) * 1000000 + \ (nowp)->tv_usec - (thenp)->tv_usec) #endif /* Function prototypes */ void snoop_ctrl __P((struct mbuf *, short, short, int)); inline void get_ti_hdr __P((struct mbuf *)); inline void fwd_or_free __P((struct mbuf *, short, short, int)); void snoop_init __P((void)); int snoop_conninit __P((struct mbuf *, ushort, short)); void snoop_wired __P((struct mbuf *, int, short, int)); void snoop_wless __P((struct mbuf *, int, short, int)); void snoop_data __P((struct mbuf *, int, short, int)); int snoop_insert __P((conn_state_t *, struct mbuf *, tcp_seq, short)); void snoop_ack __P((struct mbuf *, int, int)); void snoop_oldack __P((conn_state_t *, struct mbuf *, tcp_seq)); void snoop_dupack __P((conn_state_t *, struct mbuf *, tcp_seq, u_short, int)); void snoop_newack __P((conn_state_t *, struct mbuf *, tcp_seq)); void snoop_cleanbufs __P((conn_state_t *, tcp_seq, timev *)); int snoop_getconn __P((struct tcpiphdr *, short)); int snoop_addconn __P((struct tcpiphdr *, short)); void *snoop_malloc __P((int)); inline void save_ippkt __P((conn_state_t *, packet_t *, struct mbuf *, tcp_seq, u_short)); inline void snoop_freebuf __P((conn_state_t *, packet_t *)); inline int snoop_wlessloss __P((conn_state_t *, tcp_seq)); inline void snoop_seteln __P((struct tcpiphdr *)); int snoop_burst_loss __P((conn_state_t *, packet_t *, int)); void snoop_rexmt_pkt __P((conn_state_t *, packet_t *, u_char)); void snoop_rexmt_timeout __P((void *)); void snoop_persist_timeout __P((void *)); void snoop_garbage_timeout __P((void *)); inline long snoop_rto __P((conn_state_t *cs)); int snoop_rtt __P((conn_state_t *, timev *)); inline void snoop_timeout __P((conn_state_t *cs)); inline void snoop_untimeout __P((conn_state_t *cs)); long time_diff __P((timev *, timev *)); void snoop_seteln __P((struct tcpiphdr *)); void snoop_wired_ack __P((struct mbuf *, int, short, int)); void snoop_wless_data __P((struct mbuf *, int, short)); void snoop_done __P((int, short)); void snoop_wired_clear __P((conn_state_t *)); void snoop_wless_clear __P((conn_state_t *)); #ifndef NOMIP int snoop_mip_change __P((struct in_addr, MIP_STATES, MIP_STATES)); #endif #endif