|
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ |
|
2 /* |
|
3 * Copyright (c) 2007 Georgia Tech Research Corporation |
|
4 * |
|
5 * This program is free software; you can redistribute it and/or modify |
|
6 * it under the terms of the GNU General Public License version 2 as |
|
7 * published by the Free Software Foundation; |
|
8 * |
|
9 * This program is distributed in the hope that it will be useful, |
|
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 * GNU General Public License for more details. |
|
13 * |
|
14 * You should have received a copy of the GNU General Public License |
|
15 * along with this program; if not, write to the Free Software |
|
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
17 * |
|
18 * Author: Raj Bhattacharjea <raj.b@gatech.edu> |
|
19 */ |
|
20 |
|
21 #include "ns3/assert.h" |
|
22 #include "ns3/log.h" |
|
23 #include "ns3/nstime.h" |
|
24 |
|
25 #include "ns3/packet.h" |
|
26 #include "ns3/node.h" |
|
27 |
|
28 #include "tcp-l4-protocol.h" |
|
29 #include "tcp-header.h" |
|
30 #include "ipv4-end-point-demux.h" |
|
31 #include "ipv4-end-point.h" |
|
32 #include "ipv4-l3-protocol.h" |
|
33 #include "tcp-socket-impl.h" |
|
34 |
|
35 #include "tcp-typedefs.h" |
|
36 |
|
37 #include <vector> |
|
38 #include <sstream> |
|
39 #include <iomanip> |
|
40 |
|
41 NS_LOG_COMPONENT_DEFINE ("TcpL4Protocol"); |
|
42 |
|
43 namespace ns3 { |
|
44 |
|
45 NS_OBJECT_ENSURE_REGISTERED (TcpL4Protocol); |
|
46 |
|
47 //State Machine things -------------------------------------------------------- |
|
48 TcpStateMachine::TcpStateMachine() |
|
49 : aT (LAST_STATE, StateActionVec_t(LAST_EVENT)), |
|
50 eV (MAX_FLAGS) |
|
51 { |
|
52 NS_LOG_FUNCTION_NOARGS (); |
|
53 |
|
54 // Create the state table |
|
55 // Closed state |
|
56 aT[CLOSED][APP_LISTEN] = SA (LISTEN, NO_ACT); |
|
57 aT[CLOSED][APP_CONNECT] = SA (SYN_SENT, SYN_TX); |
|
58 aT[CLOSED][APP_SEND] = SA (CLOSED, RST_TX); |
|
59 aT[CLOSED][SEQ_RECV] = SA (CLOSED, NO_ACT); |
|
60 aT[CLOSED][APP_CLOSE] = SA (CLOSED, NO_ACT); |
|
61 aT[CLOSED][TIMEOUT] = SA (CLOSED, RST_TX); |
|
62 aT[CLOSED][ACK_RX] = SA (CLOSED, RST_TX); |
|
63 aT[CLOSED][SYN_RX] = SA (CLOSED, RST_TX); |
|
64 aT[CLOSED][SYN_ACK_RX] = SA (CLOSED, RST_TX); |
|
65 aT[CLOSED][FIN_RX] = SA (CLOSED, RST_TX); |
|
66 aT[CLOSED][FIN_ACK_RX] = SA (CLOSED, RST_TX); |
|
67 aT[CLOSED][RST_RX] = SA (CLOSED, CANCEL_TM); |
|
68 aT[CLOSED][BAD_FLAGS] = SA (CLOSED, RST_TX); |
|
69 |
|
70 // Listen State |
|
71 // For the listen state, anything other than CONNECT or SEND |
|
72 // is simply ignored....this likely indicates the child TCP |
|
73 // has finished and issued unbind call, but the remote end |
|
74 // has not yet closed. |
|
75 aT[LISTEN][APP_LISTEN] = SA (LISTEN, NO_ACT); |
|
76 aT[LISTEN][APP_CONNECT] = SA (SYN_SENT, SYN_TX); |
|
77 aT[LISTEN][APP_SEND] = SA (SYN_SENT, SYN_TX); |
|
78 aT[LISTEN][SEQ_RECV] = SA (LISTEN, NO_ACT); |
|
79 aT[LISTEN][APP_CLOSE] = SA (CLOSED, NO_ACT); |
|
80 aT[LISTEN][TIMEOUT] = SA (LISTEN, NO_ACT); |
|
81 aT[LISTEN][ACK_RX] = SA (LISTEN, NO_ACT); |
|
82 aT[LISTEN][SYN_RX] = SA (LISTEN, SYN_ACK_TX);//stay in listen and fork |
|
83 aT[LISTEN][SYN_ACK_RX] = SA (LISTEN, NO_ACT); |
|
84 aT[LISTEN][FIN_RX] = SA (LISTEN, NO_ACT); |
|
85 aT[LISTEN][FIN_ACK_RX] = SA (LISTEN, NO_ACT); |
|
86 aT[LISTEN][RST_RX] = SA (LISTEN, NO_ACT); |
|
87 aT[LISTEN][BAD_FLAGS] = SA (LISTEN, NO_ACT); |
|
88 |
|
89 // Syn Sent State |
|
90 aT[SYN_SENT][APP_LISTEN] = SA (CLOSED, RST_TX); |
|
91 aT[SYN_SENT][APP_CONNECT] = SA (SYN_SENT, SYN_TX); |
|
92 aT[SYN_SENT][APP_SEND] = SA (SYN_SENT, NO_ACT); |
|
93 aT[SYN_SENT][SEQ_RECV] = SA (ESTABLISHED, NEW_SEQ_RX); |
|
94 aT[SYN_SENT][APP_CLOSE] = SA (CLOSED, RST_TX); |
|
95 aT[SYN_SENT][TIMEOUT] = SA (CLOSED, NO_ACT); |
|
96 aT[SYN_SENT][ACK_RX] = SA (SYN_SENT, NO_ACT); |
|
97 aT[SYN_SENT][SYN_RX] = SA (SYN_RCVD, SYN_ACK_TX); |
|
98 aT[SYN_SENT][SYN_ACK_RX] = SA (ESTABLISHED, ACK_TX_1); |
|
99 aT[SYN_SENT][FIN_RX] = SA (CLOSED, RST_TX); |
|
100 aT[SYN_SENT][FIN_ACK_RX] = SA (CLOSED, RST_TX); |
|
101 aT[SYN_SENT][RST_RX] = SA (CLOSED, APP_NOTIFY); |
|
102 aT[SYN_SENT][BAD_FLAGS] = SA (CLOSED, RST_TX); |
|
103 |
|
104 // Syn Recvd State |
|
105 aT[SYN_RCVD][APP_LISTEN] = SA (CLOSED, RST_TX); |
|
106 aT[SYN_RCVD][APP_CONNECT] = SA (CLOSED, RST_TX); |
|
107 aT[SYN_RCVD][APP_SEND] = SA (CLOSED, RST_TX); |
|
108 aT[SYN_RCVD][SEQ_RECV] = SA (ESTABLISHED, NEW_SEQ_RX); |
|
109 aT[SYN_RCVD][APP_CLOSE] = SA (FIN_WAIT_1, FIN_TX); |
|
110 aT[SYN_RCVD][TIMEOUT] = SA (CLOSED, RST_TX); |
|
111 aT[SYN_RCVD][ACK_RX] = SA (ESTABLISHED, SERV_NOTIFY); |
|
112 aT[SYN_RCVD][SYN_RX] = SA (SYN_RCVD, SYN_ACK_TX); |
|
113 aT[SYN_RCVD][SYN_ACK_RX] = SA (CLOSED, RST_TX); |
|
114 aT[SYN_RCVD][FIN_RX] = SA (CLOSED, RST_TX); |
|
115 aT[SYN_RCVD][FIN_ACK_RX] = SA (CLOSE_WAIT, PEER_CLOSE); |
|
116 aT[SYN_RCVD][RST_RX] = SA (CLOSED, CANCEL_TM); |
|
117 aT[SYN_RCVD][BAD_FLAGS] = SA (CLOSED, RST_TX); |
|
118 |
|
119 // Established State |
|
120 aT[ESTABLISHED][APP_LISTEN] = SA (CLOSED, RST_TX); |
|
121 aT[ESTABLISHED][APP_CONNECT]= SA (CLOSED, RST_TX); |
|
122 aT[ESTABLISHED][APP_SEND] = SA (ESTABLISHED,TX_DATA); |
|
123 aT[ESTABLISHED][SEQ_RECV] = SA (ESTABLISHED,NEW_SEQ_RX); |
|
124 aT[ESTABLISHED][APP_CLOSE] = SA (FIN_WAIT_1, FIN_TX); |
|
125 aT[ESTABLISHED][TIMEOUT] = SA (ESTABLISHED,RETX); |
|
126 aT[ESTABLISHED][ACK_RX] = SA (ESTABLISHED,NEW_ACK); |
|
127 aT[ESTABLISHED][SYN_RX] = SA (SYN_RCVD, SYN_ACK_TX); |
|
128 aT[ESTABLISHED][SYN_ACK_RX] = SA (ESTABLISHED,NO_ACT); |
|
129 aT[ESTABLISHED][FIN_RX] = SA (CLOSE_WAIT, PEER_CLOSE); |
|
130 aT[ESTABLISHED][FIN_ACK_RX] = SA (CLOSE_WAIT, PEER_CLOSE); |
|
131 aT[ESTABLISHED][RST_RX] = SA (CLOSED, CANCEL_TM); |
|
132 aT[ESTABLISHED][BAD_FLAGS] = SA (CLOSED, RST_TX); |
|
133 |
|
134 // Close Wait State |
|
135 aT[CLOSE_WAIT][APP_LISTEN] = SA (CLOSED, RST_TX); |
|
136 aT[CLOSE_WAIT][APP_CONNECT] = SA (SYN_SENT, SYN_TX); |
|
137 aT[CLOSE_WAIT][APP_SEND] = SA (CLOSE_WAIT, TX_DATA); |
|
138 aT[CLOSE_WAIT][SEQ_RECV] = SA (CLOSE_WAIT, NEW_SEQ_RX); |
|
139 aT[CLOSE_WAIT][APP_CLOSE] = SA (LAST_ACK, FIN_ACK_TX); |
|
140 aT[CLOSE_WAIT][TIMEOUT] = SA (CLOSE_WAIT, NO_ACT); |
|
141 aT[CLOSE_WAIT][ACK_RX] = SA (CLOSE_WAIT, NO_ACT); |
|
142 aT[CLOSE_WAIT][SYN_RX] = SA (CLOSED, RST_TX); |
|
143 aT[CLOSE_WAIT][SYN_ACK_RX] = SA (CLOSED, RST_TX); |
|
144 aT[CLOSE_WAIT][FIN_RX] = SA (CLOSE_WAIT, ACK_TX); |
|
145 aT[CLOSE_WAIT][FIN_ACK_RX] = SA (CLOSE_WAIT, ACK_TX); |
|
146 aT[CLOSE_WAIT][RST_RX] = SA (CLOSED, CANCEL_TM); |
|
147 aT[CLOSE_WAIT][BAD_FLAGS] = SA (CLOSED, RST_TX); |
|
148 |
|
149 // Close Last Ack State |
|
150 aT[LAST_ACK][APP_LISTEN] = SA (CLOSED, RST_TX); |
|
151 aT[LAST_ACK][APP_CONNECT] = SA (SYN_SENT, SYN_TX); |
|
152 aT[LAST_ACK][APP_SEND] = SA (CLOSED, RST_TX); |
|
153 aT[LAST_ACK][SEQ_RECV] = SA (LAST_ACK, NEW_SEQ_RX); |
|
154 aT[LAST_ACK][APP_CLOSE] = SA (CLOSED, NO_ACT); |
|
155 aT[LAST_ACK][TIMEOUT] = SA (CLOSED, NO_ACT); |
|
156 aT[LAST_ACK][ACK_RX] = SA (CLOSED, APP_CLOSED); |
|
157 aT[LAST_ACK][SYN_RX] = SA (CLOSED, RST_TX); |
|
158 aT[LAST_ACK][SYN_ACK_RX] = SA (CLOSED, RST_TX); |
|
159 aT[LAST_ACK][FIN_RX] = SA (LAST_ACK, FIN_ACK_TX); |
|
160 aT[LAST_ACK][FIN_ACK_RX] = SA (CLOSED, NO_ACT); |
|
161 aT[LAST_ACK][RST_RX] = SA (CLOSED, CANCEL_TM); |
|
162 aT[LAST_ACK][BAD_FLAGS] = SA (CLOSED, RST_TX); |
|
163 |
|
164 // FIN_WAIT_1 state |
|
165 aT[FIN_WAIT_1][APP_LISTEN] = SA (CLOSED, RST_TX); |
|
166 aT[FIN_WAIT_1][APP_CONNECT] = SA (CLOSED, RST_TX); |
|
167 aT[FIN_WAIT_1][APP_SEND] = SA (CLOSED, RST_TX); |
|
168 aT[FIN_WAIT_1][SEQ_RECV] = SA (FIN_WAIT_1, NEW_SEQ_RX); |
|
169 aT[FIN_WAIT_1][APP_CLOSE] = SA (FIN_WAIT_1, NO_ACT); |
|
170 aT[FIN_WAIT_1][TIMEOUT] = SA (FIN_WAIT_1, NO_ACT); |
|
171 aT[FIN_WAIT_1][ACK_RX] = SA (FIN_WAIT_2, NEW_ACK); |
|
172 aT[FIN_WAIT_1][SYN_RX] = SA (CLOSED, RST_TX); |
|
173 aT[FIN_WAIT_1][SYN_ACK_RX] = SA (CLOSED, RST_TX); |
|
174 aT[FIN_WAIT_1][FIN_RX] = SA (CLOSING, ACK_TX); |
|
175 aT[FIN_WAIT_1][FIN_ACK_RX] = SA (TIMED_WAIT, ACK_TX); |
|
176 aT[FIN_WAIT_1][RST_RX] = SA (CLOSED, CANCEL_TM); |
|
177 aT[FIN_WAIT_1][BAD_FLAGS] = SA (CLOSED, RST_TX); |
|
178 |
|
179 // FIN_WAIT_2 state |
|
180 aT[FIN_WAIT_2][APP_LISTEN] = SA (CLOSED, RST_TX); |
|
181 aT[FIN_WAIT_2][APP_CONNECT] = SA (CLOSED, RST_TX); |
|
182 aT[FIN_WAIT_2][APP_SEND] = SA (CLOSED, RST_TX); |
|
183 aT[FIN_WAIT_2][SEQ_RECV] = SA (FIN_WAIT_2, NEW_SEQ_RX); |
|
184 aT[FIN_WAIT_2][APP_CLOSE] = SA (FIN_WAIT_2, NO_ACT); |
|
185 aT[FIN_WAIT_2][TIMEOUT] = SA (FIN_WAIT_2, NO_ACT); |
|
186 aT[FIN_WAIT_2][ACK_RX] = SA (FIN_WAIT_2, NEW_ACK); |
|
187 aT[FIN_WAIT_2][SYN_RX] = SA (CLOSED, RST_TX); |
|
188 aT[FIN_WAIT_2][SYN_ACK_RX] = SA (CLOSED, RST_TX); |
|
189 aT[FIN_WAIT_2][FIN_RX] = SA (TIMED_WAIT, ACK_TX); |
|
190 aT[FIN_WAIT_2][FIN_ACK_RX] = SA (TIMED_WAIT, ACK_TX); |
|
191 aT[FIN_WAIT_2][RST_RX] = SA (CLOSED, CANCEL_TM); |
|
192 aT[FIN_WAIT_2][BAD_FLAGS] = SA (CLOSED, RST_TX); |
|
193 |
|
194 // CLOSING state |
|
195 aT[CLOSING][APP_LISTEN] = SA (CLOSED, RST_TX); |
|
196 aT[CLOSING][APP_CONNECT] = SA (CLOSED, RST_TX); |
|
197 aT[CLOSING][APP_SEND] = SA (CLOSED, RST_TX); |
|
198 aT[CLOSING][SEQ_RECV] = SA (CLOSED, RST_TX); |
|
199 aT[CLOSING][APP_CLOSE] = SA (CLOSED, RST_TX); |
|
200 aT[CLOSING][TIMEOUT] = SA (CLOSING, NO_ACT); |
|
201 aT[CLOSING][ACK_RX] = SA (TIMED_WAIT, NO_ACT); |
|
202 aT[CLOSING][SYN_RX] = SA (CLOSED, RST_TX); |
|
203 aT[CLOSING][SYN_ACK_RX] = SA (CLOSED, RST_TX); |
|
204 aT[CLOSING][FIN_RX] = SA (CLOSED, ACK_TX); |
|
205 aT[CLOSING][FIN_ACK_RX] = SA (CLOSED, ACK_TX); |
|
206 aT[CLOSING][RST_RX] = SA (CLOSED, CANCEL_TM); |
|
207 aT[CLOSING][BAD_FLAGS] = SA (CLOSED, RST_TX); |
|
208 |
|
209 // TIMED_WAIT state |
|
210 aT[TIMED_WAIT][APP_LISTEN] = SA (TIMED_WAIT, NO_ACT); |
|
211 aT[TIMED_WAIT][APP_CONNECT] = SA (TIMED_WAIT, NO_ACT); |
|
212 aT[TIMED_WAIT][APP_SEND] = SA (TIMED_WAIT, NO_ACT); |
|
213 aT[TIMED_WAIT][SEQ_RECV] = SA (TIMED_WAIT, NO_ACT); |
|
214 aT[TIMED_WAIT][APP_CLOSE] = SA (TIMED_WAIT, NO_ACT); |
|
215 aT[TIMED_WAIT][TIMEOUT] = SA (TIMED_WAIT, NO_ACT); |
|
216 aT[TIMED_WAIT][ACK_RX] = SA (TIMED_WAIT, NO_ACT); |
|
217 aT[TIMED_WAIT][SYN_RX] = SA (TIMED_WAIT, NO_ACT); |
|
218 aT[TIMED_WAIT][SYN_ACK_RX] = SA (TIMED_WAIT, NO_ACT); |
|
219 aT[TIMED_WAIT][FIN_RX] = SA (TIMED_WAIT, NO_ACT); |
|
220 aT[TIMED_WAIT][FIN_ACK_RX] = SA (TIMED_WAIT, NO_ACT); |
|
221 aT[TIMED_WAIT][RST_RX] = SA (TIMED_WAIT, NO_ACT); |
|
222 aT[TIMED_WAIT][BAD_FLAGS] = SA (TIMED_WAIT, NO_ACT); |
|
223 |
|
224 // Create the flags lookup table |
|
225 eV[ 0x00] = SEQ_RECV; // No flags |
|
226 eV[ 0x01] = FIN_RX; // Fin |
|
227 eV[ 0x02] = SYN_RX; // Syn |
|
228 eV[ 0x03] = BAD_FLAGS; // Illegal |
|
229 eV[ 0x04] = RST_RX; // Rst |
|
230 eV[ 0x05] = BAD_FLAGS; // Illegal |
|
231 eV[ 0x06] = BAD_FLAGS; // Illegal |
|
232 eV[ 0x07] = BAD_FLAGS; // Illegal |
|
233 eV[ 0x08] = SEQ_RECV; // Psh flag is not used |
|
234 eV[ 0x09] = FIN_RX; // Fin |
|
235 eV[ 0x0a] = SYN_RX; // Syn |
|
236 eV[ 0x0b] = BAD_FLAGS; // Illegal |
|
237 eV[ 0x0c] = RST_RX; // Rst |
|
238 eV[ 0x0d] = BAD_FLAGS; // Illegal |
|
239 eV[ 0x0e] = BAD_FLAGS; // Illegal |
|
240 eV[ 0x0f] = BAD_FLAGS; // Illegal |
|
241 eV[ 0x10] = ACK_RX; // Ack |
|
242 eV[ 0x11] = FIN_ACK_RX;// Fin/Ack |
|
243 eV[ 0x12] = SYN_ACK_RX;// Syn/Ack |
|
244 eV[ 0x13] = BAD_FLAGS; // Illegal |
|
245 eV[ 0x14] = RST_RX; // Rst |
|
246 eV[ 0x15] = BAD_FLAGS; // Illegal |
|
247 eV[ 0x16] = BAD_FLAGS; // Illegal |
|
248 eV[ 0x17] = BAD_FLAGS; // Illegal |
|
249 eV[ 0x18] = ACK_RX; // Ack |
|
250 eV[ 0x19] = FIN_ACK_RX;// Fin/Ack |
|
251 eV[ 0x1a] = SYN_ACK_RX;// Syn/Ack |
|
252 eV[ 0x1b] = BAD_FLAGS; // Illegal |
|
253 eV[ 0x1c] = RST_RX; // Rst |
|
254 eV[ 0x1d] = BAD_FLAGS; // Illegal |
|
255 eV[ 0x1e] = BAD_FLAGS; // Illegal |
|
256 eV[ 0x1f] = BAD_FLAGS; // Illegal |
|
257 eV[ 0x20] = SEQ_RECV; // No flags (Urgent not presently used) |
|
258 eV[ 0x21] = FIN_RX; // Fin |
|
259 eV[ 0x22] = SYN_RX; // Syn |
|
260 eV[ 0x23] = BAD_FLAGS; // Illegal |
|
261 eV[ 0x24] = RST_RX; // Rst |
|
262 eV[ 0x25] = BAD_FLAGS; // Illegal |
|
263 eV[ 0x26] = BAD_FLAGS; // Illegal |
|
264 eV[ 0x27] = BAD_FLAGS; // Illegal |
|
265 eV[ 0x28] = SEQ_RECV; // Psh flag is not used |
|
266 eV[ 0x29] = FIN_RX; // Fin |
|
267 eV[ 0x2a] = SYN_RX; // Syn |
|
268 eV[ 0x2b] = BAD_FLAGS; // Illegal |
|
269 eV[ 0x2c] = RST_RX; // Rst |
|
270 eV[ 0x2d] = BAD_FLAGS; // Illegal |
|
271 eV[ 0x2e] = BAD_FLAGS; // Illegal |
|
272 eV[ 0x2f] = BAD_FLAGS; // Illegal |
|
273 eV[ 0x30] = ACK_RX; // Ack (Urgent not used) |
|
274 eV[ 0x31] = FIN_ACK_RX;// Fin/Ack |
|
275 eV[ 0x32] = SYN_ACK_RX;// Syn/Ack |
|
276 eV[ 0x33] = BAD_FLAGS; // Illegal |
|
277 eV[ 0x34] = RST_RX; // Rst |
|
278 eV[ 0x35] = BAD_FLAGS; // Illegal |
|
279 eV[ 0x36] = BAD_FLAGS; // Illegal |
|
280 eV[ 0x37] = BAD_FLAGS; // Illegal |
|
281 eV[ 0x38] = ACK_RX; // Ack |
|
282 eV[ 0x39] = FIN_ACK_RX;// Fin/Ack |
|
283 eV[ 0x3a] = SYN_ACK_RX;// Syn/Ack |
|
284 eV[ 0x3b] = BAD_FLAGS; // Illegal |
|
285 eV[ 0x3c] = RST_RX; // Rst |
|
286 eV[ 0x3d] = BAD_FLAGS; // Illegal |
|
287 eV[ 0x3e] = BAD_FLAGS; // Illegal |
|
288 eV[ 0x3f] = BAD_FLAGS; // Illegal |
|
289 } |
|
290 |
|
291 SA TcpStateMachine::Lookup (States_t s, Events_t e) |
|
292 { |
|
293 NS_LOG_FUNCTION (this << s << e); |
|
294 return aT[s][e]; |
|
295 } |
|
296 |
|
297 Events_t TcpStateMachine::FlagsEvent (uint8_t f) |
|
298 { |
|
299 NS_LOG_FUNCTION (this << f); |
|
300 // Lookup event from flags |
|
301 if (f >= MAX_FLAGS) return BAD_FLAGS; |
|
302 return eV[f]; // Look up flags event |
|
303 } |
|
304 |
|
305 static TcpStateMachine tcpStateMachine; //only instance of a TcpStateMachine |
|
306 |
|
307 //TcpL4Protocol stuff---------------------------------------------------------- |
|
308 |
|
309 |
|
310 /* see http://www.iana.org/assignments/protocol-numbers */ |
|
311 const uint8_t TcpL4Protocol::PROT_NUMBER = 6; |
|
312 |
|
313 ObjectFactory |
|
314 TcpL4Protocol::GetDefaultRttEstimatorFactory (void) |
|
315 { |
|
316 ObjectFactory factory; |
|
317 factory.SetTypeId (RttMeanDeviation::GetTypeId ()); |
|
318 return factory; |
|
319 } |
|
320 |
|
321 TypeId |
|
322 TcpL4Protocol::GetTypeId (void) |
|
323 { |
|
324 static TypeId tid = TypeId ("ns3::TcpL4Protocol") |
|
325 .SetParent<Ipv4L4Protocol> () |
|
326 .AddAttribute ("RttEstimatorFactory", |
|
327 "How RttEstimator objects are created.", |
|
328 ObjectFactoryValue (GetDefaultRttEstimatorFactory ()), |
|
329 MakeObjectFactoryAccessor (&TcpL4Protocol::m_rttFactory), |
|
330 MakeObjectFactoryChecker ()) |
|
331 ; |
|
332 return tid; |
|
333 } |
|
334 |
|
335 TcpL4Protocol::TcpL4Protocol () |
|
336 : m_endPoints (new Ipv4EndPointDemux ()) |
|
337 { |
|
338 NS_LOG_FUNCTION_NOARGS (); |
|
339 NS_LOG_LOGIC("Made a TcpL4Protocol "<<this); |
|
340 } |
|
341 |
|
342 TcpL4Protocol::~TcpL4Protocol () |
|
343 { |
|
344 NS_LOG_FUNCTION_NOARGS (); |
|
345 } |
|
346 |
|
347 void |
|
348 TcpL4Protocol::SetNode (Ptr<Node> node) |
|
349 { |
|
350 m_node = node; |
|
351 } |
|
352 |
|
353 int |
|
354 TcpL4Protocol::GetProtocolNumber (void) const |
|
355 { |
|
356 return PROT_NUMBER; |
|
357 } |
|
358 int |
|
359 TcpL4Protocol::GetVersion (void) const |
|
360 { |
|
361 return 2; |
|
362 } |
|
363 |
|
364 void |
|
365 TcpL4Protocol::DoDispose (void) |
|
366 { |
|
367 NS_LOG_FUNCTION_NOARGS (); |
|
368 if (m_endPoints != 0) |
|
369 { |
|
370 delete m_endPoints; |
|
371 m_endPoints = 0; |
|
372 } |
|
373 m_node = 0; |
|
374 Ipv4L4Protocol::DoDispose (); |
|
375 } |
|
376 |
|
377 Ptr<Socket> |
|
378 TcpL4Protocol::CreateSocket (void) |
|
379 { |
|
380 NS_LOG_FUNCTION_NOARGS (); |
|
381 Ptr<RttEstimator> rtt = m_rttFactory.Create<RttEstimator> (); |
|
382 Ptr<TcpSocketImpl> socket = CreateObject<TcpSocketImpl> (); |
|
383 socket->SetNode (m_node); |
|
384 socket->SetTcp (this); |
|
385 socket->SetRtt (rtt); |
|
386 return socket; |
|
387 } |
|
388 |
|
389 Ipv4EndPoint * |
|
390 TcpL4Protocol::Allocate (void) |
|
391 { |
|
392 NS_LOG_FUNCTION_NOARGS (); |
|
393 return m_endPoints->Allocate (); |
|
394 } |
|
395 |
|
396 Ipv4EndPoint * |
|
397 TcpL4Protocol::Allocate (Ipv4Address address) |
|
398 { |
|
399 NS_LOG_FUNCTION (this << address); |
|
400 return m_endPoints->Allocate (address); |
|
401 } |
|
402 |
|
403 Ipv4EndPoint * |
|
404 TcpL4Protocol::Allocate (uint16_t port) |
|
405 { |
|
406 NS_LOG_FUNCTION (this << port); |
|
407 return m_endPoints->Allocate (port); |
|
408 } |
|
409 |
|
410 Ipv4EndPoint * |
|
411 TcpL4Protocol::Allocate (Ipv4Address address, uint16_t port) |
|
412 { |
|
413 NS_LOG_FUNCTION (this << address << port); |
|
414 return m_endPoints->Allocate (address, port); |
|
415 } |
|
416 |
|
417 Ipv4EndPoint * |
|
418 TcpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort, |
|
419 Ipv4Address peerAddress, uint16_t peerPort) |
|
420 { |
|
421 NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort); |
|
422 return m_endPoints->Allocate (localAddress, localPort, |
|
423 peerAddress, peerPort); |
|
424 } |
|
425 |
|
426 void |
|
427 TcpL4Protocol::DeAllocate (Ipv4EndPoint *endPoint) |
|
428 { |
|
429 NS_LOG_FUNCTION (this << endPoint); |
|
430 m_endPoints->DeAllocate (endPoint); |
|
431 } |
|
432 |
|
433 void |
|
434 TcpL4Protocol::Receive (Ptr<Packet> packet, |
|
435 Ipv4Address const &source, |
|
436 Ipv4Address const &destination, |
|
437 Ptr<Ipv4Interface> incomingInterface) |
|
438 { |
|
439 NS_LOG_FUNCTION (this << packet << source << destination << incomingInterface); |
|
440 |
|
441 TcpHeader tcpHeader; |
|
442 //these two do a peek, so that the packet can be forwarded up |
|
443 packet->RemoveHeader (tcpHeader); |
|
444 NS_LOG_LOGIC("TcpL4Protocol " << this |
|
445 << " receiving seq " << tcpHeader.GetSequenceNumber() |
|
446 << " ack " << tcpHeader.GetAckNumber() |
|
447 << " flags "<< std::hex << (int)tcpHeader.GetFlags() << std::dec |
|
448 << " data size " << packet->GetSize()); |
|
449 packet->AddHeader (tcpHeader); |
|
450 NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" received a packet"); |
|
451 Ipv4EndPointDemux::EndPoints endPoints = |
|
452 m_endPoints->Lookup (destination, tcpHeader.GetDestinationPort (), |
|
453 source, tcpHeader.GetSourcePort (),incomingInterface); |
|
454 if (endPoints.empty ()) |
|
455 { |
|
456 NS_LOG_LOGIC (" No endpoints matched on TcpL4Protocol "<<this); |
|
457 std::ostringstream oss; |
|
458 oss<<" destination IP: "; |
|
459 destination.Print (oss); |
|
460 oss<<" destination port: "<< tcpHeader.GetDestinationPort ()<<" source IP: "; |
|
461 source.Print (oss); |
|
462 oss<<" source port: "<<tcpHeader.GetSourcePort (); |
|
463 NS_LOG_LOGIC (oss.str ()); |
|
464 return; |
|
465 } |
|
466 NS_ASSERT_MSG (endPoints.size() == 1 , "Demux returned more than one endpoint"); |
|
467 NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" forwarding up to endpoint/socket"); |
|
468 (*endPoints.begin ())->ForwardUp (packet, source, tcpHeader.GetSourcePort ()); |
|
469 } |
|
470 |
|
471 void |
|
472 TcpL4Protocol::Send (Ptr<Packet> packet, |
|
473 Ipv4Address saddr, Ipv4Address daddr, |
|
474 uint16_t sport, uint16_t dport) |
|
475 { |
|
476 NS_LOG_FUNCTION (this << packet << saddr << daddr << sport << dport); |
|
477 |
|
478 TcpHeader tcpHeader; |
|
479 tcpHeader.SetDestinationPort (dport); |
|
480 tcpHeader.SetSourcePort (sport); |
|
481 tcpHeader.InitializeChecksum (saddr, |
|
482 daddr, |
|
483 PROT_NUMBER); |
|
484 tcpHeader.SetFlags (TcpHeader::ACK); |
|
485 tcpHeader.SetAckNumber (0); |
|
486 |
|
487 packet->AddHeader (tcpHeader); |
|
488 |
|
489 Ptr<Ipv4L3Protocol> ipv4 = |
|
490 m_node->GetObject<Ipv4L3Protocol> (); |
|
491 if (ipv4 != 0) |
|
492 { |
|
493 ipv4->Send (packet, saddr, daddr, PROT_NUMBER); |
|
494 } |
|
495 } |
|
496 |
|
497 void |
|
498 TcpL4Protocol::SendPacket (Ptr<Packet> packet, TcpHeader outgoingHeader, |
|
499 Ipv4Address saddr, Ipv4Address daddr) |
|
500 { |
|
501 NS_LOG_LOGIC("TcpL4Protocol " << this |
|
502 << " sending seq " << outgoingHeader.GetSequenceNumber() |
|
503 << " ack " << outgoingHeader.GetAckNumber() |
|
504 << " flags " << std::hex << (int)outgoingHeader.GetFlags() << std::dec |
|
505 << " data size " << packet->GetSize()); |
|
506 NS_LOG_FUNCTION (this << packet << saddr << daddr); |
|
507 // XXX outgoingHeader cannot be logged |
|
508 |
|
509 outgoingHeader.SetLength (5); //header length in units of 32bit words |
|
510 outgoingHeader.SetChecksum (0); //XXX |
|
511 outgoingHeader.SetUrgentPointer (0); //XXX |
|
512 |
|
513 packet->AddHeader (outgoingHeader); |
|
514 |
|
515 Ptr<Ipv4L3Protocol> ipv4 = |
|
516 m_node->GetObject<Ipv4L3Protocol> (); |
|
517 if (ipv4 != 0) |
|
518 { |
|
519 ipv4->Send (packet, saddr, daddr, PROT_NUMBER); |
|
520 } |
|
521 else |
|
522 NS_FATAL_ERROR("Trying to use Tcp on a node without an Ipv4 interface"); |
|
523 } |
|
524 |
|
525 }; // namespace ns3 |
|
526 |