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
NS_LOG_FUNCTION
(
this
);
96
return
NS3_SOCK_RAW
;
97
}
98
99
Ptr<Node>
100
PacketSocket::GetNode
(
void
)
const
101
{
102
NS_LOG_FUNCTION
(
this
);
103
return
m_node
;
104
}
105
106
int
107
PacketSocket::Bind
(
void
)
108
{
109
NS_LOG_FUNCTION
(
this
);
110
PacketSocketAddress
address;
111
address.
SetProtocol
(0);
112
address.
SetAllDevices
();
113
return
DoBind
(address);
114
}
115
116
int
117
PacketSocket::Bind6
(
void
)
118
{
119
NS_LOG_FUNCTION
(
this
);
120
return
(
Bind
());
121
}
122
123
int
124
PacketSocket::Bind
(
const
Address
&address)
125
{
126
NS_LOG_FUNCTION
(
this
<< address);
127
if
(!
PacketSocketAddress::IsMatchingType
(address))
128
{
129
m_errno
=
ERROR_INVAL
;
130
return
-1;
131
}
132
PacketSocketAddress
ad =
PacketSocketAddress::ConvertFrom
(address);
133
return
DoBind
(ad);
134
}
135
136
int
137
PacketSocket::DoBind
(
const
PacketSocketAddress
&address)
138
{
139
NS_LOG_FUNCTION
(
this
<< address);
140
if
(
m_state
==
STATE_BOUND
||
141
m_state
==
STATE_CONNECTED
)
142
{
143
m_errno
=
ERROR_INVAL
;
144
return
-1;
145
}
146
if
(
m_state
==
STATE_CLOSED
)
147
{
148
m_errno
=
ERROR_BADF
;
149
return
-1;
150
}
151
Ptr<NetDevice>
dev;
152
if
(address.
IsSingleDevice
())
153
{
154
dev =
m_node
->
GetDevice
(address.
GetSingleDevice
());
155
}
156
else
157
{
158
dev = 0;
159
}
160
m_node
->
RegisterProtocolHandler
(
MakeCallback
(&
PacketSocket::ForwardUp
,
this
),
161
address.
GetProtocol
(), dev);
162
m_state
=
STATE_BOUND
;
163
m_protocol
= address.
GetProtocol
();
164
m_isSingleDevice
= address.
IsSingleDevice
();
165
m_device
= address.
GetSingleDevice
();
166
return
0;
167
}
168
169
int
170
PacketSocket::ShutdownSend
(
void
)
171
{
172
NS_LOG_FUNCTION
(
this
);
173
if
(
m_state
==
STATE_CLOSED
)
174
{
175
m_errno
=
ERROR_BADF
;
176
return
-1;
177
}
178
m_shutdownSend
=
true
;
179
return
0;
180
}
181
182
int
183
PacketSocket::ShutdownRecv
(
void
)
184
{
185
NS_LOG_FUNCTION
(
this
);
186
if
(
m_state
==
STATE_CLOSED
)
187
{
188
m_errno
=
ERROR_BADF
;
189
return
-1;
190
}
191
m_shutdownRecv
=
true
;
192
return
0;
193
}
194
195
int
196
PacketSocket::Close
(
void
)
197
{
198
NS_LOG_FUNCTION
(
this
);
199
if
(
m_state
==
STATE_CLOSED
)
200
{
201
m_errno
=
ERROR_BADF
;
202
return
-1;
203
}
204
else
if
(
m_state
==
STATE_BOUND
||
m_state
==
STATE_CONNECTED
)
205
{
206
m_node
->
UnregisterProtocolHandler
(
MakeCallback
(&
PacketSocket::ForwardUp
,
this
));
207
}
208
m_state
=
STATE_CLOSED
;
209
m_shutdownSend
=
true
;
210
m_shutdownRecv
=
true
;
211
return
0;
212
}
213
214
int
215
PacketSocket::Connect
(
const
Address
&ad)
216
{
217
NS_LOG_FUNCTION
(
this
<< ad);
218
PacketSocketAddress
address;
219
if
(
m_state
==
STATE_CLOSED
)
220
{
221
m_errno
=
ERROR_BADF
;
222
goto
error;
223
}
224
if
(
m_state
==
STATE_OPEN
)
225
{
226
// connect should happen _after_ bind.
227
m_errno
=
ERROR_INVAL
;
// generic error condition.
228
goto
error;
229
}
230
if
(
m_state
==
STATE_CONNECTED
)
231
{
232
m_errno
=
ERROR_ISCONN
;
233
goto
error;
234
}
235
if
(!
PacketSocketAddress::IsMatchingType
(ad))
236
{
237
m_errno
=
ERROR_AFNOSUPPORT
;
238
goto
error;
239
}
240
m_destAddr
= ad;
241
m_state
=
STATE_CONNECTED
;
242
NotifyConnectionSucceeded
();
243
return
0;
244
error:
245
NotifyConnectionFailed
();
246
return
-1;
247
}
248
int
249
PacketSocket::Listen
(
void
)
250
{
251
NS_LOG_FUNCTION
(
this
);
252
m_errno
=
Socket::ERROR_OPNOTSUPP
;
253
return
-1;
254
}
255
256
int
257
PacketSocket::Send
(
Ptr<Packet>
p, uint32_t flags)
258
{
259
NS_LOG_FUNCTION
(
this
<< p << flags);
260
if
(
m_state
==
STATE_OPEN
||
261
m_state
==
STATE_BOUND
)
262
{
263
m_errno
=
ERROR_NOTCONN
;
264
return
-1;
265
}
266
return
SendTo
(p, flags,
m_destAddr
);
267
}
268
269
uint32_t
270
PacketSocket::GetMinMtu
(
PacketSocketAddress
ad)
const
271
{
272
NS_LOG_FUNCTION
(
this
<< ad);
273
if
(ad.
IsSingleDevice
())
274
{
275
Ptr<NetDevice>
device =
m_node
->
GetDevice
(ad.
GetSingleDevice
());
276
return
device->
GetMtu
();
277
}
278
else
279
{
280
uint32_t minMtu = 0xffff;
281
for
(uint32_t i = 0; i <
m_node
->
GetNDevices
(); i++)
282
{
283
Ptr<NetDevice>
device =
m_node
->
GetDevice
(i);
284
minMtu = std::min (minMtu, (uint32_t)device->
GetMtu
());
285
}
286
return
minMtu;
287
}
288
}
289
290
uint32_t
291
PacketSocket::GetTxAvailable
(
void
)
const
292
{
293
NS_LOG_FUNCTION
(
this
);
294
if
(
m_state
==
STATE_CONNECTED
)
295
{
296
PacketSocketAddress
ad =
PacketSocketAddress::ConvertFrom
(
m_destAddr
);
297
return
GetMinMtu
(ad);
298
}
299
// If we are not connected, we return a 'safe' value by default.
300
return
0xffff;
301
}
302
303
int
304
PacketSocket::SendTo
(
Ptr<Packet>
p, uint32_t flags,
const
Address
&address)
305
{
306
NS_LOG_FUNCTION
(
this
<< p << flags << address);
307
PacketSocketAddress
ad;
308
if
(
m_state
==
STATE_CLOSED
)
309
{
310
NS_LOG_LOGIC
(
"ERROR_BADF"
);
311
m_errno
=
ERROR_BADF
;
312
return
-1;
313
}
314
if
(
m_shutdownSend
)
315
{
316
NS_LOG_LOGIC
(
"ERROR_SHUTDOWN"
);
317
m_errno
=
ERROR_SHUTDOWN
;
318
return
-1;
319
}
320
if
(!
PacketSocketAddress::IsMatchingType
(address))
321
{
322
NS_LOG_LOGIC
(
"ERROR_AFNOSUPPORT"
);
323
m_errno
=
ERROR_AFNOSUPPORT
;
324
return
-1;
325
}
326
ad =
PacketSocketAddress::ConvertFrom
(address);
327
if
(p->
GetSize
() >
GetMinMtu
(ad))
328
{
329
m_errno
=
ERROR_MSGSIZE
;
330
return
-1;
331
}
332
333
bool
error =
false
;
334
Address
dest = ad.
GetPhysicalAddress
();
335
if
(ad.
IsSingleDevice
())
336
{
337
Ptr<NetDevice>
device =
m_node
->
GetDevice
(ad.
GetSingleDevice
());
338
if
(!device->
Send
(p, dest, ad.
GetProtocol
()))
339
{
340
NS_LOG_LOGIC
(
"error: NetDevice::Send error"
);
341
error =
true
;
342
}
343
}
344
else
345
{
346
for
(uint32_t i = 0; i <
m_node
->
GetNDevices
(); i++)
347
{
348
Ptr<NetDevice>
device =
m_node
->
GetDevice
(i);
349
if
(!device->
Send
(p, dest, ad.
GetProtocol
()))
350
{
351
NS_LOG_LOGIC
(
"error: NetDevice::Send error"
);
352
error =
true
;
353
}
354
}
355
}
356
if
(!error)
357
{
358
NotifyDataSent
(p->
GetSize
());
359
NotifySend
(
GetTxAvailable
());
360
}
361
362
if
(error)
363
{
364
NS_LOG_LOGIC
(
"ERROR_INVAL 2"
);
365
m_errno
=
ERROR_INVAL
;
366
return
-1;
367
}
368
else
369
{
370
return
p->
GetSize
();
371
}
372
}
373
374
void
375
PacketSocket::ForwardUp
(
Ptr<NetDevice>
device,
Ptr<const Packet>
packet,
376
uint16_t protocol,
const
Address
&from,
377
const
Address
&to,
NetDevice::PacketType
packetType)
378
{
379
NS_LOG_FUNCTION
(
this
<< device << packet << protocol << from << to << packetType);
380
if
(
m_shutdownRecv
)
381
{
382
return
;
383
}
384
385
386
PacketSocketAddress
address;
387
address.
SetPhysicalAddress
(from);
388
address.
SetSingleDevice
(device->
GetIfIndex
());
389
address.
SetProtocol
(protocol);
390
391
if
((
m_rxAvailable
+ packet->
GetSize
()) <=
m_rcvBufSize
)
392
{
393
Ptr<Packet>
copy = packet->
Copy
();
394
SocketAddressTag
tag;
395
tag.
SetAddress
(address);
396
copy->
AddPacketTag
(tag);
397
m_deliveryQueue
.push (copy);
398
m_rxAvailable
+= packet->
GetSize
();
399
NS_LOG_LOGIC
(
"UID is "
<< packet->
GetUid
() <<
" PacketSocket "
<<
this
);
400
NotifyDataRecv
();
401
}
402
else
403
{
404
// In general, this case should not occur unless the
405
// receiving application reads data from this socket slowly
406
// in comparison to the arrival rate
407
//
408
// drop and trace packet
409
NS_LOG_WARN
(
"No receive buffer space available. Drop."
);
410
m_dropTrace
(packet);
411
}
412
}
413
414
uint32_t
415
PacketSocket::GetRxAvailable
(
void
)
const
416
{
417
NS_LOG_FUNCTION
(
this
);
418
// We separately maintain this state to avoid walking the queue
419
// every time this might be called
420
return
m_rxAvailable
;
421
}
422
423
Ptr<Packet>
424
PacketSocket::Recv
(uint32_t maxSize, uint32_t flags)
425
{
426
NS_LOG_FUNCTION
(
this
<< maxSize << flags);
427
if
(
m_deliveryQueue
.empty () )
428
{
429
return
0;
430
}
431
Ptr<Packet>
p =
m_deliveryQueue
.front ();
432
if
(p->
GetSize
() <= maxSize)
433
{
434
m_deliveryQueue
.pop ();
435
m_rxAvailable
-= p->
GetSize
();
436
}
437
else
438
{
439
p = 0;
440
}
441
return
p;
442
}
443
444
Ptr<Packet>
445
PacketSocket::RecvFrom
(uint32_t maxSize, uint32_t flags,
Address
&fromAddress)
446
{
447
NS_LOG_FUNCTION
(
this
<< maxSize << flags << fromAddress);
448
Ptr<Packet>
packet =
Recv
(maxSize, flags);
449
if
(packet != 0)
450
{
451
SocketAddressTag
tag;
452
bool
found;
453
found = packet->
PeekPacketTag
(tag);
454
NS_ASSERT
(found);
455
fromAddress = tag.
GetAddress
();
456
}
457
return
packet;
458
}
459
460
int
461
PacketSocket::GetSockName
(
Address
&address)
const
462
{
463
NS_LOG_FUNCTION
(
this
<< address);
464
PacketSocketAddress
ad =
PacketSocketAddress::ConvertFrom
(address);
465
466
ad.
SetProtocol
(
m_protocol
);
467
if
(
m_isSingleDevice
)
468
{
469
Ptr<NetDevice>
device =
m_node
->
GetDevice
(ad.
GetSingleDevice
());
470
ad.
SetPhysicalAddress
(device->
GetAddress
());
471
ad.
SetSingleDevice
(
m_device
);
472
}
473
else
474
{
475
ad.
SetPhysicalAddress
(
Address
());
476
ad.
SetAllDevices
();
477
}
478
address = ad;
479
480
return
0;
481
}
482
483
bool
484
PacketSocket::SetAllowBroadcast
(
bool
allowBroadcast)
485
{
486
NS_LOG_FUNCTION
(
this
<< allowBroadcast);
487
if
(allowBroadcast)
488
{
489
return
false
;
490
}
491
return
true
;
492
}
493
494
bool
495
PacketSocket::GetAllowBroadcast
()
const
496
{
497
NS_LOG_FUNCTION
(
this
);
498
return
false
;
499
}
500
501
}
// namespace ns3
src
network
utils
packet-socket.cc
Generated on Fri Dec 21 2012 19:00:44 for ns-3 by
1.8.1.2