LCOV - code coverage report
Current view: top level - src - Serializer.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 197 614 32.1 %
Date: 2010-12-13 Functions: 23 79 29.1 %
Branches: 95 471 20.2 %

           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 :         }

Generated by: LCOV version 1.8