ns-3 Direct Code Execution
Home
Tutorials ▼
Docs ▼
Wiki
Manual
Develop ▼
API
Bugs
API
Main Page
Related Pages
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Pages
local-socket-fd.cc
Go to the documentation of this file.
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
* Copyright (c) 2011 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
* Author: Frederic Urbani <frederic.urbani@inria.fr>
19
*
20
*/
21
#include "
local-socket-fd.h
"
22
#include "
local-socket-fd-factory.h
"
23
#include "
utils.h
"
24
#include "
process.h
"
25
#include "ns3/log.h"
26
#include <errno.h>
27
#include <fcntl.h>
28
#include <sys/mman.h>
// for MAP_FAILED
29
#include <sys/un.h>
30
#include "
unix-fd.h
"
31
#include <exception>
32
#include "poll.h"
33
34
NS_LOG_COMPONENT_DEFINE
(
"LocalSocketFd"
);
35
36
namespace
ns3 {
37
TypeId
38
LocalSocketFd::GetTypeId
(
void
)
39
{
40
static
TypeId tid = TypeId (
"ns3::LocalSocketFd"
).SetParent<
UnixFd
> ();
41
42
return
tid;
43
}
44
TypeId
45
LocalSocketFd::GetInstanceTypeId
(
void
)
const
46
{
47
return
LocalSocketFd::GetTypeId
();
48
}
49
LocalSocketFd::LocalSocketFd
() : m_readBuffer (0),
50
m_readBufferSize (0),
51
m_sendTimeout (0),
52
m_recvTimeout (0),
53
m_factory (0),
54
m_linger (0),
55
m_bindPath (
""
),
56
m_connectPath (
""
),
57
m_shutRead (false),
58
m_shutWrite (false)
59
{
60
}
61
LocalSocketFd::~LocalSocketFd
()
62
{
63
64
}
65
bool
66
LocalSocketFd::Isatty
(
void
)
const
67
{
68
return
false
;
69
}
70
int
71
LocalSocketFd::Setsockopt
(
int
level,
int
optname,
const
void
*optval, socklen_t optlen)
72
{
73
Thread
*current =
Current
();
74
NS_LOG_FUNCTION (
this
<< current << level << optname << optval << optlen);
75
NS_ASSERT (current != 0);
76
77
if
(level != SOL_SOCKET)
78
{
79
current->
err
= EINVAL;
80
return
-1;
81
}
82
83
switch
(optname)
84
{
85
86
case
SO_LINGER:
87
{
88
if
((0 == optval) || (0 == optlen) || (optlen <
sizeof
(
struct
linger)))
89
{
90
current->
err
= EINVAL;
91
return
-1;
92
}
93
if
(((
struct
linger *) optval)->l_onoff != 0)
94
{
95
m_linger
= (((
struct
linger *) optval)->l_linger);
96
}
97
else
98
{
99
m_linger
= 0;
100
}
101
}
102
break
;
103
104
case
SO_PASSCRED:
105
{
106
NS_LOG_DEBUG (
"LocalSocketFd SO_PASSCRED NOT IMPLEMENTED"
);
107
current->
err
= EINVAL;
108
return
-1;
109
}
110
111
case
SO_RCVBUF:
112
case
SO_SNDBUF:
113
{
114
NS_LOG_DEBUG (
"LocalSocketFd SO_RCVBUF and SO_SNDBUF ignored."
);
115
return
0;
116
}
117
case
SO_RCVLOWAT:
118
{
119
NS_LOG_DEBUG (
"LocalSocketFd SO_RCVLOWAT ignored."
);
120
return
0;
121
}
122
case
SO_SNDLOWAT:
123
{
124
NS_LOG_DEBUG (
"LocalSocketFd SO_SNDLOWAT ignored."
);
125
return
0;
126
}
127
128
case
SO_RCVTIMEO:
129
{
130
if
((0 == optval) || (0 == optlen) || (optlen <
sizeof
(
struct
timeval)))
131
{
132
current->
err
= EINVAL;
133
return
-1;
134
}
135
136
m_recvTimeout
=
UtilsTimevalToTime
((
struct
timeval *) optval);
137
138
return
0;
139
}
140
141
case
SO_SNDTIMEO:
142
{
143
if
((0 == optval) || (0 == optlen) || (optlen <
sizeof
(
struct
timeval)))
144
{
145
current->
err
= EINVAL;
146
return
-1;
147
}
148
149
m_sendTimeout
=
UtilsTimevalToTime
((
struct
timeval *) optval);
150
151
return
0;
152
}
153
154
default
:
155
break
;
156
}
157
current->
err
= EINVAL;
158
return
-1;
159
}
160
int
161
LocalSocketFd::Ioctl
(
int
request,
char
*argp)
162
{
163
Current
()->
err
= EINVAL;
164
return
-1;
165
}
166
void
*
167
LocalSocketFd::Mmap
(
void
*start,
size_t
length,
int
prot,
int
flags, off64_t offset)
168
{
169
GET_CURRENT
(start << length << prot << flags << offset);
170
current->err = ENODEV;
171
return
MAP_FAILED;
172
}
173
off64_t
174
LocalSocketFd::Lseek
(off64_t offset,
int
whence)
175
{
176
GET_CURRENT
(offset << whence);
177
current->err = ESPIPE;
178
return
-1;
179
}
180
int
181
LocalSocketFd::Fxstat
(
int
ver, struct ::stat *buf)
182
{
183
GET_CURRENT
(ver << buf);
184
buf->st_mode = S_IFSOCK;
185
buf->st_dev = -1;
186
buf->st_blksize = 0;
187
return
0;
188
}
189
int
190
LocalSocketFd::Fxstat64
(
int
ver, struct ::stat64 *buf)
191
{
192
GET_CURRENT
(ver << buf);
193
buf->st_mode = S_IFSOCK;
194
buf->st_dev = -1;
195
buf->st_blksize = 0;
196
return
0;
197
}
198
int
199
LocalSocketFd::Fcntl
(
int
cmd,
unsigned
long
arg)
200
{
201
return
UnixFd::Fcntl
(cmd, arg);
202
}
203
int
204
LocalSocketFd::Settime
(
int
flags,
const
struct
itimerspec *new_value,
struct
itimerspec *old_value)
205
{
206
NS_LOG_FUNCTION (
this
<<
Current
() << flags << new_value << old_value);
207
NS_ASSERT (
Current
() != 0);
208
Thread
*current =
Current
();
209
current->
err
= EINVAL;
210
return
-1;
211
}
212
int
213
LocalSocketFd::Gettime
(
struct
itimerspec *cur_value)
const
214
{
215
NS_LOG_FUNCTION (
this
<<
Current
() << cur_value);
216
NS_ASSERT (
Current
() != 0);
217
Thread
*current =
Current
();
218
current->
err
= EINVAL;
219
return
-1;
220
}
221
Time
222
LocalSocketFd::GetRecvTimeout
(
void
)
223
{
224
return
m_recvTimeout
;
225
}
226
Time
227
LocalSocketFd::GetSendTimeout
(
void
)
228
{
229
return
m_sendTimeout
;
230
}
231
232
// Return :
233
// the size readed ,
234
// or 0 if no more space available,
235
// or -1 if fatal error occurs
236
ssize_t
237
LocalSocketFd::DoRecvPacket
(uint8_t* buf,
size_t
len)
238
{
239
NS_LOG_FUNCTION (
this
<< len <<
" shutRead:"
<<
m_shutRead
<<
"Closed:"
<<
IsClosed
());
240
241
if
((
m_shutRead
)||
IsClosed
())
242
{
243
return
-2;
244
}
245
if
(
m_readBufferSize
>=
LOCAL_SOCKET_MAX_BUFFER
)
246
{
247
return
0;
248
}
249
250
size_t
maxi =
LOCAL_SOCKET_MAX_BUFFER
-
m_readBufferSize
;
251
252
int
l = std::min (maxi, len);
253
254
struct
Buffer
*myBuf =
new
struct
Buffer
;
255
256
myBuf->
data
= (uint8_t*) malloc (l);
257
if
(0 == myBuf->
data
)
258
{
259
Thread
*current =
Current
();
260
NS_ASSERT (current != 0);
261
current->
err
= ENOMEM;
262
return
-1;
263
}
264
myBuf->
readOffset
= 0;
265
myBuf->
size
= l;
266
267
memcpy (myBuf->
data
, buf, l);
268
269
m_readBuffer
.push_back (myBuf);
270
271
m_readBufferSize += l;
272
273
NS_LOG_DEBUG (
"DoRecvPacket before WakeUpRecv"
);
274
275
short
pi = POLLIN;
276
WakeWaiters
(&pi);
// WakeUp reader or poller for read or select for read
277
278
return
l;
279
}
280
281
size_t
282
LocalSocketFd::ReadData
(uint8_t* buf,
size_t
len,
bool
peek)
283
{
284
size_t
fill = 0;
285
size_t
rest = len;
286
287
if
(peek)
288
{
289
for
(std::list<struct Buffer*>::iterator i =
m_readBuffer
.begin (); i !=
m_readBuffer
.end (); ++i)
290
{
291
if
((fill >= len) || (rest <= 0))
292
{
293
break
;
294
}
295
296
struct
Buffer
* myBuf = *i;
297
298
size_t
avail = std::min (rest, myBuf->
size
- myBuf->
readOffset
);
299
NS_LOG_DEBUG (
"ReadData avail:"
<< avail <<
" offset:"
<< myBuf->
readOffset
<<
" size:"
<< myBuf->
size
);
300
301
if
(avail > 0)
302
{
303
memcpy (buf + fill, myBuf->
data
+ myBuf->
readOffset
, avail);
304
fill += avail;
305
rest -= avail;
306
}
307
}
308
}
309
else
310
{
311
while
((fill < len) && (
m_readBuffer
.size () > 0) && (rest > 0))
312
{
313
struct
Buffer
* myBuf =
m_readBuffer
.front ();
314
315
size_t
avail = std::min (rest, myBuf->
size
- myBuf->
readOffset
);
316
NS_LOG_DEBUG (
"ReadData avail:"
<< avail <<
" offset:"
<< myBuf->
readOffset
<<
" size:"
<< myBuf->
size
);
317
318
if
(avail > 0)
319
{
320
memcpy (buf + fill, myBuf->
data
+ myBuf->
readOffset
, avail);
321
fill += avail;
322
rest -= avail;
323
324
m_readBufferSize
-= avail;
325
myBuf->
readOffset
+= avail;
326
327
if
(myBuf->
readOffset
>= myBuf->
size
)
328
{
329
free (myBuf->
data
);
330
myBuf->
data
= 0;
331
m_readBuffer
.pop_front ();
332
delete
myBuf;
333
}
334
}
335
else
336
{
337
break
;
338
}
339
}
340
}
341
return
fill;
342
}
343
344
void
345
LocalSocketFd::ClearReadBuffer
(
void
)
346
{
347
NS_LOG_FUNCTION (
this
);
348
for
(std::list<struct Buffer *>::iterator i =
m_readBuffer
.begin (); i !=
m_readBuffer
.end (); ++i)
349
{
350
struct
Buffer
*b = *i;
351
if
(0 != b->
data
)
352
{
353
free (b->
data
);
354
}
355
b->
data
= 0;
356
b->
size
= 0;
357
b->
readOffset
= 0;
358
delete
b;
359
}
360
m_readBuffer
.clear ();
361
m_readBufferSize
= 0;
362
}
363
364
int
365
LocalSocketFd::Ftruncate
(off_t length)
366
{
367
Thread
*current =
Current
();
368
NS_ASSERT (current != 0);
369
NS_LOG_FUNCTION (
this
<< current << length);
370
371
current->
err
= EINVAL;
372
return
-1;
373
}
374
375
}
// namespace ns3
model
local-socket-fd.cc
Generated on Fri Aug 30 2013 13:57:56 for ns-3-dce by
1.8.1.2