A Discrete-Event Network Simulator
Home
Tutorials ▼
English
Portuguese
Docs ▼
Wiki
Manual
Models
Develop ▼
API
Bugs
API
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Properties
Friends
Macros
Groups
Pages
packet-socket.cc
Go to the documentation of this file.
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
* Copyright (c) 2007 Emmanuelle Laprise, INRIA
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
* Authors: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
19
* Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
20
*/
21
22
#include "
packet-socket.h
"
23
#include "
packet-socket-address.h
"
24
#include "ns3/log.h"
25
#include "ns3/node.h"
26
#include "ns3/packet.h"
27
#include "ns3/uinteger.h"
28
#include "ns3/trace-source-accessor.h"
29
30
#include <algorithm>
31
32
NS_LOG_COMPONENT_DEFINE
(
"PacketSocket"
);
33
34
namespace
ns3 {
35
36
NS_OBJECT_ENSURE_REGISTERED
(PacketSocket);
37
38
TypeId
39
PacketSocket::GetTypeId
(
void
)
40
{
41
static
TypeId
tid =
TypeId
(
"ns3::PacketSocket"
)
42
.
SetParent
<
Socket
> ()
43
.AddConstructor<PacketSocket> ()
44
.AddTraceSource (
"Drop"
,
"Drop packet due to receive buffer overflow"
,
45
MakeTraceSourceAccessor
(&
PacketSocket::m_dropTrace
))
46
.AddAttribute (
"RcvBufSize"
,
47
"PacketSocket maximum receive buffer size (bytes)"
,
48
UintegerValue
(131072),
49
MakeUintegerAccessor (&
PacketSocket::m_rcvBufSize
),
50
MakeUintegerChecker<uint32_t> ())
51
;
52
return
tid;
53
}
54
55
PacketSocket::PacketSocket
() : m_rxAvailable (0)
56
{
57
NS_LOG_FUNCTION
(
this
);
58
m_state
=
STATE_OPEN
;
59
m_shutdownSend
=
false
;
60
m_shutdownRecv
=
false
;
61
m_errno
=
ERROR_NOTERROR
;
62
m_isSingleDevice
=
false
;
63
m_device
= 0;
64
}
65
66
void
67
PacketSocket::SetNode
(
Ptr<Node>
node)
68
{
69
NS_LOG_FUNCTION
(
this
<< node);
70
m_node
= node;
71
}
72
73
PacketSocket::~PacketSocket
()
74
{
75
NS_LOG_FUNCTION
(
this
);
76
}
77
78
void
79
PacketSocket::DoDispose
(
void
)
80
{
81
NS_LOG_FUNCTION
(
this
);
82
m_device
= 0;
83
}
84
85
enum
Socket::SocketErrno
86
PacketSocket::GetErrno
(
void
)
const
87
{
88
NS_LOG_FUNCTION
(
this
);
89
return
m_errno
;
90
}
91
92
enum
Socket::SocketType
93
PacketSocket::GetSocketType
(
void
)
const
94
{
95
return
NS3_SOCK_RAW
;
96
}
97
98
Ptr<Node>
99
PacketSocket::GetNode
(
void
)
const
100
{
101
NS_LOG_FUNCTION
(
this
);
102
return
m_node
;
103
}
104
105
int
106
PacketSocket::Bind
(
void
)
107
{
108
NS_LOG_FUNCTION
(
this
);
109
PacketSocketAddress
address;
110
address.
SetProtocol
(0);
111
address.
SetAllDevices
();
112
return
DoBind
(address);
113
}
114
115
int
116
PacketSocket::Bind6
(
void
)
117
{
118
return
(
Bind
());
119
}
120
121
int
122
PacketSocket::Bind
(
const
Address
&address)
123
{
124
NS_LOG_FUNCTION
(
this
<< address);
125
if
(!
PacketSocketAddress::IsMatchingType
(address))
126
{
127
m_errno
=
ERROR_INVAL
;
128
return
-1;
129
}
130
PacketSocketAddress
ad =
PacketSocketAddress::ConvertFrom
(address);
131
return
DoBind
(ad);
132
}
133
134
int
135
PacketSocket::DoBind
(
const
PacketSocketAddress
&address)
136
{
137
NS_LOG_FUNCTION
(
this
<< address);
138
if
(
m_state
==
STATE_BOUND
||
139
m_state
==
STATE_CONNECTED
)
140
{
141
m_errno
=
ERROR_INVAL
;
142
return
-1;
143
}
144
if
(
m_state
==
STATE_CLOSED
)
145
{
146
m_errno
=
ERROR_BADF
;
147
return
-1;
148
}
149
Ptr<NetDevice>
dev;
150
if
(address.
IsSingleDevice
())
151
{
152
dev =
m_node
->
GetDevice
(address.
GetSingleDevice
());
153
}
154
else
155
{
156
dev = 0;
157
}
158
m_node
->
RegisterProtocolHandler
(
MakeCallback
(&
PacketSocket::ForwardUp
,
this
),
159
address.
GetProtocol
(), dev);
160
m_state
=
STATE_BOUND
;
161
m_protocol
= address.
GetProtocol
();
162
m_isSingleDevice
= address.
IsSingleDevice
();
163
m_device
= address.
GetSingleDevice
();
164
return
0;
165
}
166
167
int
168
PacketSocket::ShutdownSend
(
void
)
169
{
170
NS_LOG_FUNCTION
(
this
);
171
if
(
m_state
==
STATE_CLOSED
)
172
{
173
m_errno
=
ERROR_BADF
;
174
return
-1;
175
}
176
m_shutdownSend
=
true
;
177
return
0;
178
}
179
180
int
181
PacketSocket::ShutdownRecv
(
void
)
182
{
183
NS_LOG_FUNCTION
(
this
);
184
if
(
m_state
==
STATE_CLOSED
)
185
{
186
m_errno
=
ERROR_BADF
;
187
return
-1;
188
}
189
m_shutdownRecv
=
true
;
190
return
0;
191
}
192
193
int
194
PacketSocket::Close
(
void
)
195
{
196
NS_LOG_FUNCTION
(
this
);
197
if
(
m_state
==
STATE_CLOSED
)
198
{
199
m_errno
=
ERROR_BADF
;
200
return
-1;
201
}
202
else
if
(
m_state
==
STATE_BOUND
||
m_state
==
STATE_CONNECTED
)
203
{
204
m_node
->
UnregisterProtocolHandler
(
MakeCallback
(&
PacketSocket::ForwardUp
,
this
));
205
}
206
m_state
=
STATE_CLOSED
;
207
m_shutdownSend
=
true
;
208
m_shutdownRecv
=
true
;
209
return
0;
210
}
211
212
int
213
PacketSocket::Connect
(
const
Address
&ad)
214
{
215
NS_LOG_FUNCTION
(
this
<< ad);
216
PacketSocketAddress
address;
217
if
(
m_state
==
STATE_CLOSED
)
218
{
219
m_errno
=
ERROR_BADF
;
220
goto
error;
221
}
222
if
(
m_state
==
STATE_OPEN
)
223
{
224
// connect should happen _after_ bind.
225
m_errno
=
ERROR_INVAL
;
// generic error condition.
226
goto
error;
227
}
228
if
(
m_state
==
STATE_CONNECTED
)
229
{
230
m_errno
=
ERROR_ISCONN
;
231
goto
error;
232
}
233
if
(!
PacketSocketAddress::IsMatchingType
(ad))
234
{
235
m_errno
=
ERROR_AFNOSUPPORT
;
236
goto
error;
237
}
238
m_destAddr
= ad;
239
m_state
=
STATE_CONNECTED
;
240
NotifyConnectionSucceeded
();
241
return
0;
242
error:
243
NotifyConnectionFailed
();
244
return
-1;
245
}
246
int
247
PacketSocket::Listen
(
void
)
248
{
249
m_errno
=
Socket::ERROR_OPNOTSUPP
;
250
return
-1;
251
}
252
253
int
254
PacketSocket::Send
(
Ptr<Packet>
p, uint32_t flags)
255
{
256
NS_LOG_FUNCTION
(
this
<< p << flags);
257
if
(
m_state
==
STATE_OPEN
||
258
m_state
==
STATE_BOUND
)
259
{
260
m_errno
=
ERROR_NOTCONN
;
261
return
-1;
262
}
263
return
SendTo
(p, flags,
m_destAddr
);
264
}
265
266
uint32_t
267
PacketSocket::GetMinMtu
(
PacketSocketAddress
ad)
const
268
{
269
if
(ad.
IsSingleDevice
())
270
{
271
Ptr<NetDevice>
device =
m_node
->
GetDevice
(ad.
GetSingleDevice
());
272
return
device->
GetMtu
();
273
}
274
else
275
{
276
uint32_t minMtu = 0xffff;
277
for
(uint32_t i = 0; i <
m_node
->
GetNDevices
(); i++)
278
{
279
Ptr<NetDevice>
device =
m_node
->
GetDevice
(i);
280
minMtu = std::min (minMtu, (uint32_t)device->
GetMtu
());
281
}
282
return
minMtu;
283
}
284
}
285
286
uint32_t
287
PacketSocket::GetTxAvailable
(
void
)
const
288
{
289
if
(
m_state
==
STATE_CONNECTED
)
290
{
291
PacketSocketAddress
ad =
PacketSocketAddress::ConvertFrom
(
m_destAddr
);
292
return
GetMinMtu
(ad);
293
}
294
// If we are not connected, we return a 'safe' value by default.
295
return
0xffff;
296
}
297
298
int
299
PacketSocket::SendTo
(
Ptr<Packet>
p, uint32_t flags,
const
Address
&address)
300
{
301
NS_LOG_FUNCTION
(
this
<< p << flags << address);
302
PacketSocketAddress
ad;
303
if
(
m_state
==
STATE_CLOSED
)
304
{
305
NS_LOG_LOGIC
(
"ERROR_BADF"
);
306
m_errno
=
ERROR_BADF
;
307
return
-1;
308
}
309
if
(
m_shutdownSend
)
310
{
311
NS_LOG_LOGIC
(
"ERROR_SHUTDOWN"
);
312
m_errno
=
ERROR_SHUTDOWN
;
313
return
-1;
314
}
315
if
(!
PacketSocketAddress::IsMatchingType
(address))
316
{
317
NS_LOG_LOGIC
(
"ERROR_AFNOSUPPORT"
);
318
m_errno
=
ERROR_AFNOSUPPORT
;
319
return
-1;
320
}
321
ad =
PacketSocketAddress::ConvertFrom
(address);
322
if
(p->
GetSize
() >
GetMinMtu
(ad))
323
{
324
m_errno
=
ERROR_MSGSIZE
;
325
return
-1;
326
}
327
328
bool
error =
false
;
329
Address
dest = ad.
GetPhysicalAddress
();
330
if
(ad.
IsSingleDevice
())
331
{
332
Ptr<NetDevice>
device =
m_node
->
GetDevice
(ad.
GetSingleDevice
());
333
if
(!device->
Send
(p, dest, ad.
GetProtocol
()))
334
{
335
NS_LOG_LOGIC
(
"error: NetDevice::Send error"
);
336
error =
true
;
337
}
338
}
339
else
340
{
341
for
(uint32_t i = 0; i <
m_node
->
GetNDevices
(); i++)
342
{
343
Ptr<NetDevice>
device =
m_node
->
GetDevice
(i);
344
if
(!device->
Send
(p, dest, ad.
GetProtocol
()))
345
{
346
NS_LOG_LOGIC
(
"error: NetDevice::Send error"
);
347
error =
true
;
348
}
349
}
350
}
351
if
(!error)
352
{
353
NotifyDataSent
(p->
GetSize
());
354
NotifySend
(
GetTxAvailable
());
355
}
356
357
if
(error)
358
{
359
NS_LOG_LOGIC
(
"ERROR_INVAL 2"
);
360
m_errno
=
ERROR_INVAL
;
361
return
-1;
362
}
363
else
364
{
365
return
p->
GetSize
();
366
}
367
}
368
369
void
370
PacketSocket::ForwardUp
(
Ptr<NetDevice>
device,
Ptr<const Packet>
packet,
371
uint16_t protocol,
const
Address
&from,
372
const
Address
&to,
NetDevice::PacketType
packetType)
373
{
374
NS_LOG_FUNCTION
(
this
<< device << packet << protocol << from << to << packetType);
375
if
(
m_shutdownRecv
)
376
{
377
return
;
378
}
379
380
381
PacketSocketAddress
address;
382
address.
SetPhysicalAddress
(from);
383
address.
SetSingleDevice
(device->
GetIfIndex
());
384
address.
SetProtocol
(protocol);
385
386
if
((
m_rxAvailable
+ packet->
GetSize
()) <=
m_rcvBufSize
)
387
{
388
Ptr<Packet>
copy = packet->
Copy
();
389
SocketAddressTag
tag;
390
tag.
SetAddress
(address);
391
copy->
AddPacketTag
(tag);
392
m_deliveryQueue
.push (copy);
393
m_rxAvailable
+= packet->
GetSize
();
394
NS_LOG_LOGIC
(
"UID is "
<< packet->
GetUid
() <<
" PacketSocket "
<<
this
);
395
NotifyDataRecv
();
396
}
397
else
398
{
399
// In general, this case should not occur unless the
400
// receiving application reads data from this socket slowly
401
// in comparison to the arrival rate
402
//
403
// drop and trace packet
404
NS_LOG_WARN
(
"No receive buffer space available. Drop."
);
405
m_dropTrace
(packet);
406
}
407
}
408
409
uint32_t
410
PacketSocket::GetRxAvailable
(
void
)
const
411
{
412
NS_LOG_FUNCTION
(
this
);
413
// We separately maintain this state to avoid walking the queue
414
// every time this might be called
415
return
m_rxAvailable
;
416
}
417
418
Ptr<Packet>
419
PacketSocket::Recv
(uint32_t maxSize, uint32_t flags)
420
{
421
NS_LOG_FUNCTION
(
this
<< maxSize << flags);
422
if
(
m_deliveryQueue
.empty () )
423
{
424
return
0;
425
}
426
Ptr<Packet>
p =
m_deliveryQueue
.front ();
427
if
(p->
GetSize
() <= maxSize)
428
{
429
m_deliveryQueue
.pop ();
430
m_rxAvailable
-= p->
GetSize
();
431
}
432
else
433
{
434
p = 0;
435
}
436
return
p;
437
}
438
439
Ptr<Packet>
440
PacketSocket::RecvFrom
(uint32_t maxSize, uint32_t flags,
Address
&fromAddress)
441
{
442
NS_LOG_FUNCTION
(
this
<< maxSize << flags << fromAddress);
443
Ptr<Packet>
packet =
Recv
(maxSize, flags);
444
if
(packet != 0)
445
{
446
SocketAddressTag
tag;
447
bool
found;
448
found = packet->
PeekPacketTag
(tag);
449
NS_ASSERT
(found);
450
fromAddress = tag.
GetAddress
();
451
}
452
return
packet;
453
}
454
455
int
456
PacketSocket::GetSockName
(
Address
&address)
const
457
{
458
NS_LOG_FUNCTION
(
this
<< address);
459
PacketSocketAddress
ad =
PacketSocketAddress::ConvertFrom
(address);
460
461
ad.
SetProtocol
(
m_protocol
);
462
if
(
m_isSingleDevice
)
463
{
464
Ptr<NetDevice>
device =
m_node
->
GetDevice
(ad.
GetSingleDevice
());
465
ad.
SetPhysicalAddress
(device->
GetAddress
());
466
ad.
SetSingleDevice
(
m_device
);
467
}
468
else
469
{
470
ad.
SetPhysicalAddress
(
Address
());
471
ad.
SetAllDevices
();
472
}
473
address = ad;
474
475
return
0;
476
}
477
478
bool
479
PacketSocket::SetAllowBroadcast
(
bool
allowBroadcast)
480
{
481
if
(allowBroadcast)
482
{
483
return
false
;
484
}
485
return
true
;
486
}
487
488
bool
489
PacketSocket::GetAllowBroadcast
()
const
490
{
491
return
false
;
492
}
493
494
}
// namespace ns3
src
network
utils
packet-socket.cc
Generated on Tue Oct 9 2012 16:45:44 for ns-3 by
1.8.1.2