Branch data Line data Source code
1 : : // $Id: SteppingStone.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 <stdlib.h>
8 : :
9 : : #include "Event.h"
10 : : #include "Net.h"
11 : : #include "NetVar.h"
12 : : #include "TCP.h"
13 : : #include "SteppingStone.h"
14 : : #include "util.h"
15 : :
16 : 0 : SteppingStoneEndpoint::SteppingStoneEndpoint(TCP_Endpoint* e, SteppingStoneManager* m)
17 : : {
18 : 0 : endp = e;
19 : 0 : stp_max_top_seq = 0;
20 : 0 : stp_last_time = stp_resume_time = 0.0;
21 : 0 : stp_manager = m;
22 : 0 : stp_id = stp_manager->NextID();
23 : 0 : stp_key = new HashKey(bro_int_t(stp_id));
24 : :
25 : 0 : CreateEndpEvent(e->IsOrig());
26 : :
27 : : // Make sure the connection does not get deleted.
28 : 0 : Ref(endp->TCP()->Conn());
29 : 0 : }
30 : :
31 : 0 : SteppingStoneEndpoint::~SteppingStoneEndpoint()
32 : : {
33 [ # # ][ # # ]: 0 : delete stp_key;
[ # # ]
34 : 0 : Unref(endp->TCP()->Conn());
35 [ # # ][ # # ]: 0 : }
[ # # ]
36 : :
37 : 0 : void SteppingStoneEndpoint::Done()
38 : : {
39 [ # # ]: 0 : if ( RefCnt() > 1 )
40 : 0 : return;
41 : :
42 : : SteppingStoneEndpoint* ep;
43 : : IterCookie* cookie;
44 : :
45 : 0 : cookie = stp_inbound_endps.InitForIteration();
46 [ # # ]: 0 : while ( (ep = stp_inbound_endps.NextEntry(cookie)) )
47 : : {
48 : 0 : ep->stp_outbound_endps.Remove(stp_key);
49 : 0 : Event(stp_remove_pair, ep->stp_id, stp_id);
50 : 0 : Unref(ep);
51 : : }
52 : :
53 : 0 : cookie = stp_outbound_endps.InitForIteration();
54 [ # # ]: 0 : while ( (ep = stp_outbound_endps.NextEntry(cookie)) )
55 : : {
56 : 0 : ep->stp_inbound_endps.Remove(stp_key);
57 : 0 : Event(stp_remove_pair, stp_id, ep->stp_id);
58 : 0 : Unref(ep);
59 : : }
60 : :
61 : 0 : Event(stp_remove_endp, stp_id);
62 : : }
63 : :
64 : : int SteppingStoneEndpoint::DataSent(double t, int seq, int len, int caplen,
65 : : const u_char* data, const IP_Hdr* /* ip */,
66 : 0 : const struct tcphdr* tp)
67 : : {
68 [ # # ]: 0 : if ( caplen < len )
69 : 0 : len = caplen;
70 : :
71 [ # # ]: 0 : if ( len <= 0 )
72 : 0 : return 0;
73 : :
74 : 0 : double tmin = t - stp_delta;
75 : :
76 [ # # ]: 0 : while ( stp_manager->OrderedEndpoints().length() > 0 )
77 : : {
78 : 0 : int f = stp_manager->OrderedEndpoints().front();
79 : :
80 [ # # ]: 0 : if ( stp_manager->OrderedEndpoints()[f]->stp_resume_time < tmin )
81 : : {
82 : : SteppingStoneEndpoint* e =
83 : 0 : stp_manager->OrderedEndpoints().pop_front();
84 : 0 : e->Done();
85 : 0 : Unref(e);
86 : : }
87 : : else
88 : 0 : break;
89 : : }
90 : :
91 : 0 : int ack = endp->AckSeq() - endp->StartSeq();
92 : 0 : int top_seq = seq + len;
93 : :
94 [ # # # # ]: 0 : if ( top_seq <= ack || top_seq <= stp_max_top_seq )
95 : : // There is no new data in this packet
96 : 0 : return 0;
97 : :
98 : 0 : stp_max_top_seq = top_seq;
99 : :
100 [ # # ][ # # ]: 0 : if ( stp_last_time && t <= stp_last_time + stp_idle_min )
101 : : {
102 : 0 : stp_last_time = t;
103 : 0 : return 1;
104 : : }
105 : :
106 : : // Either just starts, or resumes from an idle period.
107 : 0 : stp_last_time = stp_resume_time = t;
108 : :
109 : 0 : Event(stp_resume_endp, stp_id);
110 [ # # ]: 0 : loop_over_queue(stp_manager->OrderedEndpoints(), i)
111 : : {
112 : 0 : SteppingStoneEndpoint* ep = stp_manager->OrderedEndpoints()[i];
113 [ # # ]: 0 : if ( ep->endp->TCP() != endp->TCP() )
114 : : {
115 : 0 : Ref(ep);
116 : 0 : Ref(this);
117 : :
118 : 0 : stp_inbound_endps.Insert(ep->stp_key, ep);
119 : 0 : ep->stp_outbound_endps.Insert(stp_key, this);
120 : :
121 : 0 : Event(stp_correlate_pair, ep->stp_id, stp_id);
122 : : }
123 : :
124 : : else
125 : : { // ep and this belong to same connection
126 : : }
127 : : }
128 : :
129 : 0 : stp_manager->OrderedEndpoints().push_back(this);
130 : 0 : Ref(this);
131 : :
132 : 0 : return 1;
133 : : }
134 : :
135 : 0 : void SteppingStoneEndpoint::Event(EventHandlerPtr f, int id1, int id2)
136 : : {
137 [ # # ]: 0 : if ( ! f )
138 : 0 : return;
139 : :
140 : 0 : val_list* vl = new val_list;
141 : :
142 : 0 : vl->append(new Val(id1, TYPE_INT));
143 : :
144 [ # # ]: 0 : if ( id2 >= 0 )
145 : 0 : vl->append(new Val(id2, TYPE_INT));
146 : :
147 : 0 : endp->TCP()->ConnectionEvent(f, vl);
148 : : }
149 : :
150 : 0 : void SteppingStoneEndpoint::CreateEndpEvent(int is_orig)
151 : : {
152 : 0 : val_list* vl = new val_list;
153 : :
154 : 0 : vl->append(endp->TCP()->BuildConnVal());
155 : 0 : vl->append(new Val(stp_id, TYPE_INT));
156 : 0 : vl->append(new Val(is_orig, TYPE_BOOL));
157 : :
158 : 0 : endp->TCP()->ConnectionEvent(stp_create_endp, vl);
159 : 0 : }
160 : :
161 : 0 : SteppingStone_Analyzer::SteppingStone_Analyzer(Connection* c)
162 : 0 : : TCP_ApplicationAnalyzer(AnalyzerTag::SteppingStone, c)
163 : : {
164 : 0 : stp_manager = sessions->GetSTPManager();
165 : :
166 : 0 : orig_endp = resp_endp = 0;
167 : 0 : orig_stream_pos = resp_stream_pos = 1;
168 : 0 : }
169 : :
170 : 0 : void SteppingStone_Analyzer::Init()
171 : : {
172 : 0 : TCP_ApplicationAnalyzer::Init();
173 : :
174 [ # # ]: 0 : assert(TCP());
175 : 0 : orig_endp = new SteppingStoneEndpoint(TCP()->Orig(), stp_manager);
176 : 0 : resp_endp = new SteppingStoneEndpoint(TCP()->Resp(), stp_manager);
177 : 0 : }
178 : :
179 : : void SteppingStone_Analyzer::DeliverPacket(int len, const u_char* data,
180 : : bool is_orig, int seq,
181 : 0 : const IP_Hdr* ip, int caplen)
182 : : {
183 : : TCP_ApplicationAnalyzer::DeliverPacket(len, data, is_orig, seq,
184 : 0 : ip, caplen);
185 : :
186 [ # # ]: 0 : if ( is_orig )
187 : 0 : orig_endp->DataSent(network_time, seq, len, caplen, data, 0, 0);
188 : : else
189 : 0 : resp_endp->DataSent(network_time, seq, len, caplen, data, 0, 0);
190 : 0 : }
191 : :
192 : : void SteppingStone_Analyzer::DeliverStream(int len, const u_char* data,
193 : 0 : bool is_orig)
194 : : {
195 : 0 : TCP_ApplicationAnalyzer::DeliverStream(len, data, is_orig);
196 : :
197 [ # # ]: 0 : if ( is_orig )
198 : : {
199 : : orig_endp->DataSent(network_time, orig_stream_pos, len, len,
200 : 0 : data, 0, 0);
201 : 0 : orig_stream_pos += len;
202 : : }
203 : :
204 : : else
205 : : {
206 : : resp_endp->DataSent(network_time, resp_stream_pos, len, len,
207 : 0 : data, 0, 0);
208 : 0 : resp_stream_pos += len;
209 : : }
210 : 0 : }
211 : :
212 : 0 : void SteppingStone_Analyzer::Done()
213 : : {
214 : 0 : TCP_ApplicationAnalyzer::Done();
215 : :
216 : 0 : orig_endp->Done();
217 : 0 : resp_endp->Done();
218 : :
219 : 0 : Unref(orig_endp);
220 : 0 : Unref(resp_endp);
221 [ + - ][ + - ]: 6 : }
|