Revision 574b2324

View differences:

conf/conf.c
384 384
  if (config_timer->expires == 0)
385 385
    return CONF_NOTHING;
386 386

  
387
  tm_stop(config_timer);
387
  tm2_stop(config_timer);
388 388

  
389 389
  return CONF_CONFIRM;
390 390
}
......
420 420
    return CONF_NOTHING;
421 421

  
422 422
  undo_available = 0;
423
  tm_stop(config_timer);
423
  tm2_stop(config_timer);
424 424

  
425 425
  if (configuring)
426 426
    {
......
468 468
  config_event = ev_new(&root_pool);
469 469
  config_event->hook = config_done;
470 470

  
471
  config_timer = tm_new(&root_pool);
471
  config_timer = tm2_new(&root_pool);
472 472
  config_timer->hook = config_timeout;
473 473
}
474 474

  
lib/birdlib.h
69 69
/* Microsecond time */
70 70

  
71 71
typedef s64 btime;
72
typedef s64 bird_clock_t;
72
//typedef s64 bird_clock_t;
73 73

  
74 74
#define S_	* (btime) 1000000
75 75
#define MS_	* (btime) 1000
......
85 85
#define NS	/1000
86 86
#endif
87 87

  
88
#define TIME_INFINITY ((s64) 0x7fffffffffffffff)
89

  
88 90

  
89 91
/* Rate limiting */
90 92

  
91 93
struct tbf {
92
  bird_clock_t timestamp;		/* Last update */
93
  u16 count;				/* Available tokens */
94
  btime timestamp;			/* Last update */
95
  u64 count;				/* Available micro-tokens */
94 96
  u16 burst;				/* Max number of tokens */
95
  u16 rate;				/* Rate of replenishment */
96
  u16 mark;				/* Whether last op was limited */
97
  u16 rate;				/* Rate of replenishment (tokens / sec) */
98
  u32 drop;				/* Number of failed request since last successful */
97 99
};
98 100

  
99 101
/* Default TBF values for rate limiting log messages */
100 102
#define TBF_DEFAULT_LOG_LIMITS { .rate = 1, .burst = 5 }
101 103

  
102
void tbf_update(struct tbf *f);
103

  
104
static inline int
105
tbf_limit(struct tbf *f)
106
{
107
  tbf_update(f);
108

  
109
  if (!f->count)
110
  {
111
    f->mark = 1;
112
    return 1;
113
  }
114

  
115
  f->count--;
116
  f->mark = 0;
117
  return 0;
118
}
104
int tbf_limit(struct tbf *f);
119 105

  
120 106

  
121 107
/* Logging and dying */
lib/tbf.c
10 10
#include "nest/bird.h"
11 11
#include "lib/timer.h"
12 12

  
13
void
14
tbf_update(struct tbf *f)
13
int
14
tbf_limit(struct tbf *f)
15 15
{
16
  bird_clock_t delta = now - f->timestamp;
16
  btime delta = current_time() - f->timestamp;
17 17

  
18
  if (delta == 0)
19
    return;
20

  
21
  f->timestamp = now;
18
  if (delta > 0)
19
  {
20
    u64 next = f->count + delta * f->rate;
21
    u64 burst = (u64) f->burst << 20;
22
    f->count = MIN(next, burst);
23
    f->timestamp += delta;
24
  }
22 25

  
23
  if ((0 < delta) && (delta < f->burst))
26
  if (f->count < 1000000)
24 27
  {
25
    u32 next = f->count + delta * f->rate;
26
    f->count = MIN(next, f->burst);
28
    f->drop++;
29
    return 1;
27 30
  }
28 31
  else
29
    f->count = f->burst;
32
  {
33
    f->count -= 1000000;
34
    f->drop = 0;
35
    return 0;
36
  }
30 37
}
lib/timer.h
46 46
btime current_time(void);
47 47
btime current_real_time(void);
48 48

  
49
#define now (current_time() TO_S)
50
#define now_real (current_real_time() TO_S)
49
//#define now (current_time() TO_S)
50
//#define now_real (current_real_time() TO_S)
51 51
extern btime boot_time;
52 52

  
53 53
timer2 *tm2_new(pool *p);
nest/proto.c
1288 1288
#endif
1289 1289

  
1290 1290
  proto_pool = rp_new(&root_pool, "Protocols");
