ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/util.h
(Generate patch)

Comparing gvpe/src/util.h (file contents):
Revision 1.1 by pcg, Sat Mar 1 15:53:03 2003 UTC vs.
Revision 1.4 by pcg, Fri Mar 28 04:05:10 2003 UTC

20*/ 20*/
21 21
22#ifndef UTIL_H__ 22#ifndef UTIL_H__
23#define UTIL_H__ 23#define UTIL_H__
24 24
25#include <sys/socket.h> 25#include "iom.h"
26#include <netinet/in.h>
27
28#include <map>
29
30#include "device.h" 26#include "device.h"
31
32#define SOCKADDR sockaddr_in // this is lame, I know
33 27
34/* 28/*
35 * check for an existing vped for this net, and write pid to pidfile 29 * check for an existing vped for this net, and write pid to pidfile
36 */ 30 */
37extern int write_pidfile (void); 31extern int write_pidfile (void);
69 p[5] = id; 63 p[5] = id;
70} 64}
71 65
72#define mac2id(p) (p[0] & 0x01 ? 0 : (p[4] << 8) | p[5]) 66#define mac2id(p) (p[0] & 0x01 ? 0 : (p[4] << 8) | p[5])
73 67
74// a very simple fifo pkt-queue 68struct sliding_window {
75class pkt_queue 69 u32 v[(WINDOWSIZE + 31) / 32];
76 { 70 u32 seq;
77 tap_packet *queue[QUEUEDEPTH];
78 int i, j;
79 71
80 public: 72 void reset (u32 seqno)
81
82 void put (tap_packet *p);
83 tap_packet *get ();
84
85 pkt_queue ();
86 ~pkt_queue ();
87 };
88
89struct sockinfo
90 {
91 u32 host;
92 u16 port;
93
94 void set (const SOCKADDR *sa)
95 { 73 {
96 host = sa->sin_addr.s_addr; 74 memset (v, -1, sizeof v);
97 port = sa->sin_port; 75 seq = seqno;
98 } 76 }
99 77
100 sockinfo() 78 bool recv_ok (u32 seqno)
101 { 79 {
102 host = port = 0; 80 if (seqno <= seq - WINDOWSIZE)
81 slog (L_ERR, _("received duplicate or outdated packet (received %08lx, expected %08lx)\n"
82 "possible replay attack, or just massive packet reordering"), seqno, seq + 1);//D
83 else if (seqno > seq + WINDOWSIZE)
84 slog (L_ERR, _("received duplicate or out-of-sync packet (received %08lx, expected %08lx)\n"
85 "possible replay attack, or just massive packet loss"), seqno, seq + 1);//D
86 else
87 {
88 while (seqno > seq)
89 {
90 seq++;
91
92 u32 s = seq % WINDOWSIZE;
93 u32 *cell = v + (s >> 5);
94 u32 mask = 1 << (s & 31);
95
96 *cell &= ~mask;
97 }
98
99 u32 s = seqno % WINDOWSIZE;
100 u32 *cell = v + (s >> 5);
101 u32 mask = 1 << (s & 31);
102
103 if (*cell & mask)
104 {
105 slog (L_ERR, _("received duplicate packet (received %08lx, expected %08lx)\n"
106 "possible replay attack, or just packet duplication"), seqno, seq + 1);//D
107 return false;
108 }
109 else
110 {
111 *cell |= mask;
112 return true;
113 }
114 }
103 } 115 }
104
105 sockinfo(const SOCKADDR &sa)
106 {
107 set (&sa);
108 }
109
110 sockinfo(const SOCKADDR *sa)
111 {
112 set (sa);
113 }
114
115 SOCKADDR *sa()
116 {
117 static SOCKADDR sa;
118
119 sa.sin_family = AF_INET;
120 sa.sin_port = port;
121 sa.sin_addr.s_addr = host;
122
123 return &sa;
124 }
125
126 operator const char *();
127 };
128
129inline bool
130operator == (const sockinfo &a, const sockinfo &b)
131{
132 return a.host == b.host && a.port == b.port;
133}
134
135inline bool
136operator < (const sockinfo &a, const sockinfo &b)
137{
138 return a.host < b.host
139 || (a.host == b.host && a.port < b.port);
140}
141
142// only do action once every x seconds per host.
143// currently this is quite a slow implementation,
144// but suffices for normal operation.
145struct u32_rate_limiter : private map<u32, time_t>
146 {
147 int every;
148
149 bool can (u32 host);
150
151 u32_rate_limiter (time_t every = 1)
152 {
153 this->every = every;
154 }
155 }; 116};
156
157struct net_rate_limiter : u32_rate_limiter
158 {
159 bool can (SOCKADDR *sa) { return u32_rate_limiter::can((u32)sa->sin_addr.s_addr); }
160 bool can (sockinfo &si) { return u32_rate_limiter::can((u32)si.host); }
161
162 net_rate_limiter (time_t every) : u32_rate_limiter (every) {}
163 };
164 117
165#endif 118#endif
166 119

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines