LCOV - code coverage report
Current view: top level - src - Conn.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 203 500 40.6 %
Date: 2010-12-13 Functions: 28 59 47.5 %
Branches: 62 512 12.1 %

           Branch data     Line data    Source code
       1                 :            : // $Id: Conn.cc 6219 2008-10-01 05:39:07Z vern $
       2                 :            : //
       3                 :            : // See the file "COPYING" in the main distribution directory for copyright.
       4                 :            : 
       5                 :            : #include "config.h"
       6                 :            : 
       7                 :            : #include <ctype.h>
       8                 :            : 
       9                 :            : #include "Net.h"
      10                 :            : #include "NetVar.h"
      11                 :            : #include "Conn.h"
      12                 :            : #include "Event.h"
      13                 :            : #include "Sessions.h"
      14                 :            : #include "Logger.h"
      15                 :            : #include "Timer.h"
      16                 :            : #include "PIA.h"
      17                 :            : #include "binpac.h"
      18                 :            : 
      19                 :      20278 : HashKey* ConnID::BuildConnKey() const
      20                 :            :         {
      21                 :            :         Key key;
      22                 :            : 
      23                 :            :         // Lookup up connection based on canonical ordering, which is
      24                 :            :         // the smaller of <src addr, src port> and <dst addr, dst port>
      25                 :            :         // followed by the other.
      26 [ +  + ][ +  + ]:      20278 :         if ( is_one_way ||
                 [ +  + ]
      27                 :            :              addr_port_canon_lt(src_addr, src_port, dst_addr, dst_port) )
      28                 :            :                 {
      29                 :      11326 :                 copy_addr(src_addr, key.ip1);
      30                 :      11326 :                 copy_addr(dst_addr, key.ip2);
      31                 :      11326 :                 key.port1 = src_port;
      32                 :      11326 :                 key.port2 = dst_port;
      33                 :            :                 }
      34                 :            :         else
      35                 :            :                 {
      36                 :       8952 :                 copy_addr(dst_addr, key.ip1);
      37                 :       8952 :                 copy_addr(src_addr, key.ip2);
      38                 :       8952 :                 key.port1 = dst_port;
      39                 :       8952 :                 key.port2 = src_port;
      40                 :            :                 }
      41                 :            : 
      42                 :      20278 :         return new HashKey(&key, sizeof(key));
      43                 :            :         }
      44                 :            : 
      45                 :            : void ConnectionTimer::Init(Connection* arg_conn, timer_func arg_timer,
      46                 :       2048 :                                 int arg_do_expire)
      47                 :            :         {
      48                 :       2048 :         conn = arg_conn;
      49                 :       2048 :         timer = arg_timer;
      50                 :       2048 :         do_expire = arg_do_expire;
      51                 :       2048 :         Ref(conn);
      52                 :       2048 :         }
      53                 :            : 
      54                 :       2048 : ConnectionTimer::~ConnectionTimer()
      55                 :            :         {
      56 [ -  + ][ #  # ]:       2048 :         if ( conn->RefCnt() < 1 )
                 [ #  # ]
      57                 :          0 :                 internal_error("reference count inconsistency in ~ConnectionTimer");
      58                 :            : 
      59                 :       2048 :         conn->RemoveTimer(this);
      60                 :       2048 :         Unref(conn);
      61 [ +  - ][ #  # ]:       2048 :         }
                 [ #  # ]
      62                 :            : 
      63                 :       1509 : void ConnectionTimer::Dispatch(double t, int is_expire)
      64                 :            :         {
      65 [ +  + ][ -  + ]:       1509 :         if ( is_expire && ! do_expire )
      66                 :       1509 :                 return;
      67                 :            : 
      68                 :            :         // Remove ourselves from the connection's set of timers so
      69                 :            :         // it doesn't try to cancel us.
      70                 :       1506 :         conn->RemoveTimer(this);
      71                 :            : 
      72         [ -  + ]:       1506 :         (conn->*timer)(t);
      73                 :            : 
      74         [ -  + ]:       1506 :         if ( conn->RefCnt() < 1 )
      75                 :          0 :                 internal_error("reference count inconsistency in ConnectionTimer::Dispatch");
      76                 :            :         }
      77                 :            : 
      78                 :          3 : IMPLEMENT_SERIAL(ConnectionTimer, SER_CONNECTION_TIMER);
      79                 :            : 
      80                 :          0 : bool ConnectionTimer::DoSerialize(SerialInfo* info) const
      81                 :            :         {
      82 [ #  # ][ #  # ]:          0 :         DO_SERIALIZE(SER_CONNECTION_TIMER, Timer);
      83                 :            : 
      84                 :            :         // We enumerate all the possible timer functions here ... This
      85                 :            :         // has to match the list is DoUnserialize()!
      86                 :          0 :         char type = 0;
      87                 :            : 
      88 [ #  # ][ #  # ]:          0 :         if ( timer == timer_func(&Connection::DeleteTimer) )
                 [ #  # ]
      89                 :          0 :                 type = 1;
      90 [ #  # ][ #  # ]:          0 :         else if ( timer == timer_func(&Connection::InactivityTimer) )
                 [ #  # ]
      91                 :          0 :                 type = 2;
      92 [ #  # ][ #  # ]:          0 :         else if ( timer == timer_func(&Connection::StatusUpdateTimer) )
                 [ #  # ]
      93                 :          0 :                 type = 3;
      94 [ #  # ][ #  # ]:          0 :         else if ( timer == timer_func(&Connection::RemoveConnectionTimer) )
                 [ #  # ]
      95                 :          0 :                 type = 4;
      96                 :            :         else
      97                 :          0 :                 internal_error("unknown function in ConnectionTimer::DoSerialize()");
      98                 :            : 
      99 [ #  # ][ #  # ]:          0 :         return conn->Serialize(info) && SERIALIZE(type) && SERIALIZE(do_expire);
                 [ #  # ]
     100                 :            :         }
     101                 :            : 
     102                 :          0 : bool ConnectionTimer::DoUnserialize(UnserialInfo* info)
     103                 :            :         {
     104         [ #  # ]:          0 :         DO_UNSERIALIZE(Timer);
     105                 :            : 
     106                 :          0 :         conn = Connection::Unserialize(info);
     107         [ #  # ]:          0 :         if ( ! conn )
     108                 :          0 :                 return false;
     109                 :            : 
     110                 :            :         char type;
     111                 :            : 
     112 [ #  # ][ #  # ]:          0 :         if ( ! UNSERIALIZE(&type) || ! UNSERIALIZE(&do_expire) )
                 [ #  # ]
     113                 :          0 :                 return false;
     114                 :            : 
     115   [ #  #  #  #  :          0 :         switch ( type ) {
                      # ]
     116                 :            :         case 1:
     117                 :          0 :                 timer = timer_func(&Connection::DeleteTimer);
     118                 :          0 :                 break;
     119                 :            :         case 2:
     120                 :          0 :                 timer = timer_func(&Connection::InactivityTimer);
     121                 :          0 :                 break;
     122                 :            :         case 3:
     123                 :          0 :                 timer = timer_func(&Connection::StatusUpdateTimer);
     124                 :          0 :                 break;
     125                 :            :         case 4:
     126                 :          0 :                 timer = timer_func(&Connection::RemoveConnectionTimer);
     127                 :          0 :                 break;
     128                 :            :         default:
     129                 :          0 :                 info->s->Error("unknown connection timer function");
     130                 :          0 :                 return false;
     131                 :            :         }
     132                 :            : 
     133                 :          0 :         return true;
     134                 :            :         }
     135                 :            : 
     136                 :            : unsigned int Connection::total_connections = 0;
     137                 :            : unsigned int Connection::current_connections = 0;
     138                 :            : unsigned int Connection::external_connections = 0;
     139                 :            : 
     140                 :          3 : IMPLEMENT_SERIAL(Connection, SER_CONNECTION);
     141                 :            : 
     142                 :       1627 : Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id)
     143                 :            :         {
     144                 :       1627 :         sessions = s;
     145                 :       1627 :         key = k;
     146                 :       1627 :         start_time = last_time = t;
     147                 :            : 
     148                 :       1627 :         copy_addr(id->src_addr, orig_addr);
     149                 :       1627 :         copy_addr(id->dst_addr, resp_addr);
     150                 :       1627 :         orig_port = id->src_port;
     151                 :       1627 :         resp_port = id->dst_port;
     152                 :       1627 :         proto = TRANSPORT_UNKNOWN;
     153                 :            : 
     154                 :       1627 :         conn_val = 0;
     155                 :       1627 :         orig_endp = resp_endp = 0;
     156                 :       1627 :         login_conn = 0;
     157                 :            : 
     158                 :       1627 :         is_active = 1;
     159                 :       1627 :         skip = 0;
     160                 :       1627 :         weird = 0;
     161                 :       1627 :         persistent = 0;
     162                 :            : 
     163                 :       1627 :         suppress_event = 0;
     164                 :            : 
     165                 :       1627 :         record_contents = record_packets = 1;
     166                 :            : 
     167                 :       1627 :         timers_canceled = 0;
     168                 :       1627 :         inactivity_timeout = 0;
     169                 :       1627 :         installed_status_timer = 0;
     170                 :            : 
     171                 :       1627 :         finished = 0;
     172                 :            : 
     173                 :       1627 :         hist_seen = 0;
     174                 :       1627 :         history = "";
     175                 :            : 
     176                 :       1627 :         root_analyzer = 0;
     177                 :       1627 :         primary_PIA = 0;
     178                 :            : 
     179                 :       1627 :         ++current_connections;
     180                 :       1627 :         ++total_connections;
     181                 :            : 
     182                 :       1627 :         TimerMgr::Tag* tag = current_iosrc->GetCurrentTag();
     183 [ -  + ][ #  # ]:       1627 :         conn_timer_mgr = tag ? new TimerMgr::Tag(*tag) : 0;
     184                 :            : 
     185 [ -  + ][ #  # ]:       1627 :         if ( conn_timer_mgr )
     186                 :            :                 {
     187                 :          0 :                 ++external_connections;
     188                 :            :                 // We schedule a timer which removes this connection from memory
     189                 :            :                 // indefinitively into the future. Ii will expire when the timer
     190                 :            :                 // mgr is drained but not before.
     191                 :          0 :                 ADD_TIMER(&Connection::RemoveConnectionTimer, 1e20, 1,
     192                 :            :                                 TIMER_REMOVE_CONNECTION);
     193                 :            :                 }
     194                 :       1627 :         }
     195                 :            : 
     196                 :       1627 : Connection::~Connection()
     197                 :            :         {
     198 [ -  + ][ #  # ]:       1627 :         if ( ! finished )
                 [ #  # ]
     199                 :          0 :                 internal_error("Done() not called before destruction of Connection");
     200                 :            : 
     201                 :       1627 :         CancelTimers();
     202                 :            : 
     203 [ +  -  #  #  # :       1627 :         if ( conn_val )
                      # ]
     204                 :            :                 {
     205                 :       1627 :                 conn_val->SetOrigin(0);
     206                 :       1627 :                 Unref(conn_val);
     207                 :            :                 }
     208                 :            : 
     209 [ +  + ][ #  # ]:       1627 :         delete key;
                 [ #  # ]
     210 [ +  - ][ #  # ]:       1627 :         delete root_analyzer;
                 [ #  # ]
     211 [ -  + ][ #  # ]:       1627 :         delete conn_timer_mgr;
                 [ #  # ]
     212                 :            : 
     213                 :       1627 :         --current_connections;
     214 [ -  + ][ #  # ]:       1627 :         if ( conn_timer_mgr )
                 [ #  # ]
     215                 :          0 :                 --external_connections;
     216 [ +  - ][ #  # ]:       1627 :         }
                 [ #  # ]
     217                 :            : 
     218                 :       1627 : void Connection::Done()
     219                 :            :         {
     220                 :       1627 :         finished = 1;
     221                 :            : 
     222 [ +  - ][ +  - ]:       1627 :         if ( root_analyzer && ! root_analyzer->IsFinished() )
                 [ +  - ]
     223                 :       1627 :                 root_analyzer->Done();
     224                 :       1627 :         }
     225                 :            : 
     226                 :            : void Connection::NextPacket(double t, int is_orig,
     227                 :            :                         const IP_Hdr* ip, int len, int caplen,
     228                 :            :                         const u_char*& data,
     229                 :            :                         int& record_packet, int& record_content,
     230                 :            :                         // arguments for reproducing packets
     231                 :            :                         const struct pcap_pkthdr* hdr,
     232                 :            :                         const u_char* const pkt,
     233                 :      19690 :                         int hdr_size)
     234                 :            :         {
     235                 :      19690 :         current_hdr = hdr;
     236                 :      19690 :         current_hdr_size = hdr_size;
     237                 :      19690 :         current_timestamp = t;
     238                 :      19690 :         current_pkt = pkt;
     239                 :            : 
     240         [ -  + ]:      19690 :         if ( Skipping() )
     241                 :          0 :                 return;
     242                 :            : 
     243         [ +  - ]:      19690 :         if ( root_analyzer )
     244                 :            :                 {
     245                 :      19690 :                 record_current_packet = record_packet;
     246                 :      19690 :                 record_current_content = record_content;
     247                 :      19690 :                 root_analyzer->NextPacket(len, data, is_orig, -1, ip, caplen);
     248                 :      19690 :                 record_packet = record_current_packet;
     249                 :      19690 :                 record_content = record_current_content;
     250                 :            :                 }
     251                 :            :         else
     252                 :          0 :                 last_time = t;
     253                 :            : 
     254                 :      19690 :         current_hdr = 0;
     255                 :      19690 :         current_hdr_size = 0;
     256                 :      19690 :         current_timestamp = 0;
     257                 :      19690 :         current_pkt = 0;
     258                 :            :         }
     259                 :            : 
     260                 :          0 : void Connection::SetLifetime(double lifetime)
     261                 :            :         {
     262                 :          0 :         ADD_TIMER(&Connection::DeleteTimer, network_time + lifetime, 0,
     263                 :            :                         TIMER_CONN_DELETE);
     264                 :          0 :         }
     265                 :            : 
     266                 :      17553 : bool Connection::IsReuse(double t, const u_char* pkt)
     267                 :            :         {
     268 [ +  - ][ +  + ]:      17553 :         return root_analyzer && root_analyzer->IsReuse(t, pkt);
     269                 :            :         }
     270                 :            : 
     271                 :        502 : void Connection::DeleteTimer(double /* t */)
     272                 :            :         {
     273         [ +  - ]:        502 :         if ( is_active )
     274                 :        502 :                 Event(connection_timeout, 0);
     275                 :            : 
     276                 :        502 :         sessions->Remove(this);
     277                 :        502 :         }
     278                 :            : 
     279                 :       1506 : void Connection::InactivityTimer(double t)
     280                 :            :         {
     281                 :            :         // If the inactivity_timeout is zero, there has been an active
     282                 :            :         // timeout once, but it's disabled now. We do nothing then.
     283         [ +  - ]:       1506 :         if ( inactivity_timeout )
     284                 :            :                 {
     285         [ +  + ]:       1506 :                 if ( last_time + inactivity_timeout <= t )
     286                 :            :                         {
     287                 :       1074 :                         Event(connection_timeout, 0);
     288                 :       1074 :                         sessions->Remove(this);
     289                 :       1074 :                         ++killed_by_inactivity;
     290                 :            :                         }
     291                 :            :                 else
     292                 :        432 :                         ADD_TIMER(&Connection::InactivityTimer,
     293                 :            :                                         last_time + inactivity_timeout, 0,
     294                 :            :                                         TIMER_CONN_INACTIVITY);
     295                 :            :                 }
     296                 :       1506 :         }
     297                 :            : 
     298                 :          0 : void Connection::RemoveConnectionTimer(double t)
     299                 :            :         {
     300                 :          0 :         Event(connection_state_remove, 0);
     301                 :          0 :         sessions->Remove(this);
     302                 :          0 :         }
     303                 :            : 
     304                 :       1616 : void Connection::SetInactivityTimeout(double timeout)
     305                 :            :         {
     306                 :            :         // We add a new inactivity timer even if there already is one.  When
     307                 :            :         // it fires, we always use the current value to check for inactivity.
     308         [ +  - ]:       1616 :         if ( timeout )
     309                 :       1616 :                 ADD_TIMER(&Connection::InactivityTimer,
     310                 :            :                                 last_time + timeout, 0, TIMER_CONN_INACTIVITY);
     311                 :            : 
     312                 :       1616 :         inactivity_timeout = timeout;
     313                 :       1616 :         }
     314                 :            : 
     315                 :       1722 : void Connection::EnableStatusUpdateTimer()
     316                 :            :         {
     317 [ -  + ][ #  # ]:       1722 :         if ( connection_status_update && connection_status_update_interval )
                 [ -  + ]
     318                 :            :                 {
     319                 :          0 :                 ADD_TIMER(&Connection::StatusUpdateTimer,
     320                 :            :                         network_time + connection_status_update_interval, 0,
     321                 :            :                         TIMER_CONN_STATUS_UPDATE);
     322                 :          0 :                 installed_status_timer = 1;
     323                 :            :                 }
     324                 :       1722 :         }
     325                 :            : 
     326                 :          0 : void Connection::StatusUpdateTimer(double t)
     327                 :            :         {
     328                 :          0 :         val_list* vl = new val_list(1);
     329                 :          0 :         vl->append(BuildConnVal());
     330                 :          0 :         ConnectionEvent(connection_status_update, 0, vl);
     331                 :          0 :         ADD_TIMER(&Connection::StatusUpdateTimer,
     332                 :            :                         network_time + connection_status_update_interval, 0,
     333                 :            :                         TIMER_CONN_STATUS_UPDATE);
     334                 :          0 :         }
     335                 :            : 
     336                 :      17023 : RecordVal* Connection::BuildConnVal()
     337                 :            :         {
     338         [ +  + ]:      17023 :         if ( ! conn_val )
     339                 :            :                 {
     340                 :       1627 :                 conn_val = new RecordVal(connection_type);
     341                 :            : 
     342                 :       1627 :                 TransportProto prot_type = ConnTransport();
     343                 :            : 
     344                 :       1627 :                 RecordVal* id_val = new RecordVal(conn_id);
     345                 :       1627 :                 id_val->Assign(0, new AddrVal(orig_addr));
     346                 :       1627 :                 id_val->Assign(1, new PortVal(ntohs(orig_port), prot_type));
     347                 :       1627 :                 id_val->Assign(2, new AddrVal(resp_addr));
     348                 :       1627 :                 id_val->Assign(3, new PortVal(ntohs(resp_port), prot_type));
     349                 :       1627 :                 conn_val->Assign(0, id_val);
     350                 :            : 
     351                 :       1627 :                 orig_endp = new RecordVal(endpoint);
     352                 :       1627 :                 orig_endp->Assign(0, new Val(0, TYPE_COUNT));
     353                 :       1627 :                 orig_endp->Assign(1, new Val(0, TYPE_COUNT));
     354                 :       1627 :                 conn_val->Assign(1, orig_endp);
     355                 :            : 
     356                 :       1627 :                 resp_endp = new RecordVal(endpoint);
     357                 :       1627 :                 resp_endp->Assign(0, new Val(0, TYPE_COUNT));
     358                 :       1627 :                 resp_endp->Assign(1, new Val(0, TYPE_COUNT));
     359                 :       1627 :                 conn_val->Assign(2, resp_endp);
     360                 :            : 
     361                 :            :                 // conn_val->Assign(3, new Val(start_time, TYPE_TIME));      // ###
     362                 :       1627 :                 conn_val->Assign(5, new TableVal(string_set));       // service
     363                 :       1627 :                 conn_val->Assign(6, new StringVal(""));    // addl
     364                 :       1627 :                 conn_val->Assign(7, new Val(0, TYPE_COUNT)); // hot
     365                 :       1627 :                 conn_val->Assign(8, new StringVal(""));    // history
     366                 :            :                 }
     367                 :            : 
     368         [ +  - ]:      17023 :         if ( root_analyzer )
     369                 :            :                 {
     370                 :      17023 :                 root_analyzer->UpdateEndpointVal(orig_endp, 1);
     371                 :      17023 :                 root_analyzer->UpdateEndpointVal(resp_endp, 0);
     372                 :            :                 }
     373                 :            : 
     374                 :      17023 :         conn_val->Assign(3, new Val(start_time, TYPE_TIME)); // ###
     375                 :      17023 :         conn_val->Assign(4, new Val(last_time - start_time, TYPE_INTERVAL));
     376                 :      17023 :         conn_val->Assign(8, new StringVal(history.c_str()));
     377                 :            : 
     378                 :      17023 :         conn_val->SetOrigin(this);
     379                 :            : 
     380                 :      17023 :         Ref(conn_val);
     381                 :            : 
     382                 :      17023 :         return conn_val;
     383                 :            :         }
     384                 :            : 
     385                 :          0 : Analyzer* Connection::FindAnalyzer(AnalyzerID id)
     386                 :            :         {
     387         [ #  # ]:          0 :         return root_analyzer ? root_analyzer->FindChild(id) : 0;
     388                 :            :         }
     389                 :            : 
     390                 :          8 : Analyzer* Connection::FindAnalyzer(AnalyzerTag::Tag tag)
     391                 :            :         {
     392         [ +  - ]:          8 :         return root_analyzer ? root_analyzer->FindChild(tag) : 0;
     393                 :            :         }
     394                 :            : 
     395                 :          0 : void Connection::AppendAddl(const char* str)
     396                 :            :         {
     397                 :          0 :         Unref(BuildConnVal());
     398                 :            : 
     399                 :          0 :         const char* old = conn_val->Lookup(6)->AsString()->CheckString();
     400         [ #  # ]:          0 :         const char* format = *old ? "%s %s" : "%s%s";
     401                 :            : 
     402                 :          0 :         conn_val->Assign(6, new StringVal(fmt(format, old, str)));
     403                 :          0 :         }
     404                 :            : 
     405                 :            : // Returns true if the character at s separates a version number.
     406                 :          0 : static inline bool is_version_sep(const char* s, const char* end)
     407                 :            :         {
     408                 :            :         return
     409                 :            :                 // foo-1.2.3
     410                 :            :                         (s < end - 1 && ispunct(s[0]) && isdigit(s[1])) ||
     411                 :            :                 // foo-v1.2.3
     412                 :            :                         (s < end - 2 && ispunct(s[0]) &&
     413                 :            :                          tolower(s[1]) == 'v' && isdigit(s[2])) ||
     414                 :            :                 // foo 1.2.3
     415 [ #  # ][ #  # ]:          0 :                         isspace(s[0]);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     416                 :            :         }
     417                 :            : 
     418                 :      26764 : void Connection::Match(Rule::PatternType type, const u_char* data, int len, bool is_orig, bool bol, bool eol, bool clear_state)
     419                 :            :         {
     420         [ +  - ]:      26764 :         if ( primary_PIA )
     421                 :      26764 :                 primary_PIA->Match(type, data, len, is_orig, bol, eol, clear_state);
     422                 :      26764 :         }
     423                 :            : 
     424                 :          0 : Val* Connection::BuildVersionVal(const char* s, int len)
     425                 :            :         {
     426                 :          0 :         Val* name = 0;
     427                 :          0 :         Val* major = 0;
     428                 :          0 :         Val* minor = 0;
     429                 :          0 :         Val* minor2 = 0;
     430                 :          0 :         Val* addl = 0;
     431                 :            : 
     432                 :          0 :         const char* last = s + len;
     433                 :          0 :         const char* e = s;
     434                 :            : 
     435                 :            :         // This is all just a guess...
     436                 :            : 
     437                 :            :         // Eat non-alpha-numerical chars.
     438 [ #  # ][ #  # ]:          0 :         for ( ; s < last && ! isalnum(*s); ++s )
     439                 :            :                 ;
     440                 :            : 
     441                 :            :         // Leading characters are the program name.
     442                 :            :         // (first character must not be a digit)
     443         [ #  # ]:          0 :         if ( isalpha(*s) )
     444                 :            :                 {
     445 [ #  # ][ #  # ]:          0 :                 for ( e = s; e < last && ! is_version_sep(e, last); ++e )
                 [ #  # ]
     446                 :            :                         ;
     447                 :            : 
     448         [ #  # ]:          0 :                 if ( s != e )
     449                 :          0 :                         name = new StringVal(e - s, s);
     450                 :            :                 }
     451                 :            : 
     452                 :            :         // Find first number - that's the major version.
     453 [ #  # ][ #  # ]:          0 :         for ( s = e; s < last && ! isdigit(*s); ++s )
     454                 :            :                 ;
     455 [ #  # ][ #  # ]:          0 :         for ( e = s; e < last && isdigit(*e); ++e )
     456                 :            :                 ;
     457                 :            : 
     458         [ #  # ]:          0 :         if ( s != e )
     459                 :          0 :                 major = new Val(atoi(s), TYPE_INT);
     460                 :            : 
     461                 :            :         // Find second number seperated only by punctuation chars -
     462                 :            :         // that's the minor version.
     463 [ #  # ][ #  # ]:          0 :         for ( s = e; s < last && ispunct(*s); ++s )
     464                 :            :                 ;
     465 [ #  # ][ #  # ]:          0 :         for ( e = s; e < last && isdigit(*e); ++e )
     466                 :            :                 ;
     467                 :            : 
     468         [ #  # ]:          0 :         if ( s != e )
     469                 :          0 :                 minor = new Val(atoi(s), TYPE_INT);
     470                 :            : 
     471                 :            :         // Find second number seperated only by punctuation chars; -
     472                 :            :         // that's the minor version.
     473 [ #  # ][ #  # ]:          0 :         for ( s = e; s < last && ispunct(*s); ++s )
     474                 :            :                 ;
     475 [ #  # ][ #  # ]:          0 :         for ( e = s; e < last && isdigit(*e); ++e )
     476                 :            :                 ;
     477                 :            : 
     478         [ #  # ]:          0 :         if ( s != e )
     479                 :          0 :                 minor2 = new Val(atoi(s), TYPE_INT);
     480                 :            : 
     481                 :            :         // Anything after following punctuation and until next white space is
     482                 :            :         // an additional version string.
     483 [ #  # ][ #  # ]:          0 :         for ( s = e; s < last && ispunct(*s); ++s )
     484                 :            :                 ;
     485 [ #  # ][ #  # ]:          0 :         for ( e = s; e < last && ! isspace(*e); ++e )
     486                 :            :                 ;
     487                 :            : 
     488         [ #  # ]:          0 :         if ( s != e )
     489                 :          0 :                 addl = new StringVal(e - s, s);
     490                 :            : 
     491                 :            :         // If we do not have a name yet, the next alphanumerical string is it.
     492         [ #  # ]:          0 :         if ( ! name )
     493                 :            :                 { // eat non-alpha-numerical characters
     494 [ #  # ][ #  # ]:          0 :                 for ( s = e; s < last && ! isalpha(*s); ++s )
     495                 :            :                         ;
     496                 :            : 
     497                 :            :                 // Get name.
     498 [ #  # ][ #  # ]:          0 :                 for ( e = s; e < last && (isalnum(*e) || *e == '_'); ++e )
                 [ #  # ]
     499                 :            :                         ;
     500                 :            : 
     501         [ #  # ]:          0 :                 if ( s != e )
     502                 :          0 :                         name = new StringVal(e - s, s);
     503                 :            :                 }
     504                 :            : 
     505                 :            :         // We need at least a name.
     506         [ #  # ]:          0 :         if ( ! name )
     507                 :          0 :                 return 0;
     508                 :            : 
     509                 :          0 :         RecordVal* version = new RecordVal(software_version);
     510         [ #  # ]:          0 :         version->Assign(0, major ? major : new Val(-1, TYPE_INT));
     511         [ #  # ]:          0 :         version->Assign(1, minor ? minor : new Val(-1, TYPE_INT));
     512         [ #  # ]:          0 :         version->Assign(2, minor2 ? minor2 : new Val(-1, TYPE_INT));
     513         [ #  # ]:          0 :         version->Assign(3, addl ? addl : new StringVal(""));
     514                 :            : 
     515                 :          0 :         RecordVal* sw = new RecordVal(software);
     516                 :          0 :         sw->Assign(0, name);
     517                 :          0 :         sw->Assign(1, version);
     518                 :            : 
     519                 :          0 :         return sw;
     520                 :            :         }
     521                 :            : 
     522                 :            : int Connection::VersionFoundEvent(const uint32* addr, const char* s, int len,
     523                 :          0 :                                         Analyzer* analyzer)
     524                 :            :         {
     525 [ #  # ][ #  # ]:          0 :         if ( ! software_version_found && ! software_parse_error )
                 [ #  # ]
     526                 :          0 :                 return 1;
     527                 :            : 
     528         [ #  # ]:          0 :         if ( ! is_printable(s, len) )
     529                 :          0 :                 return 0;
     530                 :            : 
     531                 :          0 :         Val* val = BuildVersionVal(s, len);
     532         [ #  # ]:          0 :         if ( ! val )
     533                 :            :                 {
     534         [ #  # ]:          0 :                 if ( software_parse_error )
     535                 :            :                         {
     536                 :          0 :                         val_list* vl = new val_list;
     537                 :          0 :                         vl->append(BuildConnVal());
     538                 :          0 :                         vl->append(new AddrVal(addr));
     539                 :          0 :                         vl->append(new StringVal(len, s));
     540                 :          0 :                         ConnectionEvent(software_parse_error, analyzer, vl);
     541                 :            :                         }
     542                 :          0 :                 return 0;
     543                 :            :                 }
     544                 :            : 
     545         [ #  # ]:          0 :         if ( software_version_found )
     546                 :            :                 {
     547                 :          0 :                 val_list* vl = new val_list;
     548                 :          0 :                 vl->append(BuildConnVal());
     549                 :          0 :                 vl->append(new AddrVal(addr));
     550                 :          0 :                 vl->append(val);
     551                 :          0 :                 vl->append(new StringVal(len, s));
     552                 :          0 :                 ConnectionEvent(software_version_found, 0, vl);
     553                 :            :                 }
     554                 :            :         else
     555                 :          0 :                 Unref(val);
     556                 :            : 
     557                 :          0 :         return 1;
     558                 :            :         }
     559                 :            : 
     560                 :            : int Connection::UnparsedVersionFoundEvent(const uint32* addr,
     561                 :          0 :                                         const char* full, int len, Analyzer* analyzer)
     562                 :            :         {
     563                 :            :         // Skip leading white space.
     564 [ #  # ][ #  # ]:          0 :         while ( len && isspace(*full) )
     565                 :            :                 {
     566                 :          0 :                 --len;
     567                 :          0 :                 ++full;
     568                 :            :                 }
     569                 :            : 
     570         [ #  # ]:          0 :         if ( ! is_printable(full, len) )
     571                 :          0 :                 return 0;
     572                 :            : 
     573         [ #  # ]:          0 :         if ( software_unparsed_version_found )
     574                 :            :                 {
     575                 :          0 :                 val_list* vl = new val_list;
     576                 :          0 :                 vl->append(BuildConnVal());
     577                 :          0 :                 vl->append(new AddrVal(addr));
     578                 :          0 :                 vl->append(new StringVal(len, full));
     579                 :          0 :                 ConnectionEvent(software_unparsed_version_found, analyzer, vl);
     580                 :            :                 }
     581                 :            : 
     582                 :          0 :         return 1;
     583                 :            :         }
     584                 :            : 
     585                 :       8713 : void Connection::Event(EventHandlerPtr f, Analyzer* analyzer, const char* name)
     586                 :            :         {
     587         [ +  + ]:       8713 :         if ( ! f )
     588                 :       3728 :                 return;
     589                 :            : 
     590                 :       4985 :         val_list* vl = new val_list(2);
     591         [ +  + ]:       4985 :         if ( name )
     592                 :        433 :                 vl->append(new StringVal(name));
     593                 :       4985 :         vl->append(BuildConnVal());
     594                 :            : 
     595                 :       8713 :         ConnectionEvent(f, analyzer, vl);
     596                 :            :         }
     597                 :            : 
     598                 :          0 : void Connection::Event(EventHandlerPtr f, Analyzer* analyzer, Val* v1, Val* v2)
     599                 :            :         {
     600         [ #  # ]:          0 :         if ( ! f )
     601                 :            :                 {
     602                 :          0 :                 Unref(v1);
     603                 :          0 :                 Unref(v2);
     604                 :          0 :                 return;
     605                 :            :                 }
     606                 :            : 
     607                 :          0 :         val_list* vl = new val_list(3);
     608                 :          0 :         vl->append(BuildConnVal());
     609                 :          0 :         vl->append(v1);
     610                 :            : 
     611         [ #  # ]:          0 :         if ( v2 )
     612                 :          0 :                 vl->append(v2);
     613                 :            : 
     614                 :          0 :         ConnectionEvent(f, analyzer, vl);
     615                 :            :         }
     616                 :            : 
     617                 :      16749 : void Connection::ConnectionEvent(EventHandlerPtr f, Analyzer* a, val_list* vl)
     618                 :            :         {
     619         [ -  + ]:      16749 :         if ( ! f )
     620                 :            :                 {
     621                 :            :                 // This may actually happen if there is no local handler
     622                 :            :                 // and a previously existing remote handler went away.
     623         [ #  # ]:          0 :                 loop_over_list(*vl, i)
     624                 :          0 :                         Unref((*vl)[i]);
     625         [ #  # ]:          0 :                 delete vl;
     626                 :          0 :                 return;
     627                 :            :                 }
     628                 :            : 
     629                 :            :         // "this" is passed as a cookie for the event
     630                 :            :         mgr.QueueEvent(f, vl, SOURCE_LOCAL,
     631         [ +  + ]:      16749 :                         a ? a->GetID() : 0, GetTimerMgr(), this);
     632                 :            :         }
     633                 :            : 
     634                 :        433 : void Connection::Weird(const char* name)
     635                 :            :         {
     636                 :        433 :         weird = 1;
     637         [ +  - ]:        433 :         if ( conn_weird )
     638                 :        433 :                 Event(conn_weird, 0, name);
     639                 :            :         else
     640                 :          0 :                 fprintf(stderr, "%.06f weird: %s\n", network_time, name);
     641                 :        433 :         }
     642                 :            : 
     643                 :          0 : void Connection::Weird(const char* name, const char* addl)
     644                 :            :         {
     645                 :          0 :         weird = 1;
     646         [ #  # ]:          0 :         if ( conn_weird_addl )
     647                 :            :                 {
     648                 :          0 :                 val_list* vl = new val_list(3);
     649                 :            : 
     650                 :          0 :                 vl->append(new StringVal(name));
     651                 :          0 :                 vl->append(BuildConnVal());
     652                 :          0 :                 vl->append(new StringVal(addl));
     653                 :            : 
     654                 :          0 :                 ConnectionEvent(conn_weird_addl, 0, vl);
     655                 :            :                 }
     656                 :            : 
     657                 :            :         else
     658                 :          0 :                 fprintf(stderr, "%.06f weird: %s (%s)\n", network_time, name, addl);
     659                 :          0 :         }
     660                 :            : 
     661                 :          0 : void Connection::Weird(const char* name, int addl_len, const char* addl)
     662                 :            :         {
     663                 :          0 :         weird = 1;
     664         [ #  # ]:          0 :         if ( conn_weird_addl )
     665                 :            :                 {
     666                 :          0 :                 val_list* vl = new val_list(3);
     667                 :            : 
     668                 :          0 :                 vl->append(new StringVal(name));
     669                 :          0 :                 vl->append(BuildConnVal());
     670                 :          0 :                 vl->append(new StringVal(addl_len, addl));
     671                 :            : 
     672                 :          0 :                 ConnectionEvent(conn_weird_addl, 0, vl);
     673                 :            :                 }
     674                 :            : 
     675                 :            :         else
     676                 :            :                 {
     677                 :          0 :                 fprintf(stderr, "%.06f weird: %s (", network_time, name);
     678         [ #  # ]:          0 :                 for ( int i = 0; i < addl_len; ++i )
     679                 :          0 :                         fputc(addl[i], stderr);
     680                 :          0 :                 fprintf(stderr, ")\n");
     681                 :            :                 }
     682                 :          0 :         }
     683                 :            : 
     684                 :            : void Connection::AddTimer(timer_func timer, double t, int do_expire,
     685                 :       2048 :                 TimerType type)
     686                 :            :         {
     687         [ +  - ]:       2048 :         if ( timers_canceled )
     688                 :       2048 :                 return;
     689                 :            : 
     690                 :            :         // If the key is cleared, the connection isn't stored in the connection
     691                 :            :         // table anymore and will soon be deleted. We're not installing new
     692                 :            :         // timers anymore then.
     693         [ -  + ]:       2048 :         if ( ! key )
     694                 :          0 :                 return;
     695                 :            : 
     696                 :       2048 :         Timer* conn_timer = new ConnectionTimer(this, timer, t, do_expire, type);
     697                 :       2048 :         GetTimerMgr()->Add(conn_timer);
     698                 :       2048 :         timers.append(conn_timer);
     699                 :            :         }
     700                 :            : 
     701                 :       3554 : void Connection::RemoveTimer(Timer* t)
     702                 :            :         {
     703                 :       3554 :         timers.remove(t);
     704                 :       3554 :         }
     705                 :            : 
     706                 :       3251 : void Connection::CancelTimers()
     707                 :            :         {
     708                 :            :         // We are going to cancel our timers which, in turn, may cause them to
     709                 :            :         // call RemoveTimer(), which would then modify the list we're just
     710                 :            :         // traversing. Thus, we first make a copy of the list which we then
     711                 :            :         // iterate through.
     712                 :       3251 :         timer_list tmp(timers.length());
     713         [ +  + ]:       3790 :         loop_over_list(timers, j)
     714                 :        539 :                 tmp.append(timers[j]);
     715                 :            : 
     716         [ +  + ]:       3790 :         loop_over_list(tmp, i)
     717                 :        539 :                 GetTimerMgr()->Cancel(tmp[i]);
     718                 :            : 
     719                 :       3251 :         timers_canceled = 1;
     720                 :       3251 :         timers.clear();
     721                 :       3251 :         }
     722                 :            : 
     723                 :      40026 : TimerMgr* Connection::GetTimerMgr() const
     724                 :            :         {
     725         [ +  - ]:      40026 :         if ( ! conn_timer_mgr )
     726                 :            :                 // Global manager.
     727                 :      40026 :                 return timer_mgr;
     728                 :            : 
     729                 :            :         // We need to check whether the local timer manager still exists;
     730                 :            :         // it may have already been timed out, in which case we fall back
     731                 :            :         // to the global manager (though this should be rare).
     732                 :          0 :         TimerMgr* local_mgr = sessions->LookupTimerMgr(conn_timer_mgr, false);
     733         [ #  # ]:      40026 :         return local_mgr ? local_mgr : timer_mgr;
     734                 :            :         }
     735                 :            : 
     736                 :          0 : void Connection::FlipRoles()
     737                 :            :         {
     738                 :            :         uint32 tmp_addr[NUM_ADDR_WORDS];
     739                 :          0 :         copy_addr(resp_addr, tmp_addr);
     740                 :          0 :         copy_addr(orig_addr, resp_addr);
     741                 :          0 :         copy_addr(tmp_addr, orig_addr);
     742                 :            : 
     743                 :          0 :         uint32 tmp_port = resp_port;
     744                 :          0 :         resp_port = orig_port;
     745                 :          0 :         orig_port = tmp_port;
     746                 :            : 
     747                 :          0 :         RecordVal* tmp_rc = resp_endp;
     748                 :          0 :         resp_endp = orig_endp;
     749                 :          0 :         orig_endp = tmp_rc;
     750                 :            : 
     751                 :          0 :         Unref(conn_val);
     752                 :          0 :         conn_val = 0;
     753                 :            : 
     754         [ #  # ]:          0 :         if ( root_analyzer )
     755                 :          0 :                 root_analyzer->FlipRoles();
     756                 :          0 :         }
     757                 :            : 
     758                 :      19166 : int Connection::RewritingTrace()
     759                 :            :         {
     760         [ +  - ]:      19166 :         return root_analyzer ? root_analyzer->RewritingTrace() : 0;
     761                 :            :         }
     762                 :            : 
     763                 :        567 : Rewriter* Connection::TraceRewriter() const
     764                 :            :         {
     765         [ +  - ]:        567 :         return root_analyzer ? root_analyzer->TraceRewriter() : 0;
     766                 :            :         }
     767                 :            : 
     768                 :          0 : unsigned int Connection::MemoryAllocation() const
     769                 :            :         {
     770                 :            :         return padded_sizeof(*this)
     771                 :            :                 + (key ? key->MemoryAllocation() : 0)
     772                 :            :                 + (timers.MemoryAllocation() - padded_sizeof(timers))
     773                 :            :                 + (conn_val ? conn_val->MemoryAllocation() : 0)
     774 [ #  # ][ #  # ]:          0 :                 + (root_analyzer ? root_analyzer->MemoryAllocation(): 0)
                 [ #  # ]
     775                 :            :                 // login_conn is just a casted 'this'.
     776                 :            :                 // primary_PIA is already contained in the analyzer tree.
     777                 :            :                 ;
     778                 :            :         }
     779                 :            : 
     780                 :          0 : unsigned int Connection::MemoryAllocationConnVal() const
     781                 :            :         {
     782         [ #  # ]:          0 :         return conn_val ? conn_val->MemoryAllocation() : 0;
     783                 :            :         }
     784                 :            : 
     785                 :          0 : void Connection::Describe(ODesc* d) const
     786                 :            :         {
     787                 :          0 :         d->Add(start_time);
     788                 :          0 :         d->Add("(");
     789                 :          0 :         d->Add(last_time);
     790                 :          0 :         d->AddSP(")");
     791                 :            : 
     792   [ #  #  #  #  :          0 :         switch ( proto ) {
                      # ]
     793                 :            :                 case TRANSPORT_TCP:
     794                 :          0 :                         d->Add("TCP");
     795                 :          0 :                         break;
     796                 :            : 
     797                 :            :                 case TRANSPORT_UDP:
     798                 :          0 :                         d->Add("UDP");
     799                 :          0 :                         break;
     800                 :            : 
     801                 :            :                 case TRANSPORT_ICMP:
     802                 :          0 :                         d->Add("ICMP");
     803                 :          0 :                         break;
     804                 :            : 
     805                 :            :                 case TRANSPORT_UNKNOWN:
     806                 :          0 :                         internal_error("unknown transport in Connction::Describe()");
     807                 :            :                         break;
     808                 :            :                 }
     809                 :            : 
     810                 :          0 :         d->SP();
     811                 :          0 :         d->Add(dotted_addr(orig_addr));
     812                 :          0 :         d->Add(":");
     813                 :          0 :         d->Add(ntohs(orig_port));
     814                 :            : 
     815                 :          0 :         d->SP();
     816                 :          0 :         d->AddSP("->");
     817                 :            : 
     818                 :          0 :         d->Add(dotted_addr(resp_addr));
     819                 :          0 :         d->Add(":");
     820                 :          0 :         d->Add(ntohs(resp_port));
     821                 :            : 
     822                 :          0 :         d->NL();
     823                 :          0 :         }
     824                 :            : 
     825                 :          0 : bool Connection::Serialize(SerialInfo* info) const
     826                 :            :         {
     827                 :          0 :         return SerialObj::Serialize(info);
     828                 :            :         }
     829                 :            : 
     830                 :          0 : Connection* Connection::Unserialize(UnserialInfo* info)
     831                 :            :         {
     832                 :          0 :         return (Connection*) SerialObj::Unserialize(info, SER_CONNECTION);
     833                 :            :         }
     834                 :            : 
     835                 :          0 : bool Connection::DoSerialize(SerialInfo* info) const
     836                 :            :         {
     837 [ #  # ][ #  # ]:          0 :         DO_SERIALIZE(SER_CONNECTION, BroObj);
     838                 :            : 
     839                 :            :         // First we write the members which are needed to
     840                 :            :         // create the HashKey.
     841         [ #  # ]:          0 :         for ( int j = 0; j < NUM_ADDR_WORDS; ++j )
     842 [ #  # ][ #  # ]:          0 :                 if ( ! SERIALIZE(orig_addr[j]) || ! SERIALIZE(resp_addr[j]) )
                 [ #  # ]
     843                 :          0 :                         return false;
     844                 :            : 
     845 [ #  # ][ #  # ]:          0 :         if ( ! SERIALIZE(orig_port) || ! SERIALIZE(resp_port) )
                 [ #  # ]
     846                 :          0 :                 return false;
     847                 :            : 
     848         [ #  # ]:          0 :         if ( ! SERIALIZE(timers.length()) )
     849                 :          0 :                 return false;
     850                 :            : 
     851         [ #  # ]:          0 :         loop_over_list(timers, i)
     852         [ #  # ]:          0 :                 if ( ! timers[i]->Serialize(info) )
     853                 :          0 :                         return false;
     854                 :            : 
     855 [ #  # ][ #  # ]:          0 :         SERIALIZE_OPTIONAL(conn_val);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     856 [ #  # ][ #  # ]:          0 :         SERIALIZE_OPTIONAL(orig_endp);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     857 [ #  # ][ #  # ]:          0 :         SERIALIZE_OPTIONAL(resp_endp);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     858                 :            : 
     859                 :            :         // FIXME: RuleEndpointState not yet serializable.
     860                 :            :         // FIXME: Analyzers not yet serializable.
     861                 :            : 
     862                 :            :         return
     863                 :            :                 SERIALIZE(int(proto)) &&
     864                 :            :                 SERIALIZE(history) &&
     865                 :            :                 SERIALIZE(hist_seen) &&
     866                 :            :                 SERIALIZE(start_time) &&
     867                 :            :                 SERIALIZE(last_time) &&
     868                 :            :                 SERIALIZE(inactivity_timeout) &&
     869                 :            :                 SERIALIZE(suppress_event) &&
     870                 :            :                 SERIALIZE(login_conn != 0) &&
     871                 :            :                 SERIALIZE_BIT(installed_status_timer) &&
     872                 :            :                 SERIALIZE_BIT(timers_canceled) &&
     873                 :            :                 SERIALIZE_BIT(is_active) &&
     874                 :            :                 SERIALIZE_BIT(skip) &&
     875                 :            :                 SERIALIZE_BIT(weird) &&
     876                 :            :                 SERIALIZE_BIT(finished) &&
     877                 :            :                 SERIALIZE_BIT(record_packets) &&
     878                 :            :                 SERIALIZE_BIT(record_contents) &&
     879 [ #  # ][ #  # ]:          0 :                 SERIALIZE_BIT(persistent);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     880                 :            :         }
     881                 :            : 
     882                 :          0 : bool Connection::DoUnserialize(UnserialInfo* info)
     883                 :            :         {
     884                 :            :         // Make sure this is initialized for the condition in Unserialize().
     885                 :          0 :         persistent = 0;
     886                 :            : 
     887         [ #  # ]:          0 :         DO_UNSERIALIZE(BroObj);
     888                 :            : 
     889                 :            :         // Build the hash key first. Some of the recursive *::Unserialize()
     890                 :            :         // functions may need it.
     891         [ #  # ]:          0 :         for ( int i = 0; i < NUM_ADDR_WORDS; ++i )
     892 [ #  # ][ #  # ]:          0 :                 if ( ! UNSERIALIZE(&orig_addr[i]) || ! UNSERIALIZE(&resp_addr[i]) )
                 [ #  # ]
     893                 :          0 :                         goto error;
     894                 :            : 
     895 [ #  # ][ #  # ]:          0 :         if ( ! UNSERIALIZE(&orig_port) || ! UNSERIALIZE(&resp_port) )
                 [ #  # ]
     896                 :          0 :                 goto error;
     897                 :            : 
     898                 :            :         ConnID id;
     899                 :          0 :         id.src_addr = orig_addr;
     900                 :          0 :         id.dst_addr = resp_addr;
     901                 :            :         // This doesn't work for ICMP. But I guess this is not really important.
     902                 :          0 :         id.src_port = orig_port;
     903                 :          0 :         id.dst_port = resp_port;
     904                 :          0 :         id.is_one_way = 0;      // ### incorrect for ICMP
     905                 :          0 :         key = id.BuildConnKey();
     906                 :            : 
     907                 :            :         int len;
     908         [ #  # ]:          0 :         if ( ! UNSERIALIZE(&len) )
     909                 :          0 :                 goto error;
     910                 :            : 
     911         [ #  # ]:          0 :         while ( len-- )
     912                 :            :                 {
     913                 :          0 :                 Timer* t = Timer::Unserialize(info);
     914         [ #  # ]:          0 :                 if ( ! t )
     915                 :          0 :                         goto error;
     916                 :          0 :                 timers.append(t);
     917                 :            :                 }
     918                 :            : 
     919 [ #  # ][ #  # ]:          0 :         UNSERIALIZE_OPTIONAL(conn_val,
                 [ #  # ]
     920                 :            :                         (RecordVal*) Val::Unserialize(info, connection_type));
     921 [ #  # ][ #  # ]:          0 :         UNSERIALIZE_OPTIONAL(orig_endp,
                 [ #  # ]
     922                 :            :                         (RecordVal*) Val::Unserialize(info, endpoint));
     923 [ #  # ][ #  # ]:          0 :         UNSERIALIZE_OPTIONAL(resp_endp,
                 [ #  # ]
     924                 :            :                         (RecordVal*) Val::Unserialize(info, endpoint));
     925                 :            : 
     926                 :            :         int iproto;
     927                 :            : 
     928 [ #  # ][ #  # ]:          0 :         if ( ! (UNSERIALIZE(&iproto) &&
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     929                 :            :                 UNSERIALIZE(&history) &&
     930                 :            :                 UNSERIALIZE(&hist_seen) &&
     931                 :            :                 UNSERIALIZE(&start_time) &&
     932                 :            :                 UNSERIALIZE(&last_time) &&
     933                 :            :                 UNSERIALIZE(&inactivity_timeout) &&
     934                 :            :                 UNSERIALIZE(&suppress_event)) )
     935                 :          0 :                 goto error;
     936                 :            : 
     937                 :          0 :         proto = static_cast<TransportProto>(iproto);
     938                 :            : 
     939                 :            :         bool has_login_conn;
     940         [ #  # ]:          0 :         if ( ! UNSERIALIZE(&has_login_conn) )
     941                 :          0 :                 goto error;
     942                 :            : 
     943         [ #  # ]:          0 :         login_conn = has_login_conn ? (LoginConn*) this : 0;
     944                 :            : 
     945         [ #  # ]:          0 :         UNSERIALIZE_BIT(installed_status_timer);
     946         [ #  # ]:          0 :         UNSERIALIZE_BIT(timers_canceled);
     947         [ #  # ]:          0 :         UNSERIALIZE_BIT(is_active);
     948         [ #  # ]:          0 :         UNSERIALIZE_BIT(skip);
     949         [ #  # ]:          0 :         UNSERIALIZE_BIT(weird);
     950         [ #  # ]:          0 :         UNSERIALIZE_BIT(finished);
     951         [ #  # ]:          0 :         UNSERIALIZE_BIT(record_packets);
     952         [ #  # ]:          0 :         UNSERIALIZE_BIT(record_contents);
     953         [ #  # ]:          0 :         UNSERIALIZE_BIT(persistent);
     954                 :            : 
     955                 :            :         // Hmm... Why does each connection store a sessions ptr?
     956                 :          0 :         sessions = ::sessions;
     957                 :            : 
     958                 :          0 :         root_analyzer = 0;
     959                 :          0 :         primary_PIA = 0;
     960                 :          0 :         conn_timer_mgr = 0;
     961                 :            : 
     962                 :          0 :         return true;
     963                 :            : 
     964                 :          0 : error:
     965                 :          0 :         abort();
     966                 :            :         CancelTimers();
     967                 :          0 :         return false;
     968                 :            :         }
     969                 :            : 
     970                 :       1627 : void Connection::SetRootAnalyzer(TransportLayerAnalyzer* analyzer, PIA* pia)
     971                 :            :         {
     972                 :       1627 :         root_analyzer = analyzer;
     973                 :       1627 :         primary_PIA = pia;
     974 [ +  - ][ +  - ]:       1633 :         }

Generated by: LCOV version 1.8