1291
  proto_shutdown_timer = tm_new(proto_pool);
1291
  proto_shutdown_timer = tm2_new(proto_pool);
1292 1292
  proto_shutdown_timer->hook = proto_shutdown_loop;
1293 1293
}
1294 1294

  
proto/ospf/ospf.h
58 58
  log_rl(&p->log_lsa_tbf, L_REMOTE "%s: " msg, p->p.name, args)
59 59

  
60 60
#define LOG_LSA2(msg, args...) \
61
  do { if (! p->log_lsa_tbf.mark) \
61
  do { if (! p->log_lsa_tbf.drop) \
62 62
    log(L_REMOTE "%s: " msg, p->p.name, args); } while(0)
63 63

  
64 64

  
proto/rip/packets.c
189 189
   * have the same CSN. We are using real time, but enforcing monotonicity.
190 190
   */
191 191
  if (ifa->cf->auth_type == RIP_AUTH_CRYPTO)
192
    ifa->csn = (ifa->csn < (u32) now_real) ? (u32) now_real : ifa->csn + 1;
192
  {
193
    u32 now_real = (u32) (current_real_time() TO_S);
194
    ifa->csn = (ifa->csn < now_real) ? now_real : ifa->csn + 1;
195
  }
193 196
}
194 197

  
195 198
static void
sysdep/linux/netlink.c
151 151
      nl->fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
152 152
      if (nl->fd < 0)
153 153
	die("Unable to open rtnetlink socket: %m");
154
      nl->seq = now;
154
      nl->seq = (u32) (current_time() TO_S); /* Or perhaps random_u32() ? */
155 155
      nl->rx_buffer = xmalloc(NL_RX_SIZE);
156 156
      nl->last_hdr = NULL;
157 157
      nl->last_size = 0;
sysdep/unix/io.c
2132 2132
  // XXX init_times();
2133 2133
  // XXX update_times();
2134 2134
  boot_time = current_time();
2135
  srandom((int) now_real);
2135
  srandom((uint) (current_real_time() TO_S));
2136 2136
}
2137 2137

  
2138 2138
static int short_loops = 0;
sysdep/unix/log.c
180 180
void
181 181
log_rl(struct tbf *f, const char *msg, ...)
182 182
{
183
  int last_hit = f->mark;
184 183
  int class = 1;
185 184
  va_list args;
186 185

  
187 186
  /* Rate limiting is a bit tricky here as it also logs '...' during the first hit */
188
  if (tbf_limit(f) && last_hit)
187
  if (tbf_limit(f) && (f->drop > 1))
189 188
    return;
190 189

  
191 190
  if (*msg >= 1 && *msg <= 8)
192 191
    class = *msg++;
193 192

  
194 193
  va_start(args, msg);
195
  vlog(class, (f->mark ? "..." : msg), args);
194
  vlog(class, (f->drop ? "..." : msg), args);
196 195
  va_end(args);
197 196
}
198 197

  
......
332 331
mrt_dump_message(struct proto *p, u16 type, u16 subtype, byte *buf, u32 len)
333 332
{
334 333
  /* Prepare header */
335
  put_u32(buf+0, now_real);
334
  put_u32(buf+0, current_real_time() TO_S);
336 335
  put_u16(buf+4, type);
337 336
  put_u16(buf+6, subtype);
338 337
  put_u32(buf+8, len - MRTDUMP_HDR_LENGTH);
sysdep/unix/timer.h
16 16

  
17 17

  
18 18
typedef struct timer2 timer;
19

  
19
#if 0
20 20
static inline timer *tm_new(pool *p)
21 21
{ return (void *) tm2_new(p); }
22 22

  
......
44 44
static inline timer * tm_new_set(pool *p, void (*hook)(timer *), void *data, uint rand, uint rec)
45 45
{ return tm2_new_init(p, hook, data, rec S_, rand S_); }
46 46

  
47
#endif
47 48

  
48
#define TIME_INFINITY ((s64) 0x7fffffffffffffff)
49 49

  
50 50

  
51 51
#endif

Also available in: Unified diff