Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
emulab
emulab-devel
Commits
c3c1766c
Commit
c3c1766c
authored
Mar 31, 2008
by
Jonathon Duerig
Browse files
Quick checkpoint for refactoring DummynetPipe
parent
98775689
Changes
2
Hide whitespace changes
Inline
Side-by-side
event/delay-agent/new/DummynetPipe.cc
View file @
c3c1766c
...
...
@@ -5,177 +5,236 @@
#include
"lib.hh"
#include
"DummynetPipe.hh"
extern
"C"
{
#include
<sys/types.h>
#include
<sys/socket.h>
/*
#include <netinet/ip_compat.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_fw.h>
#include <netinet/ip_dummynet.h>
*/
#include
<net/if.h>
#include
<netinet/in.h>
#include
<netinet/in_systm.h>
#include
<netinet/ip.h>
#include
<netinet/ip_icmp.h>
#include
<netinet/ip_fw.h>
#include
<net/route.h>
/* def. of struct route */
#include
<netinet/ip_dummynet.h>
#include
<netinet/tcp.h>
#include
<arpa/inet.h>
}
#if __FreeBSD_version >= 601000
#define DN_PIPE_NEXT(p) ((p)->next.sle_next)
#else
#define DN_PIPE_NEXT(p) ((p)->next)
#endif
using
namespace
std
;
DummynetPipe
::
DummynetPipe
(
std
::
string
const
&
pipeno
)
{
dummynetPipeNumber
=
stringToInt
(
pipeno
);
dummynetPipeNumber
=
stringToInt
(
pipeno
);
dummynetSocket
=
socket
(
AF_INET
,
SOCK_RAW
,
IPPROTO_RAW
);
if
(
dummynetSocket
<
0
)
{
cerr
<<
"Can't create raw socket"
<<
endl
;
}
dummynetSocket
=
socket
(
AF_INET
,
SOCK_RAW
,
IPPROTO_RAW
);
if
(
dummynetSocket
<
0
)
{
cerr
<<
"Can't create raw socket"
<<
endl
;
}
}
DummynetPipe
::~
DummynetPipe
()
{
close
(
dummynetSocket
);
close
(
dummynetSocket
);
}
DummynetPipe
::
reset
(
void
)
void
DummynetPipe
::
reset
(
void
)
{
struct
dn_pipe
*
pipe
;
struct
dn_pipe
*
pipe
;
pipe
=
getPipe
();
if
(
pipe
==
NULL
)
{
cerr
<<
"Couldn't find pipe for "
<<
dummynetPipeNumber
<<
endl
;
return
;
}
pipe
=
getPipe
();
if
(
pipe
==
NULL
)
{
cerr
<<
"Couldn't find pipe for "
<<
dummynetPipeNumber
<<
endl
;
return
;
}
map
<
Parameter
::
ParameterType
,
Parameter
>::
iterator
pos
=
g
::
defaultParameters
.
begin
();
map
<
Parameter
::
ParameterType
,
Parameter
>::
iterator
limit
=
g
::
defaultParameters
.
end
();
map
<
Parameter
::
ParameterType
,
Parameter
>::
iterator
pos
=
g
::
defaultParameters
.
begin
();
map
<
Parameter
::
ParameterType
,
Parameter
>::
iterator
limit
=
g
::
defaultParameters
.
end
();
for
(;
pos
!=
limit
;
++
pos
)
{
updateParameter
(
pipe
,
pos
->
second
);
}
for
(;
pos
!=
limit
;
++
pos
)
{
updateParameter
(
pipe
,
pos
->
second
);
}
setPipe
(
pipe
);
setPipe
(
pipe
);
free
(
pipe
);
free
(
pipe
);
}
DummynetPipe
::
updateParameter
(
struct
dn_pipe
*
pipe
,
Parameter
const
&
p
arameter
)
void
DummynetPipe
::
updateParameter
(
struct
dn_pipe
*
pipe
,
Parameter
const
&
newP
arameter
)
{
switch
(
parameter
.
getType
())
{
case
BANDWIDTH
:
pipe
->
bandwidth
=
newParameter
.
getValue
();
break
;
case
DELAY
:
pipe
->
delay
=
newParameter
.
getValue
();
break
;
#if 0
case LOSS:
parameterString = "LOSS";
break;
#endif
}
switch
(
newParameter
.
getType
())
{
case
Parameter
::
BANDWIDTH
:
pipe
->
bandwidth
=
newParameter
.
getValue
();
break
;
case
Parameter
::
DELAY
:
pipe
->
delay
=
newParameter
.
getValue
();
break
;
default:
// TODO: Handle UP and DOWN events
break
;
}
}
DummynetPipe
::
resetParameter
(
Parameter
const
&
newParameter
)
void
DummynetPipe
::
resetParameter
(
Parameter
const
&
newParameter
)
{
struct
dn_pipe
*
pipe
;
struct
dn_pipe
*
pipe
;
pipe
=
getPipe
();
if
(
pipe
==
NULL
)
{
return
;
}
pipe
=
getPipe
();
if
(
pipe
==
NULL
)
{
return
;
}
updateParameter
(
pipe
,
newParameter
);
updateParameter
(
pipe
,
newParameter
);
setPipe
(
pipe
);
setPipe
(
pipe
);
free
(
pipe
);
free
(
pipe
);
}
void
*
DummynetPipe
::
getPipe
(
void
)
char
*
callGetsockopt
(
char
*
data
,
size_t
*
count
)
{
struct
dn_pipe
*
pipes
;
int
fix_size
;
int
num_bytes
,
num_alloc
;
void
*
data
;
void
*
next
;
struct
dn_pipe
*
p
,
*
pipe
;
struct
dn_flow_queue
*
q
;
int
l
;
data
=
NULL
;
fix_size
=
sizeof
(
*
pipes
);
num_alloc
=
fix_size
;
num_bytes
=
num_alloc
;
data
=
malloc
(
num_bytes
);
if
(
data
==
NULL
){
cerr
<<
"malloc: cant allocate memory"
<<
endl
;
return
0
;
}
if
(
getsockopt
(
dummynetSocket
,
IPPROTO_IP
,
IP_DUMMYNET_GET
,
data
,
count
)
<
0
)
{
cerr
<<
"Error in getsockopt
\n
"
<<
endl
;
return
NULL
;
}
else
{
return
data
;
}
}
while
(
num_bytes
>=
num_alloc
)
{
num_alloc
=
num_alloc
*
2
+
200
;
num_bytes
=
num_alloc
;
if
((
data
=
realloc
(
data
,
num_bytes
))
==
NULL
){
cerr
<<
"cant alloc memory"
<<
endl
;
return
0
;
}
char
*
DummynetPipe
::
getAllPipes
(
void
)
{
static
vector
<
char
>
data
(
sizeof
(
struct
dn_pipe
));
char
*
result
=
&
data
[
0
];
size_t
num_bytes
=
0
;
result
=
callGetsockopt
(
&
data
[
0
],
&
num_bytes
);
while
(
num_bytes
>=
data
.
size
()
&&
result
!=
NULL
)
{
data
.
resize
(
data
.
size
()
*
2
+
200
);
result
=
callGetsockopt
(
&
data
[
0
],
&
num_bytes
);
}
return
result
;
}
if
(
getsockopt
(
dummynetSocket
,
IPPROTO_IP
,
IP_DUMMYNET_GET
,
data
,
&
num_bytes
)
<
0
){
cerr
<<
"error in getsockopt"
<<
endl
;
return
0
;
}
struct
dn_pipe
*
DummynetPipe
::
getPipe
(
void
)
{
// Find the pipe we care about
// Pass this pipe to the thing which should deal with it.
size_t
num_bytes
=
sizeof
(
struct
dn_pipe
);
size_t
num_alloc
=
sizeof
(
struct
dn_pipe
);
void
*
data
=
NULL
;
void
*
next
=
NULL
;
struct
dn_pipe
*
p
=
NULL
;
struct
dn_pipe
*
pipe
=
NULL
;
struct
dn_flow_queue
*
q
=
NULL
;
int
l
;
data
=
malloc
(
num_bytes
);
if
(
data
==
NULL
)
{
cerr
<<
"malloc: cant allocate memory"
<<
endl
;
return
0
;
}
while
(
num_bytes
>=
num_alloc
)
{
num_alloc
=
num_alloc
*
2
+
200
;
num_bytes
=
num_alloc
;
if
((
data
=
realloc
(
data
,
num_bytes
))
==
NULL
)
{
cerr
<<
"cant alloc memory"
<<
endl
;
return
0
;
}
next
=
data
;
p
=
(
struct
dn_pipe
*
)
data
;
pipe
=
NULL
;
if
(
getsockopt
(
dummynetSocket
,
IPPROTO_IP
,
IP_DUMMYNET_GET
,
data
,
&
num_bytes
)
<
0
)
{
cerr
<<
"error in getsockopt"
<<
endl
;
return
0
;
}
for
(
;
num_bytes
>=
sizeof
(
*
p
)
;
p
=
(
struct
dn_pipe
*
)
next
)
{
}
next
=
data
;
p
=
(
struct
dn_pipe
*
)
data
;
pipe
=
NULL
;
if
(
DN_PIPE_NEXT
(
p
)
!=
(
struct
dn_pipe
*
)
DN_IS_PIPE
)
break
;
for
(
;
num_bytes
>=
sizeof
(
*
p
)
;
p
=
(
struct
dn_pipe
*
)
next
)
{
if
(
DN_PIPE_NEXT
(
p
)
!=
(
struct
dn_pipe
*
)
DN_IS_PIPE
)
break
;
l
=
sizeof
(
*
p
)
+
p
->
fs
.
rq_elements
*
sizeof
(
*
q
)
;
next
=
(
void
*
)
p
+
l
;
num_bytes
-=
l
;
if
(
pipe_num
!=
p
->
pipe_nr
)
continue
;
l
=
sizeof
(
*
p
)
+
p
->
fs
.
rq_elements
*
sizeof
(
*
q
)
;
next
=
(
void
*
)((
char
*
)
p
+
l
)
;
num_bytes
-=
l
;
if
(
dummynetPipeNumber
!=
p
->
pipe_nr
)
continue
;
q
=
(
struct
dn_flow_queue
*
)(
p
+
1
)
;
q
=
(
struct
dn_flow_queue
*
)(
p
+
1
)
;
#if 0
/* grab pipe delay and bandwidth */
link_map[l_index].getParams(p_index).setDelay(p->delay);
link_map[l_index].getParams(p_index).setBandwidth(p->bandwidth);
/* grab pipe delay and bandwidth */
link_map[l_index].getParams(p_index).setDelay(p->delay);
link_map[l_index].getParams(p_index).setBandwidth(p->bandwidth);
/* get flow set parameters*/
get_flowset_params( &(p->fs), l_index, p_index);
/* get flow set parameters*/
get_flowset_params( &(p->fs), l_index, p_index);
/* get dynamic queue parameters*/
get_queue_params( &(p->fs), l_index, p_index);
/* get dynamic queue parameters*/
get_queue_params( &(p->fs), l_index, p_index);
#endif
}
}
if
((
num_bytes
<
sizeof
(
*
p
)
||
(
DN_PIPE_NEXT
(
p
)
!=
(
struct
dn_pipe
*
)
DN_IS_PIPE
)))
{
return
NULL
;
}
if
((
num_bytes
<
sizeof
(
*
p
)
||
(
DN_PIPE_NEXT
(
p
)
!=
(
struct
dn_pipe
*
)
DN_IS_PIPE
)))
{
return
NULL
;
}
pipe
=
malloc
(
l
);
if
(
foo
==
NULL
)
{
cerr
<<
"can't allocate memory"
<<
endl
;
return
NULL
;
}
pipe
=
(
struct
dn_pipe
*
)
malloc
(
l
);
if
(
pipe
==
NULL
)
{
cerr
<<
"can't allocate memory"
<<
endl
;
return
NULL
;
}
memcpy
(
pipe
,
p
,
l
);
free
(
data
);
memcpy
(
pipe
,
p
,
l
);
free
(
data
);
return
pipe
;
return
pipe
;
}
void
DummynetPipe
::
setPipe
(
struct
dn_pipe
*
pipe
)
{
if
(
setsockopt
(
dummynetSocket
,
IPPROTO_IP
,
IP_DUMMYNET_CONFIGURE
,
pipe
,
sizeof
(
*
pipe
))
<
0
)
cerr
<<
"IP_DUMMYNET_CONFIGURE setsockopt failed"
<<
endl
;
if
(
setsockopt
(
dummynetSocket
,
IPPROTO_IP
,
IP_DUMMYNET_CONFIGURE
,
pipe
,
sizeof
(
*
pipe
))
<
0
)
cerr
<<
"IP_DUMMYNET_CONFIGURE setsockopt failed"
<<
endl
;
}
#endif
event/delay-agent/new/DummynetPipe.hh
View file @
c3c1766c
...
...
@@ -5,6 +5,8 @@
#ifndef DUMMYNET_PIPE_HH_DELAY_AGENT_1
#define DUMMYNET_PIPE_HH_DELAY_AGENT_1
struct
dn_pipe
;
class
DummynetPipe
:
public
RootPipe
{
public:
...
...
@@ -13,9 +15,9 @@ public:
virtual
void
reset
(
void
);
virtual
void
resetParameter
(
Parameter
const
&
newParameter
);
private:
v
irtual
updateParameter
(
struct
dn_pipe
*
pipe
,
Parameter
const
&
parameter
);
virtual
void
setPipe
(
struct
dn_pipe
*
pipe
);
virtual
struct
dn_pipe
*
getPipe
(
void
);
v
oid
updateParameter
(
struct
dn_pipe
*
pipe
,
Parameter
const
&
parameter
);
void
setPipe
(
struct
dn_pipe
*
pipe
);
struct
dn_pipe
*
getPipe
(
void
);
int
dummynetPipeNumber
;
int
dummynetSocket
;
};
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment