Branch data Line data Source code
1 : : // $Id: Serializer.cc 6752 2009-06-14 04:24:52Z vern $
2 : :
3 : : #include <fcntl.h>
4 : : #include <unistd.h>
5 : : #include <errno.h>
6 : : #include <time.h>
7 : : #include <dirent.h>
8 : : #include <libgen.h>
9 : : #include <sys/time.h>
10 : : #include <sys/stat.h>
11 : :
12 : : #include "Serializer.h"
13 : : #include "Scope.h"
14 : : #include "Stmt.h"
15 : : #include "Logger.h"
16 : : #include "Func.h"
17 : : #include "Event.h"
18 : : #include "EventRegistry.h"
19 : : #include "SerializationFormat.h"
20 : : #include "NetVar.h"
21 : : #include "Conn.h"
22 : : #include "Timer.h"
23 : : #include "RemoteSerializer.h"
24 : :
25 : 6 : Serializer::Serializer(SerializationFormat* arg_format)
26 : : {
27 [ # # ][ - + ]: 6 : if ( arg_format )
28 : 0 : format = arg_format;
29 : : else
30 : 6 : format = new BinarySerializationFormat();
31 : :
32 : 6 : io = 0;
33 : 6 : error_descr = 0;
34 : 6 : current_cache = 0;
35 : 6 : }
36 : :
37 : 2 : Serializer::~Serializer()
38 : : {
39 [ # # ][ # # ]: 2 : delete format;
[ + - ]
40 [ # # ][ # # ]: 2 : delete [] error_descr;
[ + + ]
41 [ # # ][ # # ]: 2 : }
[ - + ]
42 : :
43 : 0 : bool Serializer::Read(string* s, const char* tag)
44 : : {
45 : : char* cstr;
46 : : int len;
47 [ # # ]: 0 : if ( format->Read(&cstr, &len, tag) )
48 : : {
49 : 0 : s->assign(cstr, len);
50 [ # # ]: 0 : delete [] cstr;
51 : 0 : return true;
52 : : }
53 : : else
54 : 0 : return false;
55 : : }
56 : :
57 : : bool Serializer::StartSerialization(SerialInfo* info, const char* descr,
58 : 1 : char tag)
59 : : {
60 : 1 : format->StartWrite();
61 [ - + ]: 1 : assert(current_cache);
62 : 1 : SetErrorDescr(fmt("serializing %s", descr));
63 [ - + ]: 1 : if ( ! Write(tag, "tag") )
64 : : {
65 : 0 : Error(io->Error());
66 : 0 : return false;
67 : : }
68 : :
69 : 1 : current_cache->Begin(info->new_cache_strategy);
70 : 1 : return true;
71 : : }
72 : :
73 : 1 : bool Serializer::EndSerialization(SerialInfo* info)
74 : : {
75 : 1 : ChunkedIO::Chunk* chunk = new ChunkedIO::Chunk;
76 : 1 : chunk->len = format->EndWrite(&chunk->data);
77 : :
78 [ - + ]: 1 : if ( info->chunk )
79 : : {
80 : :
81 [ # # ]: 0 : if ( ! io->Write(info->chunk) )
82 : : {
83 : 0 : Error(io->Error());
84 : 0 : return false;
85 : : }
86 : : }
87 : :
88 [ - + ]: 1 : if ( ! io->Write(chunk) )
89 : : {
90 : 0 : Error(io->Error());
91 : 0 : return false;
92 : : }
93 : :
94 : 1 : current_cache->End(info->new_cache_strategy);
95 : 1 : return true;
96 : : }
97 : :
98 : 1 : bool Serializer::Serialize(SerialInfo* info, const ID& id)
99 : : {
100 [ + - ]: 1 : if ( info->cont.NewInstance() )
101 : : {
102 [ - + ][ # # ]: 1 : if ( ! (id.IsGlobal() || id.IsEnumConst()) )
[ - + ]
103 : : {
104 : 0 : Error("non-global identifiers cannot be serialized");
105 : 0 : return false;
106 : : }
107 : :
108 [ - + ]: 1 : if ( ! StartSerialization(info, "ID", 'i') )
109 : 0 : return false;
110 : : }
111 : :
112 : 1 : info->cont.SaveContext();
113 : 1 : bool result = id.Serialize(info);
114 : 1 : info->cont.RestoreContext();
115 : :
116 [ - + ]: 1 : if ( ! result )
117 : : {
118 : 0 : Error("failed");
119 : 0 : return false;
120 : : }
121 : :
122 [ - + ]: 1 : if ( info->cont.ChildSuspended() )
123 : 0 : return true;
124 : :
125 : 1 : WriteSeparator();
126 : 1 : return EndSerialization(info);
127 : : }
128 : :
129 : 0 : bool Serializer::Serialize(SerialInfo* info, const char* func, val_list* args)
130 : : {
131 : 0 : DisableSuspend suspend(info);
132 : :
133 [ # # ]: 0 : if ( ! StartSerialization(info, "call", 'e') )
134 : 0 : return false;
135 : :
136 : 0 : WriteOpenTag("call");
137 : 0 : int a = args->length();
138 : 0 : Write(func, "name");
139 : 0 : Write(network_time, "time");
140 : 0 : Write(a, "len");
141 : :
142 [ # # ]: 0 : loop_over_list(*args, i) (*args)[i]->Serialize(info);
143 : :
144 : 0 : WriteCloseTag("call");
145 : 0 : WriteSeparator();
146 : :
147 : 0 : return EndSerialization(info);
148 : : }
149 : :
150 : 0 : bool Serializer::Serialize(SerialInfo* info, const StateAccess& s)
151 : : {
152 : 0 : DisableSuspend suspend(info);
153 : :
154 [ # # ]: 0 : if ( ! StartSerialization(info, "state access", 's') )
155 : 0 : return false;
156 : :
157 [ # # ]: 0 : if ( ! s.Serialize(info) )
158 : : {
159 : 0 : Error("failed");
160 : 0 : return false;
161 : : }
162 : :
163 : 0 : return EndSerialization(info);
164 : : }
165 : :
166 : 0 : bool Serializer::Serialize(SerialInfo* info, const Timer& t)
167 : : {
168 : 0 : DisableSuspend suspend(info);
169 : :
170 [ # # ]: 0 : if ( ! StartSerialization(info, "timer", 't') )
171 : 0 : return false;
172 : :
173 [ # # ]: 0 : if ( ! t.Serialize(info) )
174 : : {
175 : 0 : Error("failed");
176 : 0 : return false;
177 : : }
178 : :
179 : 0 : return EndSerialization(info);
180 : : }
181 : :
182 : 0 : bool Serializer::Serialize(SerialInfo* info, const Connection& c)
183 : : {
184 : 0 : DisableSuspend suspend(info);
185 : :
186 [ # # ]: 0 : if ( ! StartSerialization(info, "connection", 'c') )
187 : 0 : return false;
188 : :
189 [ # # ]: 0 : if ( ! c.Serialize(info) )
190 : : {
191 : 0 : Error("failed");
192 : 0 : return false;
193 : : }
194 : :
195 : 0 : return EndSerialization(info);
196 : : }
197 : :
198 : 0 : bool Serializer::Serialize(SerialInfo* info, const Packet& p)
199 : : {
200 : 0 : DisableSuspend suspend(info);
201 : :
202 [ # # ]: 0 : if ( ! StartSerialization(info, "packet", 'p') )
203 : 0 : return false;
204 : :
205 [ # # ]: 0 : if ( ! p.Serialize(info) )
206 : : {
207 : 0 : Error("failed");
208 : 0 : return false;
209 : : }
210 : :
211 : 0 : return EndSerialization(info);
212 : : }
213 : :
214 : 1 : int Serializer::Unserialize(UnserialInfo* info, bool block)
215 : : {
216 [ - + ]: 1 : assert(current_cache);
217 : :
218 : 1 : SetErrorDescr("unserializing");
219 : :
220 : 1 : current_cache->Begin(info->new_cache_strategy);
221 : :
222 : 1 : ChunkedIO::Chunk* chunk = info->chunk;
223 : :
224 [ + - ]: 1 : while ( ! chunk )
225 : : {
226 [ + - ]: 1 : if ( ! io->Read(&chunk) )
227 : : {
228 [ + - ]: 1 : if ( io->Eof() )
229 : 1 : return 0;
230 : 0 : Error(io->Error());
231 : 0 : return -1;
232 : : }
233 : :
234 [ # # ][ # # ]: 0 : if ( ! chunk && ! block )
235 : 0 : return 0;
236 : : }
237 : :
238 : 0 : format->StartRead(chunk->data, chunk->len);
239 : :
240 : : char type;
241 [ # # ]: 0 : if ( ! format->Read(&type, "tag") )
242 : 0 : return -1;
243 : :
244 : : // DEBUG(fmt("parent: serialization of size %d", );
245 : :
246 : : bool result;
247 [ # # # # # : 0 : switch ( type ) {
# # ]
248 : : case 'i':
249 : 0 : result = UnserializeID(info);
250 : 0 : break;
251 : :
252 : : case 'e':
253 : 0 : result = UnserializeCall(info);
254 : 0 : break;
255 : :
256 : : case 's':
257 : 0 : result = UnserializeStateAccess(info);
258 : 0 : break;
259 : :
260 : : case 'c':
261 : 0 : result = UnserializeConnection(info);
262 : 0 : break;
263 : :
264 : : case 't':
265 : 0 : result = UnserializeTimer(info);
266 : 0 : break;
267 : :
268 : : case 'p':
269 : 0 : result = UnserializePacket(info);
270 : 0 : break;
271 : :
272 : : default:
273 : 0 : Error(fmt("unknown serialization type %x", (int) type));
274 : 0 : result = false;
275 : : }
276 : :
277 : 0 : format->EndRead();
278 : :
279 [ # # ]: 0 : if ( ! info->chunk )
280 : : { // only delete if we allocated it ourselves
281 [ # # ]: 0 : delete [] chunk->data;
282 : 0 : delete chunk;
283 : : }
284 : :
285 : 0 : current_cache->End(info->new_cache_strategy);
286 : :
287 [ # # ]: 1 : return result ? 1 : -1;
288 : : }
289 : :
290 : 0 : bool Serializer::UnserializeID(UnserialInfo* info)
291 : : {
292 : 0 : SetErrorDescr("unserializing ID");
293 : :
294 : 0 : ID* id = ID::Unserialize(info);
295 : :
296 [ # # ]: 0 : if ( ! id )
297 : 0 : return false;
298 : :
299 [ # # ]: 0 : if ( info->print )
300 : : {
301 : 0 : ODesc d;
302 : 0 : d.SetQuotes(true);
303 : 0 : d.SetIncludeStats(true);
304 : 0 : d.SetShort();
305 : 0 : id->DescribeExtended(&d);
306 : 0 : fprintf(info->print, "ID %s\n", d.Description());
307 : : }
308 : :
309 [ # # ]: 0 : if ( ! info->ignore_callbacks )
310 : 0 : GotID(id, id->ID_Val());
311 : : else
312 : 0 : Unref(id);
313 : :
314 : 0 : return true;
315 : : }
316 : :
317 : 0 : bool Serializer::UnserializeCall(UnserialInfo* info)
318 : : {
319 : : char* name;
320 : : int len;
321 : : double time;
322 : :
323 [ # # ][ # # ]: 0 : if ( ! (UNSERIALIZE_STR(&name, 0) && UNSERIALIZE(&time) && UNSERIALIZE(&len)) )
[ # # ][ # # ]
324 : 0 : return false;
325 : :
326 : 0 : SetErrorDescr(fmt("unserializing event/function %s", name));
327 : :
328 : 0 : bool ignore = false;
329 : 0 : FuncType* functype = 0;
330 : 0 : type_list* types = 0;
331 : :
332 : 0 : ID* id = global_scope()->Lookup(name);
333 : :
334 [ # # ]: 0 : if ( id )
335 : : {
336 [ # # ]: 0 : if ( id->Type()->Tag() == TYPE_FUNC )
337 : : {
338 : 0 : functype = id->Type()->AsFuncType();
339 : 0 : types = functype->ArgTypes()->Types();
340 [ # # ]: 0 : if ( types->length() != len )
341 : : {
342 : 0 : Error("wrong number of arguments, ignoring");
343 : 0 : ignore = true;
344 : : }
345 : : }
346 : : else
347 : : {
348 : 0 : Error("not a function/event, ignoring");
349 : 0 : ignore = true;
350 : : }
351 : : }
352 : : else
353 : : {
354 : 0 : Error("unknown event/function, ignoring");
355 : 0 : ignore = true;
356 : : }
357 : :
358 : 0 : ODesc d;
359 : 0 : d.SetQuotes(true);
360 : 0 : d.SetIncludeStats(true);
361 : 0 : d.SetShort();
362 : :
363 : 0 : val_list* args = new val_list;
364 [ # # ]: 0 : for ( int i = 0; i < len; ++i )
365 : : {
366 : 0 : Val* v = Val::Unserialize(info);
367 : :
368 [ # # ]: 0 : if ( ! v )
369 : : {
370 [ # # ]: 0 : delete [] name;
371 : 0 : return false;
372 : : }
373 : :
374 [ # # ]: 0 : if ( ! ignore )
375 : : {
376 [ # # ][ # # ]: 0 : if ( v->Type()->Tag() != (*types)[i]->Tag() &&
[ # # ]
377 : : (*types)[i]->Tag() != TYPE_ANY )
378 : : {
379 : 0 : Error("mismatch in argument types; ignoring");
380 : 0 : ignore = true;
381 : : }
382 : :
383 [ # # ][ # # ]: 0 : if ( info->print && types && ! ignore )
[ # # ]
384 : 0 : v->Describe(&d);
385 : : }
386 : :
387 : 0 : args->append(v);
388 : : }
389 : :
390 [ # # ]: 0 : if ( ! ignore )
391 : : {
392 [ # # ]: 0 : if ( info->print )
393 : : fprintf(info->print, "%s [%.06f] %s(%s)\n",
394 : : functype->IsEvent() ? "Event" : "Function call",
395 [ # # ][ # # ]: 0 : time, name, types ? d.Description() : "<ignored>");
396 : :
397 [ # # ]: 0 : if ( functype->IsEvent() )
398 : : {
399 : 0 : EventHandler* handler = event_registry->Lookup(name);
400 [ # # ]: 0 : assert(handler);
401 [ # # ]: 0 : if ( ! info->ignore_callbacks )
402 : 0 : GotEvent(name, time, handler, args);
403 : : }
404 : : else
405 [ # # ]: 0 : if ( ! info->ignore_callbacks )
406 : 0 : GotFunctionCall(name, time, id->ID_Val()->AsFunc(), args);
407 : :
408 [ # # ]: 0 : if ( info->ignore_callbacks )
409 : 0 : delete_vals(args);
410 : :
411 : : }
412 : : else
413 : 0 : delete_vals(args);
414 : :
415 [ # # ]: 0 : delete [] name;
416 : :
417 : 0 : return true;
418 : : }
419 : :
420 : 0 : bool Serializer::UnserializeStateAccess(UnserialInfo* info)
421 : : {
422 : 0 : SetErrorDescr("unserializing state acess");
423 : :
424 : 0 : StateAccess* s = StateAccess::Unserialize(info);
425 : :
426 [ # # ]: 0 : if ( ! s )
427 : 0 : return false;
428 : :
429 [ # # ]: 0 : if ( info->print )
430 : : {
431 : 0 : ODesc d;
432 : 0 : d.SetQuotes(true);
433 : 0 : d.SetIncludeStats(true);
434 : 0 : d.SetShort();
435 : 0 : s->Describe(&d);
436 : 0 : fprintf(info->print, "State access: %s\n", d.Description());
437 : : }
438 : :
439 [ # # ]: 0 : if ( ! info->ignore_callbacks )
440 : 0 : GotStateAccess(s);
441 : : else
442 [ # # ]: 0 : delete s;
443 : :
444 : 0 : return true;
445 : : }
446 : :
447 : 0 : bool Serializer::UnserializeTimer(UnserialInfo* info)
448 : : {
449 : 0 : SetErrorDescr("unserializing timer");
450 : :
451 : 0 : Timer* t = Timer::Unserialize(info);
452 : :
453 [ # # ]: 0 : if ( ! t )
454 : 0 : return false;
455 : :
456 [ # # ]: 0 : if ( info->print )
457 : : {
458 : 0 : ODesc d;
459 : 0 : d.SetQuotes(true);
460 : 0 : d.SetIncludeStats(true);
461 : 0 : d.SetShort();
462 : 0 : t->Describe(&d);
463 : 0 : fprintf(info->print, "Timer: %s\n", d.Description());
464 : : }
465 : :
466 [ # # ]: 0 : if ( ! info->ignore_callbacks )
467 : 0 : GotTimer(t);
468 : :
469 : 0 : return true;
470 : : }
471 : :
472 : 0 : bool Serializer::UnserializeConnection(UnserialInfo* info)
473 : : {
474 : 0 : SetErrorDescr("unserializing connection");
475 : :
476 : 0 : Connection* c = Connection::Unserialize(info);
477 : :
478 [ # # ]: 0 : if ( ! c )
479 : 0 : return false;
480 : :
481 [ # # ]: 0 : if ( info->print )
482 : : {
483 : 0 : ODesc d;
484 : 0 : d.SetQuotes(true);
485 : 0 : d.SetIncludeStats(true);
486 : 0 : d.SetShort();
487 : 0 : c->Describe(&d);
488 : 0 : fprintf(info->print, "Connection: %s", d.Description());
489 : : }
490 : :
491 [ # # ]: 0 : if ( info->install_conns )
492 : : {
493 [ # # ][ # # ]: 0 : if ( c->IsPersistent() && c->Key() )
[ # # ]
494 : 0 : persistence_serializer->Register(c);
495 : 0 : Ref(c);
496 : 0 : sessions->Insert(c);
497 : : }
498 : : else
499 : : // We finish the connection here because it's not part
500 : : // of the standard processing and most likely to be
501 : : // discarded pretty soon.
502 : : // Without the Done(), some cleanup may not take place.
503 : 0 : c->Done();
504 : :
505 [ # # ]: 0 : if ( ! info->ignore_callbacks )
506 : 0 : GotConnection(c);
507 : : else
508 : 0 : Unref(c);
509 : :
510 : 0 : return true;
511 : : }
512 : :
513 : 0 : bool Serializer::UnserializePacket(UnserialInfo* info)
514 : : {
515 : 0 : SetErrorDescr("unserializing packet");
516 : :
517 : 0 : Packet* p = Packet::Unserialize(info);
518 : :
519 [ # # ]: 0 : if ( ! p )
520 : 0 : return false;
521 : :
522 [ # # ]: 0 : if ( info->print )
523 : : {
524 : 0 : ODesc d;
525 : 0 : d.SetQuotes(true);
526 : 0 : d.SetIncludeStats(true);
527 : 0 : d.SetShort();
528 : 0 : p->Describe(&d);
529 : 0 : fprintf(info->print, "Packet: %s", d.Description());
530 : : }
531 : :
532 [ # # ]: 0 : if ( ! info->ignore_callbacks )
533 : 0 : GotPacket(p);
534 : : else
535 [ # # ]: 0 : delete p;
536 : :
537 : 0 : return true;
538 : : }
539 : :
540 : 0 : void Serializer::Error(const char* str)
541 : : {
542 : : char buffer[1024];
543 : : safe_snprintf(buffer, sizeof(buffer), "%s%s%s",
544 [ # # ][ # # ]: 0 : error_descr ? error_descr : "", error_descr ? ": " : "", str);
545 : 0 : ReportError(buffer);
546 : 0 : }
547 : :
548 : 0 : void Serializer::Warning(const char* str)
549 : : {
550 : : // We ignore these as there's no good place to report them.
551 : 0 : }
552 : :
553 : 3 : SerializationCache::SerializationCache(unsigned int arg_max_cache_size)
554 : : {
555 : 3 : max_cache_size = arg_max_cache_size;
556 : 3 : next_id = 1;
557 : 3 : cache_stable.head = cache_stable.tail = 0;
558 : 3 : cache_unstable.head = cache_unstable.tail = 0;
559 : 3 : cache_stable.size = cache_unstable.size = 0;
560 : 3 : }
561 : :
562 : 1 : SerializationCache::~SerializationCache()
563 : : {
564 : 1 : Clear();
565 : 1 : }
566 : :
567 : : SerializationCache::PermanentID
568 : : SerializationCache::Register(const SerialObj* obj, PermanentID pid,
569 : 65 : bool new_cache_strategy)
570 : : {
571 [ + - ]: 65 : if ( pid == NONE )
572 : 65 : pid = next_id++;
573 : :
574 : 65 : PIDMap::iterator i = pid_map.find(pid);
575 [ - + ]: 65 : assert(i == pid_map.end());
576 : :
577 : : CacheList* cache =
578 : : (new_cache_strategy && obj->IsCacheStable()) ?
579 [ - + ][ # # ]: 65 : &cache_stable : &cache_unstable;
580 : :
581 : 65 : CacheEntry* entry = new CacheEntry;
582 : 65 : entry->obj.serial = obj;
583 : 65 : entry->is_bro_obj = obj->IsBroObj();
584 : 65 : entry->pid = pid;
585 : 65 : entry->tid = obj->GetTID()->Value();
586 : 65 : entry->time = SerialObj::GetTimeCounter();
587 : 65 : entry->prev = cache->tail;
588 : 65 : entry->next = 0;
589 : 65 : entry->cache = cache;
590 : 65 : entry->stype = obj->GetSerialType();
591 : :
592 [ + + ]: 65 : if ( cache->tail )
593 : 64 : cache->tail->next = entry;
594 [ + + ]: 65 : if ( ! cache->head )
595 : 1 : cache->head = entry;
596 : :
597 : 65 : cache->tail = entry;
598 : 65 : ++(cache->size);
599 : :
600 : : // This is a bit weird. If the TID is already contained in the map (i.e.
601 : : // we're re-registering), TIDMap::insert() will *not* override the old
602 : : // entry but set the bool to false and return it.
603 : 65 : pair<TIDMap::iterator, bool> old = tid_map.insert(TIDMap::value_type(entry->tid, entry));
604 [ - + ]: 65 : if ( ! old.second )
605 : : {
606 : : // Already existed.
607 : 0 : old.first->second->tid = 0; // invalidate
608 : 0 : old.first->second = entry; // replace
609 : : }
610 : :
611 : 65 : pid_map.insert(PIDMap::value_type(pid, entry));
612 : :
613 [ + + ]: 65 : if ( entry->is_bro_obj )
614 : 33 : Ref(const_cast<BroObj*>(entry->obj.bro));
615 : : else
616 : : {
617 : : // Make sure it goes into unstable.
618 [ - + ]: 32 : assert(! obj->IsCacheStable());
619 : :
620 : 32 : volatiles.push_back(entry);
621 : : }
622 : :
623 : 65 : return entry->pid;
624 : : }
625 : :
626 : 107 : void SerializationCache::UnlinkEntry(CacheEntry* e)
627 : : {
628 [ - + ]: 107 : assert(e);
629 : :
630 : : // Remove from double-linked list.
631 [ + + ]: 107 : if ( e == e->cache->head )
632 : : {
633 : 33 : e->cache->head = e->next;
634 [ + + ]: 33 : if ( e->cache->head )
635 : 33 : e->cache->head->prev = 0;
636 : : }
637 : : else
638 : 74 : e->prev->next = e->next;
639 : :
640 [ + + ]: 107 : if ( e == e->cache->tail )
641 : : {
642 : 8 : e->cache->tail = e->prev;
643 [ + + ]: 8 : if ( e->cache->tail )
644 : 8 : e->cache->tail->next = 0;
645 : : }
646 : : else
647 : 99 : e->next->prev = e->prev;
648 : :
649 : 107 : e->prev = e->next = 0;
650 : 107 : }
651 : :
652 : 65 : void SerializationCache::RemoveEntry(CacheEntry* e)
653 : : {
654 [ - + ]: 65 : assert(e);
655 : 65 : UnlinkEntry(e);
656 : :
657 [ + - ]: 65 : if ( e->tid )
658 : 65 : tid_map.erase(e->tid);
659 : :
660 : 65 : pid_map.erase(e->pid);
661 : :
662 [ + + ]: 65 : if ( e->is_bro_obj )
663 : 33 : Unref(const_cast<BroObj*>(e->obj.bro));
664 : :
665 : 65 : e->obj.serial = 0; // for debugging
666 : 65 : --(e->cache->size);
667 : 65 : delete e;
668 : 65 : }
669 : :
670 : 42 : void SerializationCache::MoveEntryToTail(CacheEntry* e)
671 : : {
672 [ - + ]: 42 : assert(e);
673 : 42 : UnlinkEntry(e);
674 : 42 : e->prev = e->cache->tail;
675 : 42 : e->next = 0;
676 : :
677 [ + - ]: 42 : if ( e->cache->tail )
678 : 42 : e->cache->tail->next = e;
679 [ - + ]: 42 : if ( ! e->cache->head )
680 : 0 : e->cache->head = e;
681 : :
682 : 42 : e->cache->tail = e;
683 : 42 : }
684 : :
685 : 7 : void SerializationCache::Clear()
686 : : {
687 : 7 : tid_map.clear();
688 : 7 : pid_map.clear();
689 : 7 : volatiles.clear();
690 : :
691 [ - + ]: 7 : while ( cache_stable.head )
692 : 0 : RemoveEntry(cache_stable.head);
693 : :
694 [ + + ]: 40 : while ( cache_unstable.head )
695 : 33 : RemoveEntry(cache_unstable.head);
696 : :
697 [ - + ]: 7 : assert(cache_stable.size == 0);
698 [ - + ]: 7 : assert(cache_unstable.size == 0);
699 : 7 : }
700 : :
701 : 3 : void SerializationCache::End(bool new_cache_strategy)
702 : : {
703 : : // Remove objects not-derived from BroObj (they aren't ref'counted
704 : : // so it's not safe to keep them).
705 [ + + ]: 35 : for ( VolatileList::iterator i = volatiles.begin();
706 : : i != volatiles.end(); i++ )
707 : : {
708 [ - + ]: 32 : assert(*i);
709 : 32 : RemoveEntry(*i);
710 : : }
711 : :
712 : 3 : volatiles.clear();
713 : :
714 [ - + ]: 3 : if ( new_cache_strategy )
715 : : {
716 [ # # ][ # # ]: 0 : while ( max_cache_size && cache_stable.head &&
[ # # ]
717 : : cache_stable.size > max_cache_size )
718 : 0 : RemoveEntry(cache_stable.head);
719 : :
720 [ # # ][ # # ]: 0 : while ( max_cache_size && cache_unstable.head &&
[ # # ]
721 : : cache_unstable.size > max_cache_size )
722 : 0 : RemoveEntry(cache_unstable.head);
723 : : }
724 : :
725 : : else
726 : : {
727 [ + - ][ - + ]: 3 : while ( max_cache_size && pid_map.size() > max_cache_size )
[ - + ]
728 : 0 : RemoveEntry(cache_unstable.head);
729 : : }
730 : 3 : }
731 : :
732 : 3 : FileSerializer::FileSerializer(SerializationFormat* format)
733 : 3 : : Serializer(format), cache(100)
734 : : {
735 : 3 : file = 0;
736 : 3 : fd = -1;
737 : 3 : io = 0;
738 : 3 : SetCache(&cache);
739 : 3 : }
740 : :
741 : 1 : FileSerializer::~FileSerializer()
742 : : {
743 [ # # ][ # # ]: 1 : if ( io )
[ - + ]
744 : 0 : io->Flush();
745 : :
746 [ # # ][ # # ]: 1 : delete [] file;
[ - + ]
747 [ # # ][ # # ]: 1 : delete io;
[ - + ]
748 : :
749 [ # # ][ # # ]: 1 : if ( fd >= 0 )
[ - + ]
750 : 0 : close(fd);
751 [ # # ][ # # ]: 1 : }
[ - + ]
752 : :
753 : 0 : bool FileSerializer::Open(const char* file, bool pure)
754 : : {
755 [ # # ]: 0 : if ( ! OpenFile(file, false) )
756 : 0 : return false;
757 : :
758 [ # # ]: 0 : if ( pure )
759 : 0 : io->MakePure();
760 : :
761 [ # # ]: 0 : if ( ! PrepareForWriting() )
762 : 0 : return false;
763 : :
764 : 0 : return true;
765 : : }
766 : :
767 : 0 : bool FileSerializer::Close()
768 : : {
769 : 0 : CloseFile();
770 : 0 : return true;
771 : : }
772 : :
773 : 2 : bool FileSerializer::OpenFile(const char* arg_file, bool readonly, bool should_exist)
774 : : {
775 : 2 : CloseFile();
776 : :
777 : 2 : cache.Clear();
778 : :
779 : 2 : file = copy_string(arg_file);
780 [ + + ]: 2 : fd = open(file, readonly ? O_RDONLY : O_WRONLY | O_CREAT | O_TRUNC, 0600);
781 : :
782 [ - + ]: 2 : if ( fd < 0 )
783 : : {
784 [ # # ][ # # ]: 0 : if ( readonly && errno == ENOENT )
[ # # ]
785 : : {
786 : : // Only an error if we expect to exist.
787 [ # # ]: 0 : if ( should_exist )
788 : : {
789 : 0 : Error(fmt("%s does not exist", file));
790 : 0 : return false;
791 : : }
792 : :
793 : 0 : CloseFile();
794 : 0 : return true;
795 : : }
796 : :
797 : : Error(fmt("can't open file %s for %s: %s",
798 : : file, (readonly ? "reading" : "writing"),
799 [ # # ]: 0 : strerror(errno)));
800 : 0 : return false;
801 : : }
802 : :
803 : 4 : io = new ChunkedIOFd(fd, "file");
804 : :
805 : 2 : return io != 0;
806 : : }
807 : :
808 : 4 : void FileSerializer::CloseFile()
809 : : {
810 [ + + ]: 4 : if ( io )
811 : 2 : io->Flush();
812 : :
813 [ + + ]: 4 : if ( fd >= 0 )
814 : 2 : close(fd);
815 : 4 : fd = -1;
816 : :
817 [ + + ]: 4 : delete [] file;
818 : 4 : file = 0;
819 : :
820 [ + + ]: 4 : delete io;
821 : 4 : io = 0;
822 : :
823 : 4 : cache.Clear();
824 : 4 : }
825 : :
826 : 1 : bool FileSerializer::PrepareForWriting()
827 : : {
828 [ + - ]: 1 : if ( ! io->IsPure() )
829 : : {
830 : : // Write file header.
831 : 1 : uint32 magic = htonl(MAGIC);
832 : 1 : uint16 version = htons(DATA_FORMAT_VERSION);
833 : 1 : uint32 time = htonl(uint32(::time(0)));
834 : :
835 [ + - + - ]: 1 : if ( write(fd, &magic, sizeof(magic)) != sizeof(magic ) ||
[ - + ][ - + ]
836 : : write(fd, &version, sizeof(version)) != sizeof(version) ||
837 : : write(fd, &time, sizeof(time)) != sizeof(time))
838 : : {
839 : : Error(fmt("can't write file header to %s: %s",
840 : 0 : file, strerror(errno)));
841 : 0 : return false;
842 : : }
843 : : }
844 : :
845 : 1 : return true;
846 : : }
847 : :
848 : 1 : bool FileSerializer::ReadHeader(UnserialInfo* info)
849 : : {
850 : : uint32 magic;
851 : : uint16 version;
852 : : uint32 time;
853 : :
854 [ + - ][ + - ]: 1 : if ( read(fd, &magic, sizeof(magic)) != sizeof(magic ) ||
[ - + ][ - + ]
855 : : read(fd, &version, sizeof(version)) != sizeof(version) ||
856 : : read(fd, &time, sizeof(time)) != sizeof(time) )
857 : : {
858 : : Error(fmt("can't read file header from %s: %s",
859 : 0 : file, strerror(errno)));
860 : 0 : return false;
861 : : }
862 : :
863 : 1 : version = ntohs(version);
864 : 1 : time = ntohl(time);
865 : :
866 [ + - - + ]: 1 : if ( info && info->print )
867 : : {
868 : 0 : time_t teatime = (time_t) time;
869 : 0 : fprintf(stderr, "Date: %s", ctime(&teatime));
870 : : }
871 : :
872 [ - + ]: 1 : if ( magic != htonl(MAGIC) )
873 : : {
874 : 0 : Error(fmt("%s is not a bro state file", file));
875 : 0 : CloseFile();
876 : 0 : return false;
877 : : }
878 : :
879 [ - + ]: 1 : if ( version != DATA_FORMAT_VERSION )
880 : : {
881 : 0 : Error(fmt("wrong data format, expected version %d but got version %d", DATA_FORMAT_VERSION, version));
882 : 0 : CloseFile();
883 : 0 : return false;
884 : : }
885 : :
886 : 1 : return true;
887 : : }
888 : :
889 : 1 : bool FileSerializer::Read(UnserialInfo* info, const char* file, bool header)
890 : : {
891 [ - + ]: 1 : if ( ! OpenFile(file, true, info->print) )
892 : 0 : return false;
893 : :
894 : : // fprintf( stderr, "Reading %s\n", file );
895 : :
896 [ - + ]: 1 : if ( fd < 0 )
897 : : // Not existent, but that's ok.
898 : 0 : return true;
899 : :
900 [ + - ][ - + ]: 1 : if ( header && ! ReadHeader(info) )
[ - + ]
901 : 0 : return false;
902 : :
903 : : int i;
904 [ - + ]: 1 : while ( (i = Unserialize(info, true)) > 0 )
905 : : ;
906 : :
907 : 1 : CloseFile();
908 : :
909 : 1 : return i == 0;
910 : : }
911 : :
912 : 0 : void FileSerializer::ReportError(const char* str)
913 : : {
914 : 0 : run_time(str);
915 : 0 : }
916 : :
917 : 0 : void FileSerializer::GotID(ID* id, Val* val)
918 : : {
919 : : // Do nothing.
920 : 0 : Unref(id);
921 : 0 : }
922 : :
923 : 0 : void FileSerializer::GotStateAccess(StateAccess* s)
924 : : {
925 [ # # ]: 0 : delete s;
926 : 0 : }
927 : :
928 : : void FileSerializer::GotEvent(const char* name, double time,
929 : 0 : EventHandlerPtr event, val_list* args)
930 : : {
931 : : // Do nothing.
932 : 0 : delete_vals(args);
933 : 0 : }
934 : :
935 : : void FileSerializer::GotFunctionCall(const char* name, double time,
936 : 0 : Func* func, val_list* args)
937 : : {
938 : : // Do nothing.
939 : 0 : delete_vals(args);
940 : 0 : }
941 : :
942 : 0 : void FileSerializer::GotTimer(Timer* t)
943 : : {
944 : : // Do nothing.
945 [ # # ]: 0 : delete t;
946 : 0 : }
947 : :
948 : 0 : void FileSerializer::GotConnection(Connection* c)
949 : : {
950 : : // Do nothing.
951 : 0 : Unref(c);
952 : 0 : }
953 : :
954 : 0 : void FileSerializer::GotPacket(Packet* p)
955 : : {
956 : : // Do nothing.
957 [ # # ]: 0 : delete p;
958 : 0 : }
959 : :
960 : : ConversionSerializer::ConversionSerializer(SerializationFormat* in,
961 : 0 : SerializationFormat* out)
962 : 0 : : FileSerializer(in)
963 : : {
964 : 0 : serout = new FileSerializer(out);
965 : 0 : }
966 : :
967 : 0 : ConversionSerializer::~ConversionSerializer()
968 : : {
969 [ # # ][ # # ]: 0 : delete serout;
[ # # ]
970 [ # # ][ # # ]: 0 : }
[ # # ]
971 : :
972 : 0 : bool ConversionSerializer::Convert(const char* file_in, const char* file_out)
973 : : {
974 : 0 : internal_error("Error: Printing as XML is broken.");
975 : :
976 : : if ( ! serout->Open(file_out, true) )
977 : : return false;
978 : :
979 : : UnserialInfo info_in(this);
980 : : if ( ! Read(&info_in, file_in) )
981 : : return false;
982 : :
983 : : if ( ! serout->Close() )
984 : : return false;
985 : :
986 : : return true;
987 : : }
988 : :
989 : : void ConversionSerializer::GotEvent(const char* name, double time,
990 : 0 : EventHandlerPtr event, val_list* args)
991 : : {
992 : 0 : SerialInfo info(serout);
993 : 0 : serout->Serialize(&info, name, args);
994 : 0 : delete_vals(args);
995 : 0 : }
996 : :
997 : : void ConversionSerializer::GotFunctionCall(const char* name, double time,
998 : 0 : Func* func, val_list* args)
999 : : {
1000 : 0 : SerialInfo info(serout);
1001 : 0 : serout->Serialize(&info, name, args);
1002 : 0 : delete_vals(args);
1003 : 0 : }
1004 : :
1005 : 0 : void ConversionSerializer::GotID(ID* id, Val* val)
1006 : : {
1007 : 0 : warn("ConversionSerializer::GotID not implemented");
1008 : 0 : Unref(id);
1009 : 0 : }
1010 : :
1011 : 0 : void ConversionSerializer::GotStateAccess(StateAccess* s)
1012 : : {
1013 : 0 : warn("ConversionSerializer::GotID not implemented");
1014 [ # # ]: 0 : delete s;
1015 : 0 : }
1016 : :
1017 : 0 : void ConversionSerializer::GotPacket(Packet* p)
1018 : : {
1019 : 0 : warn("ConversionSerializer::GotPacket not implemented");
1020 [ # # ]: 0 : delete p;
1021 : 0 : }
1022 : :
1023 : 0 : EventPlayer::EventPlayer(const char* file)
1024 : : {
1025 [ # # # # ]: 0 : if ( ! OpenFile(file, true) || fd < 0 )
[ # # # # ]
[ # # ][ # # ]
1026 : 0 : Error(fmt("event replayer: cannot open %s", file));
1027 : :
1028 [ # # ][ # # ]: 0 : if ( ReadHeader() )
1029 : 0 : io_sources.Register(this);
1030 : 0 : }
1031 : :
1032 : 0 : EventPlayer::~EventPlayer()
1033 : : {
1034 : 0 : CloseFile();
1035 [ # # ][ # # ]: 0 : }
[ # # ]
1036 : :
1037 : : void EventPlayer::GotEvent(const char* name, double time,
1038 : 0 : EventHandlerPtr event, val_list* args)
1039 : : {
1040 : 0 : ne_time = time;
1041 : 0 : ne_handler = event;
1042 : 0 : ne_args = args;
1043 : 0 : }
1044 : :
1045 : : void EventPlayer::GotFunctionCall(const char* name, double time,
1046 : 0 : Func* func, val_list* args)
1047 : : {
1048 : : // We don't replay function calls.
1049 : 0 : }
1050 : :
1051 : 0 : void EventPlayer::GetFds(int* read, int* write, int* except)
1052 : : {
1053 : 0 : *read = fd;
1054 : 0 : }
1055 : :
1056 : 0 : double EventPlayer::NextTimestamp(double* local_network_time)
1057 : : {
1058 [ # # ]: 0 : if ( ne_time )
1059 : 0 : return ne_time;
1060 : :
1061 [ # # ]: 0 : if ( ! io )
1062 : 0 : return 0;
1063 : :
1064 : : // Read next event if we don't have one waiting.
1065 [ # # ]: 0 : if ( ! ne_time )
1066 : : {
1067 : 0 : UnserialInfo info(this);
1068 : 0 : Unserialize(&info);
1069 : 0 : closed = io->Eof();
1070 : : }
1071 : :
1072 [ # # ]: 0 : if ( ! ne_time )
1073 : 0 : return 0;
1074 : :
1075 [ # # ]: 0 : if ( ! network_time )
1076 : : {
1077 : : // Network time not initialized yet.
1078 : 0 : stream_time = replay_time = ne_time;
1079 : 0 : return ne_time;
1080 : : }
1081 : :
1082 [ # # ]: 0 : if ( ! stream_time )
1083 : : {
1084 : : // Init base times.
1085 : 0 : stream_time = ne_time;
1086 : 0 : replay_time = network_time;
1087 : : }
1088 : :
1089 : : // Scale time.
1090 : 0 : ne_time = ne_time - stream_time + network_time;
1091 : 0 : return ne_time;
1092 : : }
1093 : :
1094 : 0 : void EventPlayer::Process()
1095 : : {
1096 [ # # ][ # # ]: 0 : if ( ! (io && ne_time) )
1097 : 0 : return;
1098 : :
1099 : 0 : Event* event = new Event(ne_handler, ne_args);
1100 : 0 : mgr.Dispatch(event);
1101 : :
1102 : 0 : ne_time = 0;
1103 : : }
1104 : :
1105 : 0 : void Packet::Describe(ODesc* d) const
1106 : : {
1107 : 0 : const IP_Hdr ip = IP();
1108 : 0 : d->Add(dotted_addr(ip.SrcAddr()));
1109 : 0 : d->Add("->");
1110 : 0 : d->Add(dotted_addr(ip.DstAddr()));
1111 : 0 : }
1112 : :
1113 : 0 : bool Packet::Serialize(SerialInfo* info) const
1114 : : {
1115 : : return SERIALIZE(uint32(hdr->ts.tv_sec)) &&
1116 : : SERIALIZE(uint32(hdr->ts.tv_usec)) &&
1117 : : SERIALIZE(uint32(hdr->len)) &&
1118 : : SERIALIZE(link_type) &&
1119 : : info->s->Write(tag.c_str(), 0, "tag") &&
1120 [ # # ][ # # ]: 0 : info->s->Write((const char*) pkt, hdr->caplen, "data");
[ # # ][ # # ]
[ # # ][ # # ]
1121 : : }
1122 : :
1123 : : static BroFile* profiling_output = 0;
1124 : :
1125 : : #ifdef DEBUG
1126 : : static PktDumper* dump = 0;
1127 : : #endif
1128 : :
1129 : 0 : Packet* Packet::Unserialize(UnserialInfo* info)
1130 : : {
1131 : 0 : Packet* p = new Packet("", true);
1132 : 0 : pcap_pkthdr* hdr = new pcap_pkthdr;
1133 : :
1134 : : uint32 tv_sec, tv_usec, len;
1135 : :
1136 [ # # # # ]: 0 : if ( ! (UNSERIALIZE(&tv_sec) &&
[ # # ][ # # ]
[ # # ]
1137 : : UNSERIALIZE(&tv_usec) &&
1138 : : UNSERIALIZE(&len) &&
1139 : : UNSERIALIZE(&p->link_type)) )
1140 : 0 : return 0;
1141 : :
1142 : 0 : hdr->ts.tv_sec = tv_sec;
1143 : 0 : hdr->ts.tv_usec = tv_usec;
1144 : 0 : hdr->len = len;
1145 : :
1146 : : char* tag;
1147 [ # # ]: 0 : if ( ! info->s->Read((char**) &tag, 0, "tag") )
1148 : 0 : return 0;
1149 : :
1150 : : u_char* pkt;
1151 : : int caplen;
1152 [ # # ]: 0 : if ( ! info->s->Read((char**) &pkt, &caplen, "data") )
1153 : : {
1154 [ # # ]: 0 : delete [] tag;
1155 : 0 : return 0;
1156 : : }
1157 : :
1158 : 0 : hdr->caplen = uint32(caplen);
1159 : 0 : p->hdr = hdr;
1160 : 0 : p->pkt = pkt;
1161 : 0 : p->tag = tag;
1162 : 0 : p->hdr_size = get_link_header_size(p->link_type);
1163 : :
1164 [ # # ]: 0 : delete [] tag;
1165 : :
1166 : : // For the global timer manager, we take the global network_time as the
1167 : : // packet's timestamp for feeding it into our packet loop.
1168 [ # # ]: 0 : if ( p->tag == "" )
1169 : 0 : p->time = timer_mgr->Time();
1170 : : else
1171 : 0 : p->time = p->hdr->ts.tv_sec + double(p->hdr->ts.tv_usec) / 1e6;
1172 : :
1173 [ # # ]: 0 : if ( time_machine_profiling )
1174 : : {
1175 [ # # ]: 0 : if ( ! profiling_output )
1176 : : profiling_output =
1177 : 0 : new BroFile("tm-prof.packets.log", "w");
1178 : :
1179 : : profiling_output->Write(fmt("%.6f %s %d\n", current_time(),
1180 [ # # ]: 0 : (p->tag != "" ? p->tag.c_str() : "-"), hdr->len));
1181 : : }
1182 : :
1183 : : #ifdef DEBUG
1184 [ # # ]: 0 : if ( debug_logger.IsEnabled(DBG_TM) )
1185 : : {
1186 [ # # ]: 0 : if ( ! dump )
1187 : 0 : dump = new PktDumper("tm.pcap");
1188 : :
1189 : 0 : dump->Dump(p->hdr, p->pkt);
1190 : : }
1191 : : #endif
1192 : :
1193 : 0 : return p;
1194 [ + - ][ + - ]: 6 : }
|