Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
B
babeld
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
babeld
Commits
7e7eafae
Commit
7e7eafae
authored
Oct 09, 2008
by
Juliusz Chroboczek
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement new protocol.
parent
4ebf4c38
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
803 additions
and
516 deletions
+803
-516
babel.c
babel.c
+1
-1
message.c
message.c
+763
-494
message.h
message.h
+37
-19
network.c
network.c
+2
-2
No files found.
babel.c
View file @
7e7eafae
...
@@ -492,7 +492,7 @@ main(int argc, char **argv)
...
@@ -492,7 +492,7 @@ main(int argc, char **argv)
gettime
(
&
now
);
gettime
(
&
now
);
send_hello
(
net
);
send_hello
(
net
);
send_self_update
(
net
,
0
);
send_self_update
(
net
,
0
);
send_request
(
net
,
NULL
,
0
,
0
,
0
,
0
);
send_request
(
net
,
NULL
,
0
);
flushupdates
();
flushupdates
();
flushbuf
(
net
);
flushbuf
(
net
);
}
}
...
...
message.c
View file @
7e7eafae
...
@@ -38,10 +38,11 @@ THE SOFTWARE.
...
@@ -38,10 +38,11 @@ THE SOFTWARE.
#include "resend.h"
#include "resend.h"
#include "message.h"
#include "message.h"
#include "filter.h"
#include "filter.h"
#include "kernel.h"
struct
timeval
update_flush_timeout
=
{
0
,
0
};
struct
timeval
update_flush_timeout
=
{
0
,
0
};
const
unsigned
char
packet_header
[
8
]
=
{
42
,
1
};
unsigned
char
packet_header
[
4
]
=
{
42
,
2
};
int
parasitic
=
0
;
int
parasitic
=
0
;
int
silent_time
=
30
;
int
silent_time
=
30
;
...
@@ -52,9 +53,10 @@ struct timeval seqno_time = {0, 0};
...
@@ -52,9 +53,10 @@ struct timeval seqno_time = {0, 0};
int
seqno_interval
=
-
1
;
int
seqno_interval
=
-
1
;
struct
buffered_update
{
struct
buffered_update
{
unsigned
char
id
[
16
];
unsigned
char
id
[
8
];
unsigned
char
prefix
[
16
];
unsigned
char
prefix
[
16
];
unsigned
char
plen
;
unsigned
char
plen
;
unsigned
char
pad
[
3
];
};
};
struct
buffered_update
buffered_updates
[
MAX_BUFFERED_UPDATES
];
struct
buffered_update
buffered_updates
[
MAX_BUFFERED_UPDATES
];
struct
network
*
update_net
=
NULL
;
struct
network
*
update_net
=
NULL
;
...
@@ -66,28 +68,76 @@ unsigned char *unicast_buffer = NULL;
...
@@ -66,28 +68,76 @@ unsigned char *unicast_buffer = NULL;
struct
neighbour
*
unicast_neighbour
=
NULL
;
struct
neighbour
*
unicast_neighbour
=
NULL
;
struct
timeval
unicast_flush_timeout
=
{
0
,
0
};
struct
timeval
unicast_flush_timeout
=
{
0
,
0
};
unsigned
short
static
const
unsigned
char
v4prefix
[
16
]
=
hash_id
(
const
unsigned
char
*
id
)
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0xFF
,
0xFF
,
0
,
0
,
0
,
0
};
static
const
unsigned
char
ll_prefix
[
16
]
=
{
0xFE
,
0x80
};
static
int
network_prefix
(
int
ae
,
int
plen
,
unsigned
int
omitted
,
const
unsigned
char
*
p
,
const
unsigned
char
*
dp
,
unsigned
int
len
,
unsigned
char
*
p_r
)
{
{
int
i
;
unsigned
pb
;
unsigned
short
hash
=
0
;
unsigned
char
prefix
[
16
];
for
(
i
=
0
;
i
<
8
;
i
++
)
hash
^=
(
id
[
2
*
i
]
<<
8
)
|
id
[
2
*
i
+
1
];
if
(
plen
>=
0
)
return
hash
;
pb
=
(
plen
+
7
)
/
8
;
else
if
(
ae
==
1
)
pb
=
4
;
else
pb
=
16
;
memset
(
prefix
,
0
,
16
);
switch
(
ae
)
{
case
0
:
return
1
;
case
1
:
if
(
pb
>
omitted
&&
len
<
pb
-
omitted
)
return
-
1
;
if
(
omitted
)
{
if
(
dp
==
NULL
)
return
-
1
;
memcpy
(
prefix
,
dp
,
omitted
);
}
if
(
pb
>
omitted
)
memcpy
(
prefix
,
v4prefix
,
12
);
memcpy
(
prefix
+
12
,
p
,
pb
);
break
;
case
2
:
if
(
pb
>
omitted
&&
len
<
pb
-
omitted
)
return
-
1
;
if
(
omitted
)
{
if
(
dp
==
NULL
)
return
-
1
;
memcpy
(
prefix
,
dp
,
omitted
);
}
if
(
pb
>
omitted
)
memcpy
(
prefix
+
omitted
,
p
,
pb
-
omitted
);
break
;
case
3
:
if
(
pb
>
8
&&
len
<
pb
-
8
)
return
-
1
;
prefix
[
0
]
=
0xfe
;
prefix
[
1
]
=
0x80
;
if
(
pb
>
8
)
memcpy
(
prefix
+
8
,
p
,
pb
-
8
);
break
;
default:
return
-
1
;
}
mask_prefix
(
p_r
,
prefix
,
plen
<
0
?
128
:
ae
==
1
?
plen
+
96
:
plen
);
return
1
;
}
static
int
network_address
(
int
ae
,
const
unsigned
char
*
a
,
unsigned
int
len
,
unsigned
char
*
a_r
)
{
return
network_prefix
(
ae
,
-
1
,
0
,
a
,
NULL
,
len
,
a_r
);
}
}
void
void
parse_packet
(
const
unsigned
char
*
from
,
struct
network
*
net
,
parse_packet
(
const
unsigned
char
*
from
,
struct
network
*
net
,
const
unsigned
char
*
packet
,
int
len
)
const
unsigned
char
*
packet
,
int
packet
len
)
{
{
int
i
,
j
;
int
i
;
const
unsigned
char
*
message
;
const
unsigned
char
*
message
;
unsigned
char
type
,
plen
,
hop_count
;
unsigned
char
type
,
len
;
unsigned
short
seqno
,
metric
;
int
bodylen
;
const
unsigned
char
*
address
;
struct
neighbour
*
neigh
;
struct
neighbour
*
neigh
;
int
have_current_source
=
0
;
int
have_router_id
=
0
,
have_v4_prefix
=
0
,
have_v6_prefix
=
0
,
unsigned
char
current_source
[
16
];
have_v4_nh
=
0
,
have_v6_nh
=
0
;
unsigned
char
router_id
[
8
],
v4_prefix
[
16
],
v6_prefix
[
16
],
v4_nh
[
16
],
v6_nh
[
16
];
if
(
from
[
0
]
!=
0xFE
||
(
from
[
1
]
&
0xC0
)
!=
0x80
)
{
if
(
from
[
0
]
!=
0xFE
||
(
from
[
1
]
&
0xC0
)
!=
0x80
)
{
fprintf
(
stderr
,
"Received packet from non-local address %s.
\n
"
,
fprintf
(
stderr
,
"Received packet from non-local address %s.
\n
"
,
...
@@ -101,243 +151,255 @@ parse_packet(const unsigned char *from, struct network *net,
...
@@ -101,243 +151,255 @@ parse_packet(const unsigned char *from, struct network *net,
return
;
return
;
}
}
if
(
packet
[
1
]
!=
1
)
{
if
(
packet
[
1
]
!=
2
)
{
fprintf
(
stderr
,
fprintf
(
stderr
,
"Received packet with unknown version %d on %s from %s.
\n
"
,
"Received packet with unknown version %d on %s from %s.
\n
"
,
packet
[
1
],
net
->
ifname
,
format_address
(
from
));
packet
[
1
],
net
->
ifname
,
format_address
(
from
));
return
;
return
;
}
}
if
(
len
%
24
!=
8
)
{
neigh
=
find_neighbour
(
from
,
net
);
fprintf
(
stderr
,
"Received malformed packet on %s from %s.
\n
"
,
if
(
neigh
==
NULL
)
{
net
->
ifname
,
format_address
(
from
)
);
fprintf
(
stderr
,
"Couldn't allocate neighbour.
\n
"
);
return
;
return
;
}
}
j
=
0
;
DO_NTOHS
(
bodylen
,
packet
+
2
);
for
(
i
=
0
;
i
<
(
len
-
8
)
/
24
;
i
++
)
{
message
=
packet
+
8
+
24
*
i
;
if
(
bodylen
+
4
>
packetlen
)
{
fprintf
(
stderr
,
"Received truncated packet (%d + 4 > %d).
\n
"
,
bodylen
,
packetlen
);
bodylen
=
packetlen
-
4
;
}
i
=
0
;
while
(
i
<
bodylen
)
{
message
=
packet
+
4
+
i
;
type
=
message
[
0
];
type
=
message
[
0
];
plen
=
message
[
1
];
if
(
type
==
MESSAGE_PAD1
)
{
hop_count
=
message
[
3
];
debugf
(
"Received pad1 from %s on %s.
\n
"
,
seqno
=
ntohs
(
*
(
uint16_t
*
)(
message
+
4
));
format_address
(
from
),
net
->
ifname
);
metric
=
ntohs
(
*
(
uint16_t
*
)(
message
+
6
));
i
++
;
address
=
message
+
8
;
if
(
type
==
0
)
{
int
changed
;
if
(
memcmp
(
address
,
myid
,
16
)
==
0
)
continue
;
continue
;
debugf
(
"Received hello (%d) on %s from %s (%s).
\n
"
,
}
metric
,
net
->
ifname
,
if
(
i
+
1
>
bodylen
)
{
format_address
(
address
),
fprintf
(
stderr
,
"Received truncated message.
\n
"
);
format_address
(
from
));
break
;
}
len
=
message
[
1
];
if
(
i
+
len
>
bodylen
)
{
fprintf
(
stderr
,
"Received truncated message.
\n
"
);
break
;
}
if
(
type
==
MESSAGE_PADN
)
{
debugf
(
"Received pad%d from %s on %s.
\n
"
,
len
,
format_address
(
from
),
net
->
ifname
);
}
else
if
(
type
==
MESSAGE_ACK_REQ
)
{
unsigned
short
nonce
,
interval
;
if
(
len
<
2
)
goto
fail
;
DO_NTOHS
(
nonce
,
message
+
4
);
DO_NTOHS
(
interval
,
message
+
6
);
debugf
(
"Received ack-req (%04X %d) from %s on %s.
\n
"
,
nonce
,
interval
,
format_address
(
from
),
net
->
ifname
);
send_ack
(
neigh
,
nonce
,
interval
);
}
else
if
(
type
==
MESSAGE_ACK
)
{
debugf
(
"Received ack from %s on %s.
\n
"
,
format_address
(
from
),
net
->
ifname
);
/* Nothing right now */
}
else
if
(
type
==
MESSAGE_HELLO
)
{
unsigned
short
seqno
,
interval
;
int
changed
;
if
(
len
<
6
)
goto
fail
;
DO_NTOHS
(
seqno
,
message
+
4
);
DO_NTOHS
(
interval
,
message
+
6
);
debugf
(
"Received hello %d (%d) from %s on %s.
\n
"
,
seqno
,
interval
,
format_address
(
from
),
net
->
ifname
);
net
->
activity_time
=
now
.
tv_sec
;
net
->
activity_time
=
now
.
tv_sec
;
update_hello_interval
(
net
);
update_hello_interval
(
net
);
neigh
=
add_neighbour
(
address
,
from
,
net
);
changed
=
update_neighbour
(
neigh
,
seqno
,
interval
);
if
(
neigh
==
NULL
)
continue
;
changed
=
update_neighbour
(
neigh
,
seqno
,
metric
);
if
(
changed
)
if
(
changed
)
update_neighbour_metric
(
neigh
);
update_neighbour_metric
(
neigh
);
if
(
metric
>
0
)
if
(
interval
>
0
)
schedule_neighbours_check
(
metric
*
10
,
0
);
schedule_neighbours_check
(
interval
*
10
,
0
);
}
else
{
}
else
if
(
type
==
MESSAGE_IHU
)
{
neigh
=
find_neighbour
(
from
,
net
);
unsigned
short
txcost
,
interval
;
if
(
neigh
==
NULL
)
{
unsigned
char
address
[
16
];
debugf
(
"Received message from unknown neighbour %s.
\n
"
,
int
rc
;
format_address
(
from
));
if
(
len
<
6
)
goto
fail
;
continue
;
DO_NTOHS
(
txcost
,
message
+
4
);
}
DO_NTOHS
(
interval
,
message
+
6
);
net
->
activity_time
=
now
.
tv_sec
;
rc
=
network_address
(
message
[
2
],
message
+
8
,
len
-
6
,
address
);
if
(
type
==
1
)
{
if
(
rc
<
0
)
goto
fail
;
debugf
(
"Received ihu %d for %s from %s (%s) %d.
\n
"
,
debugf
(
"Received ihu %d (%d) from %s on %s for %s.
\n
"
,
metric
,
txcost
,
interval
,
format_address
(
address
),
format_address
(
from
),
net
->
ifname
,
format_address
(
neigh
->
id
),
format_address
(
address
));
format_address
(
from
),
seqno
);
if
(
message
[
3
]
==
0
||
network_ll_address
(
net
,
address
))
{
if
(
memcmp
(
myid
,
address
,
16
)
==
0
)
{
neigh
->
txcost
=
txcost
;
neigh
->
txcost
=
metric
;
neigh
->
ihu_time
=
now
;
neigh
->
ihu_time
=
now
;
neigh
->
ihu_interval
=
seqno
;
neigh
->
ihu_interval
=
interval
;
update_neighbour_metric
(
neigh
);
update_neighbour_metric
(
neigh
);
if
(
seqno
>
0
)
if
(
interval
>
0
)
schedule_neighbours_check
(
seqno
*
10
*
3
,
0
);
schedule_neighbours_check
(
interval
*
10
*
3
,
0
);
}
}
else
if
(
type
==
2
)
{
debugf
(
"Received request on %s from %s (%s) for %s "
"(%d hops).
\n
"
,
net
->
ifname
,
format_address
(
neigh
->
id
),
format_address
(
from
),
plen
==
0xFF
?
"any"
:
format_prefix
(
address
,
plen
),
hop_count
);
if
(
plen
==
0xFF
)
{
/* If a neighbour is requesting a full route dump from us,
we might as well send it an IHU. */
send_ihu
(
neigh
,
NULL
);
send_update
(
neigh
->
network
,
0
,
NULL
,
0
);
}
else
{
handle_request
(
neigh
,
address
,
plen
,
hop_count
,
seqno
,
metric
);
}
}
else
if
(
type
==
3
)
{
if
(
plen
==
0xFF
)
debugf
(
"Received update for %s/none on %s from %s (%s).
\n
"
,
format_address
(
address
),
net
->
ifname
,
format_address
(
neigh
->
id
),
format_address
(
from
));
else
debugf
(
"Received update for %s on %s from %s (%s).
\n
"
,
format_prefix
(
address
,
plen
),
net
->
ifname
,
format_address
(
neigh
->
id
),
format_address
(
from
));
memcpy
(
current_source
,
address
,
16
);
have_current_source
=
1
;
if
(
memcmp
(
address
,
myid
,
16
)
==
0
)
continue
;
if
(
plen
<=
128
)
{
unsigned
char
prefix
[
16
];
mask_prefix
(
prefix
,
address
,
plen
);
update_route
(
address
,
prefix
,
plen
,
seqno
,
metric
,
neigh
,
neigh
->
address
);
}
}
}
else
if
(
type
==
4
)
{
}
else
if
(
type
==
MESSAGE_ROUTER_ID
)
{
unsigned
char
prefix
[
16
];
if
(
len
<
10
)
{
debugf
(
"Received prefix %s on %s from %s (%s).
\n
"
,
have_router_id
=
0
;
format_prefix
(
address
,
plen
),
goto
fail
;
net
->
ifname
,
format_address
(
neigh
->
id
),
format_address
(
from
));
if
(
!
have_current_source
)
{
fprintf
(
stderr
,
"Received prefix with no source "
"on %s from %s (%s).
\n
"
,
net
->
ifname
,
format_address
(
neigh
->
id
),
format_address
(
from
));
continue
;
}
}
if
(
memcmp
(
current_source
,
myid
,
16
)
==
0
)
memcpy
(
router_id
,
message
+
4
,
8
);
continue
;
have_router_id
=
1
;
mask_prefix
(
prefix
,
address
,
plen
);
debugf
(
"Received router-id %s from %s on %s.
\n
"
,
update_route
(
current_source
,
prefix
,
plen
,
seqno
,
metric
,
format_eui64
(
router_id
),
format_address
(
from
),
net
->
ifname
);
neigh
,
neigh
->
address
);
}
else
if
(
type
==
MESSAGE_NH
)
{
}
else
if
(
type
==
5
)
{
unsigned
char
nh
[
16
];
unsigned
char
p4
[
16
],
prefix
[
16
],
nh
[
16
];
int
rc
;
if
(
!
net
->
ipv4
)
if
(
len
<
2
)
{
continue
;
have_v4_nh
=
0
;
v4tov6
(
p4
,
message
+
20
);
have_v6_nh
=
0
;
v4tov6
(
nh
,
message
+
16
);
goto
fail
;
debugf
(
"Received update for %s nh %s on %s from %s (%s).
\n
"
,
format_prefix
(
p4
,
plen
+
96
),
format_address
(
nh
),
net
->
ifname
,
format_address
(
neigh
->
id
),
format_address
(
from
));
if
(
plen
>
32
)
continue
;
if
(
!
have_current_source
)
{
fprintf
(
stderr
,
"Received IPv4 prefix with no source "
"on %s from %s (%s).
\n
"
,
net
->
ifname
,
format_address
(
neigh
->
id
),
format_address
(
from
));
continue
;
}
}
if
(
memcmp
(
current_source
,
myid
,
16
)
==
0
)
rc
=
network_address
(
message
[
2
],
message
+
4
,
len
-
2
,
continue
;
nh
);
mask_prefix
(
prefix
,
p4
,
plen
+
96
);
if
(
rc
<
0
)
{
update_route
(
current_source
,
prefix
,
plen
+
96
,
seqno
,
metric
,
have_v4_nh
=
0
;
neigh
,
nh
);
have_v6_nh
=
0
;
goto
fail
;
}
debugf
(
"Received nh %s (%d) from %s on %s.
\n
"
,
format_address
(
nh
),
message
[
2
],
format_address
(
from
),
net
->
ifname
);
if
(
message
[
2
]
==
1
)
{
memcpy
(
v4_nh
,
nh
,
16
);
have_v4_nh
=
1
;
}
else
{
}
else
{
debugf
(
"Received unknown packet type %d from %s (%s).
\n
"
,
memcpy
(
v6_nh
,
nh
,
16
);
type
,
format_address
(
neigh
->
id
),
format_address
(
from
))
;
have_v6_nh
=
1
;
}
}
}
else
if
(
type
==
MESSAGE_UPDATE
)
{
unsigned
char
prefix
[
16
],
*
nh
;
unsigned
char
plen
;
unsigned
short
interval
,
seqno
,
metric
;
int
rc
;
if
(
len
<
10
)
{
if
(
len
<
2
||
message
[
3
]
&
0x80
)
have_v4_prefix
=
have_v6_prefix
=
0
;
goto
fail
;
}
}
DO_NTOHS
(
interval
,
message
+
6
);
DO_NTOHS
(
seqno
,
message
+
8
);
DO_NTOHS
(
metric
,
message
+
10
);
if
(
message
[
5
]
==
0
||
(
message
[
3
]
==
1
?
have_v4_prefix
:
have_v6_prefix
))
rc
=
network_prefix
(
message
[
2
],
message
[
4
],
message
[
5
],
message
+
12
,
message
[
3
]
==
1
?
v4_prefix
:
v6_prefix
,
len
-
10
,
prefix
);
else
rc
=
-
1
;
if
(
rc
<
0
)
{
if
(
message
[
3
]
&
0x80
)
have_v4_prefix
=
have_v6_prefix
=
0
;
goto
fail
;
}
}
return
;
}
void
plen
=
message
[
4
]
+
(
message
[
2
]
==
1
?
96
:
0
);
handle_request
(
struct
neighbour
*
neigh
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
unsigned
char
hop_count
,
unsigned
short
seqno
,
unsigned
short
router_hash
)
{
struct
xroute
*
xroute
;
struct
route
*
route
;
struct
neighbour
*
successor
=
NULL
;
xroute
=
find_xroute
(
prefix
,
plen
);
if
(
message
[
3
]
&
0x80
)
{
if
(
xroute
)
{
if
(
message
[
2
]
==
1
)
{
if
(
hop_count
>
0
&&
router_hash
==
hash_id
(
myid
))
{
memcpy
(
v4_prefix
,
prefix
,
16
);
if
(
seqno_compare
(
seqno
,
myseqno
)
>
0
)
{
have_v4_prefix
=
1
;
if
(
seqno_minus
(
seqno
,
myseqno
)
>
100
)
{
}
else
{
/* Hopelessly out-of-date request */
memcpy
(
v6_prefix
,
prefix
,
16
);
return
;
have_v6_prefix
=
1
;
}
}
update_myseqno
(
1
);
}
}
if
(
message
[
3
]
&
0x40
)
{
if
(
message
[
2
]
==
1
)
{
memset
(
router_id
,
0
,
4
);
memcpy
(
router_id
+
4
,
prefix
+
12
,
4
);
}
else
{
memcpy
(
router_id
,
prefix
+
8
,
8
);
}
}
send_update
(
neigh
->
network
,
1
,
prefix
,
plen
);
have_router_id
=
1
;
return
;
}
}
if
(
!
have_router_id
)
{
route
=
find_installed_route
(
prefix
,
plen
);
fprintf
(
stderr
,
"Received prefix with no router id.
\n
"
);
if
(
route
&&
goto
fail
;
(
hop_count
==
0
||
(
route
->
metric
<
INFINITY
&&
(
router_hash
!=
hash_id
(
route
->
src
->
id
)
||
seqno_compare
(
seqno
,
route
->
seqno
)
<=
0
))))
{
/* We can satisfy this request straight away. Note that in the
hop_count=0 case, we do send a recent retraction, in order to
reply to nodes whose routes are about to expire. */
send_update
(
neigh
->
network
,
1
,
prefix
,
plen
);
return
;
}
}
debugf
(
"Received update%s%s for %s from %s on %s.
\n
"
,
if
(
hop_count
<=
1
)
(
message
[
3
]
&
0x80
)
?
"/prefix"
:
""
,
return
;
(
message
[
3
]
&
0x40
)
?
"/id"
:
""
,
format_prefix
(
prefix
,
plen
),
if
(
route
&&
router_hash
==
hash_id
(
route
->
src
->
id
)
&&
format_address
(
from
),
net
->
ifname
);
seqno_minus
(
seqno
,
route
->
seqno
)
>
100
)
{
/* Hopelessly out-of-date */
if
(
message
[
2
]
==
1
)
{
return
;
if
(
!
have_v4_nh
)
goto
fail
;
nh
=
v4_nh
;
}
else
if
(
have_v6_nh
)
{
nh
=
v6_nh
;
}
else
{
nh
=
neigh
->
address
;
}
}
if
(
request_redundant
(
neigh
->
network
,
prefix
,
plen
,
seqno
,
router_hash
))
update_route
(
router_id
,
prefix
,
plen
,
seqno
,
metric
,
neigh
,
nh
);
return
;
}
else
if
(
type
==
MESSAGE_REQUEST
)
{
unsigned
char
prefix
[
16
];
/* Let's try to forward this request. */
int
rc
;
if
(
route
&&
route
->
metric
<
INFINITY
)
if
(
len
<
2
)
successor
=
route
->
neigh
;
goto
fail
;
rc
=
network_prefix
(
message
[
2
],
message
[
3
],
0
,
if
(
!
successor
||
successor
==
neigh
)
{
message
+
4
,
NULL
,
len
-
2
,
prefix
);
/* We were about to forward a request to its requestor. Try to
if
(
rc
<
0
)
goto
fail
;
find a different neighbour to forward the request to. */
debugf
(
"Received request for %s from %s on %s.
\n
"
,
struct
route
*
other_route
;
format_prefix
(
prefix
,
message
[
3
]),
format_address
(
from
),
net
->
ifname
);
other_route
=
find_best_route
(
prefix
,
plen
,
0
,
neigh
);
if
(
message
[
2
]
==
0
)
{
if
(
other_route
&&
other_route
->
metric
<
INFINITY
)
/* If a neighbour is requesting a full route dump from us,
successor
=
other_route
->
neigh
;
we might as well send it an IHU. */
send_ihu
(
neigh
,
NULL
);
send_update
(
neigh
->
network
,
0
,
NULL
,
0
);
}
else
{
send_update
(
neigh
->
network
,
0
,
prefix
,
message
[
3
]);
}
}
else
if
(
type
==
MESSAGE_MH_REQUEST
)
{
unsigned
char
prefix
[
16
];
unsigned
short
seqno
;
int
rc
;
if
(
len
<
14
)
goto
fail
;
DO_NTOHS
(
seqno
,
message
+
4
);
rc
=
network_prefix
(
message
[
2
],
message
[
3
],
0
,
message
+
16
,
NULL
,
len
-
14
,
prefix
);
if
(
rc
<
0
)
goto
fail
;
debugf
(
"Received request (%d) for %s from %s on %s (%s, %d).
\n
"
,
message
[
6
],
format_prefix
(
prefix
,
message
[
3
]),
format_address
(
from
),
net
->
ifname
,
format_eui64
(
message
+
8
),
seqno
);
handle_request
(
neigh
,
prefix
,
message
[
3
],
message
[
6
],
seqno
,
message
+
8
);
}
else
{
debugf
(
"Received unknown packet type %d from %s on %s.
\n
"
,
type
,
format_address
(
from
),
net
->
ifname
);
}
}
i
+=
len
+
2
;
continue
;
if
(
!
successor
||
successor
==
neigh
)
fail:
/* Give up */
fprintf
(
stderr
,
"Couldn't parse packet (%d %d).
\n
"
,
message
[
0
],
message
[
1
]);
i
+=
len
+
2
;
}
return
;
return
;
send_unicast_request
(
successor
,
prefix
,
plen
,
hop_count
-
1
,
seqno
,
router_hash
);
record_resend
(
RESEND_REQUEST
,
prefix
,
plen
,
seqno
,
router_hash
,
neigh
->
network
,
0
);
}
}
/* Under normal circumstances, there are enough moderation mechanisms
/* Under normal circumstances, there are enough moderation mechanisms
elsewhere in the protocol to make sure that this last-ditch check
elsewhere in the protocol to make sure that this last-ditch check
should never trigger. But I'm supersti
c
ious. */
should never trigger. But I'm supersti
t
ious. */
static
int
static
int
check_bucket
(
struct
network
*
net
)
check_bucket
(
struct
network
*
net
)
...
@@ -380,6 +442,7 @@ flushbuf(struct network *net)
...
@@ -380,6 +442,7 @@ flushbuf(struct network *net)
memcpy
(
&
sin6
.
sin6_addr
,
protocol_group
,
16
);
memcpy
(
&
sin6
.
sin6_addr
,
protocol_group
,
16
);
sin6
.
sin6_port
=
htons
(
protocol_port
);
sin6
.
sin6_port
=
htons
(
protocol_port
);
sin6
.
sin6_scope_id
=
net
->
ifindex
;
sin6
.
sin6_scope_id
=
net
->
ifindex
;
DO_HTONS
(
packet_header
+
2
,
net
->
buffered
);
rc
=
babel_send
(
protocol_socket
,
rc
=
babel_send
(
protocol_socket
,
packet_header
,
sizeof
(
packet_header
),
packet_header
,
sizeof
(
packet_header
),
net
->
sendbuf
,
net
->
buffered
,
net
->
sendbuf
,
net
->
buffered
,
...
@@ -393,6 +456,10 @@ flushbuf(struct network *net)
...
@@ -393,6 +456,10 @@ flushbuf(struct network *net)
}
}
VALGRIND_MAKE_MEM_UNDEFINED
(
net
->
sendbuf
,
net
->
bufsize
);
VALGRIND_MAKE_MEM_UNDEFINED
(
net
->
sendbuf
,
net
->
bufsize
);
net
->
buffered
=
0
;
net
->
buffered
=
0
;
net
->
have_buffered_hello
=
0
;
net
->
have_buffered_id
=
0
;
net
->
have_buffered_nh
=
0
;
net
->
have_buffered_prefix
=
0
;
net
->
flush_timeout
.
tv_sec
=
0
;
net
->
flush_timeout
.
tv_sec
=
0
;
net
->
flush_timeout
.
tv_usec
=
0
;
net
->
flush_timeout
.
tv_usec
=
0
;
}
}
...
@@ -409,7 +476,7 @@ schedule_flush(struct network *net)
...
@@ -409,7 +476,7 @@ schedule_flush(struct network *net)
now
.
tv_sec
+
(
now
.
tv_usec
/
1000
+
msecs
)
/
1000
;
now
.
tv_sec
+
(
now
.
tv_usec
/
1000
+
msecs
)
/
1000
;
}
}
void
static
void
schedule_flush_now
(
struct
network
*
net
)
schedule_flush_now
(
struct
network
*
net
)
{
{
/* Almost now */
/* Almost now */
...
@@ -423,12 +490,11 @@ schedule_flush_now(struct network *net)
...
@@ -423,12 +490,11 @@ schedule_flush_now(struct network *net)
}
}
static
void
static
void
schedule_unicast_flush
(
void
)
schedule_unicast_flush
(
int
msecs
)
{
{
int
msecs
;
if
(
!
unicast_neighbour
)
if
(
!
unicast_neighbour
)
return
;
return
;
if
(
msecs
<
0
)
msecs
=
jitter
(
unicast_neighbour
->
network
,
1
);
msecs
=
jitter
(
unicast_neighbour
->
network
,
1
);
if
(
unicast_flush_timeout
.
tv_sec
!=
0
&&
if
(
unicast_flush_timeout
.
tv_sec
!=
0
&&
timeval_minus_msec
(
&
unicast_flush_timeout
,
&
now
)
<
msecs
)
timeval_minus_msec
(
&
unicast_flush_timeout
,
&
now
)
<
msecs
)
...
@@ -439,74 +505,134 @@ schedule_unicast_flush(void)
...
@@ -439,74 +505,134 @@ schedule_unicast_flush(void)
}
}
static
void
static
void
start_message
(
struct
network
*
net
,
int
bytes
)
ensure_space
(
struct
network
*
net
,
int
space
)
{
{
assert
(
net
->
buffered
%
24
==
0
);
if
(
net
->
bufsize
-
net
->
buffered
<
space
)
if
(
net
->
bufsize
-
net
->
buffered
<
bytes
)
flushbuf
(
net
);
flushbuf
(
net
);
}
}
static
void
static
void
send_message
(
struct
network
*
net
,
start_message
(
struct
network
*
net
,
int
type
,
int
len
)
unsigned
char
type
,
unsigned
char
plen
,
unsigned
char
hop_count
,
unsigned
short
seqno
,
unsigned
short
metric
,
const
unsigned
char
*
address
)
{
{
unsigned
char
*
buf
;
if
(
net
->
bufsize
-
net
->
buffered
<
len
+
2
)
int
n
;
flushbuf
(
net
);
net
->
sendbuf
[
net
->
buffered
++
]
=
type
;
net
->
sendbuf
[
net
->
buffered
++
]
=
len
;
}
if
(
!
net
->
up
)
static
void
return
;
end_message
(
struct
network
*
net
,
int
type
,
int
bytes
)
{
assert
(
net
->
buffered
>=
bytes
+
2
&&
net
->
sendbuf
[
net
->
buffered
-
bytes
-
2
]
==
type
&&
net
->
sendbuf
[
net
->
buffered
-
bytes
-
1
]
==
bytes
);
schedule_flush
(
net
);
}
start_message
(
net
,
24
);
static
void
buf
=
net
->
sendbuf
;
accumulate_byte
(
struct
network
*
net
,
unsigned
char
value
)
n
=
net
->
buffered
;
{
net
->
sendbuf
[
net
->
buffered
++
]
=
value
;
buf
[
n
++
]
=
type
;
}
buf
[
n
++
]
=
plen
;
buf
[
n
++
]
=
0
;
buf
[
n
++
]
=
hop_count
;
buf
[
n
++
]
=
(
seqno
>>
8
)
&
0xFF
;
buf
[
n
++
]
=
seqno
&
0xFF
;
buf
[
n
++
]
=
(
metric
>>
8
)
&
0xFF
;
buf
[
n
++
]
=
metric
&
0xFF
;
memcpy
(
buf
+
n
,
address
,
16
);
n
+=
16
;
net
->
buffered
=
n
;
schedule_flush
(
net
);
static
void
accumulate_short
(
struct
network
*
net
,
unsigned
short
value
)
{
DO_HTONS
(
net
->
sendbuf
+
net
->
buffered
,
value
);
net
->
buffered
+=
2
;
}
}
/* Flush buffers if they contain any hellos. This avoids sending multiple
static
void
hellos in a single packet, which breaks link quality estimation. */
accumulate_bytes
(
struct
network
*
net
,
int
const
unsigned
char
*
value
,
unsigned
len
)
flush_hellos
(
struct
network
*
net
)
{
{
int
i
;
memcpy
(
net
->
sendbuf
+
net
->
buffered
,
value
,
len
);
assert
(
net
->
buffered
%
24
==
0
);
net
->
buffered
+=
len
;
}
for
(
i
=
0
;
i
<
net
->
buffered
/
24
;
i
++
)
{
static
int
const
unsigned
char
*
message
;
start_unicast_message
(
struct
neighbour
*
neigh
,
int
type
,
int
len
)
message
=
(
const
unsigned
char
*
)(
net
->
sendbuf
+
i
*
24
);
{
if
(
message
[
0
]
==
0
)
{
if
(
unicast_neighbour
)
{
flushbuf
(
net
);
if
(
neigh
!=
unicast_neighbour
||
return
1
;
unicast_buffered
+
len
+
2
>=
MIN
(
UNICAST_BUFSIZE
,
neigh
->
network
->
bufsize
))
flush_unicast
(
0
);
}
}
if
(
!
unicast_buffer
)
unicast_buffer
=
malloc
(
UNICAST_BUFSIZE
);
if
(
!
unicast_buffer
)
{
perror
(
"malloc(unicast_buffer)"
);
return
-
1
;
}
}
return
0
;
unicast_neighbour
=
neigh
;
unicast_buffer
[
unicast_buffered
++
]
=
type
;
unicast_buffer
[
unicast_buffered
++
]
=
len
;
return
1
;
}
static
void
end_unicast_message
(
struct
neighbour
*
neigh
,
int
type
,
int
bytes
)
{
assert
(
unicast_neighbour
==
neigh
&&
unicast_buffered
>=
bytes
+
2
&&
unicast_buffer
[
unicast_buffered
-
bytes
-
2
]
==
type
&&
unicast_buffer
[
unicast_buffered
-
bytes
-
1
]
==
bytes
);
schedule_unicast_flush
(
-
1
);
}
static
void
accumulate_unicast_byte
(
struct
neighbour
*
neigh
,
unsigned
char
value
)
{
unicast_buffer
[
unicast_buffered
++
]
=
value
;
}
static
void
accumulate_unicast_short
(
struct
neighbour
*
neigh
,
unsigned
short
value
)
{
DO_HTONS
(
unicast_buffer
+
unicast_buffered
,
value
);
unicast_buffered
+=
2
;
}
static
void
accumulate_unicast_bytes
(
struct
neighbour
*
neigh
,
const
unsigned
char
*
value
,
unsigned
len
)
{
memcpy
(
unicast_buffer
+
unicast_buffered
,
value
,
len
);
unicast_buffered
+=
len
;
}
void
send_ack
(
struct
neighbour
*
neigh
,
unsigned
short
nonce
,
unsigned
short
interval
)
{
int
rc
;
debugf
(
"Sending ack (%04x) to %s on %s.
\n
"
,
nonce
,
format_address
(
neigh
->
address
),
neigh
->
network
->
ifname
);
rc
=
start_unicast_message
(
neigh
,
MESSAGE_ACK
,
2
);
if
(
rc
<
0
)
return
;
accumulate_unicast_short
(
neigh
,
nonce
);
end_unicast_message
(
neigh
,
MESSAGE_ACK
,
2
);
}
}
void
void
send_hello_noupdate
(
struct
network
*
net
,
unsigned
interval
)
send_hello_noupdate
(
struct
network
*
net
,
unsigned
interval
)
{
{
debugf
(
"Sending hello (%d) to %s.
\n
"
,
interval
,
net
->
ifname
);
/* This avoids sending multiple hellos in a single packet, which breaks
link quality estimation. */
if
(
net
->
have_buffered_hello
)
flushbuf
(
net
);
net
->
hello_seqno
=
seqno_plus
(
net
->
hello_seqno
,
1
);
net
->
hello_seqno
=
seqno_plus
(
net
->
hello_seqno
,
1
);
flush_hellos
(
net
);
delay_jitter
(
&
net
->
hello_time
,
&
net
->
hello_timeout
,
delay_jitter
(
&
net
->
hello_time
,
&
net
->
hello_timeout
,
net
->
hello_interval
);
net
->
hello_interval
);
send_message
(
net
,
0
,
0
,
0
,
net
->
hello_seqno
,
interval
>
0xFFFF
?
0
:
interval
,
debugf
(
"Sending hello %d (%d) to %s.
\n
"
,
myid
);
net
->
hello_seqno
,
interval
,
net
->
ifname
);
start_message
(
net
,
MESSAGE_HELLO
,
6
);
accumulate_short
(
net
,
0
);
accumulate_short
(
net
,
net
->
hello_seqno
);
accumulate_short
(
net
,
interval
>
0xFFFF
?
0xFFFF
:
interval
);
end_message
(
net
,
MESSAGE_HELLO
,
6
);
net
->
have_buffered_hello
=
1
;
}
}
void
void
...
@@ -522,56 +648,6 @@ send_hello(struct network *net)
...
@@ -522,56 +648,6 @@ send_hello(struct network *net)
send_marginal_ihu
(
net
);
send_marginal_ihu
(
net
);
}
}
void
send_request
(
struct
network
*
net
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
unsigned
char
hop_count
,
unsigned
short
seqno
,
unsigned
short
router_hash
)
{
if
(
net
==
NULL
)
{
struct
network
*
n
;
FOR_ALL_NETS
(
n
)
{
if
(
n
->
up
)
continue
;
send_request
(
n
,
prefix
,
plen
,
hop_count
,
seqno
,
router_hash
);
}
return
;
}
/* Make sure any buffered updates go out before this request. */
if
(
!
net
||
update_net
==
net
)
flushupdates
();
debugf
(
"Sending request to %s for %s (%d hops).
\n
"
,
net
->
ifname
,
prefix
?
format_prefix
(
prefix
,
plen
)
:
"any"
,
hop_count
);
if
(
prefix
)
send_message
(
net
,
2
,
plen
,
hop_count
,
seqno
,
router_hash
,
prefix
);
else
send_message
(
net
,
2
,
0xFF
,
0
,
0
,
0
,
ones
);
}
void
send_request_resend
(
struct
neighbour
*
neigh
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
unsigned
short
seqno
,
unsigned
short
router_hash
)
{
int
delay
;
if
(
neigh
)
send_unicast_request
(
neigh
,
prefix
,
plen
,
127
,
seqno
,
router_hash
);
else
send_request
(
NULL
,
prefix
,
plen
,
127
,
seqno
,
router_hash
);
delay
=
2000
;
delay
=
MIN
(
delay
,
wireless_hello_interval
/
2
);
delay
=
MIN
(
delay
,
wired_hello_interval
/
2
);
delay
=
MAX
(
delay
,
10
);
record_resend
(
RESEND_REQUEST
,
prefix
,
plen
,
seqno
,
router_hash
,
neigh
?
neigh
->
network
:
NULL
,
delay
);
}
void
void
flush_unicast
(
int
dofree
)
flush_unicast
(
int
dofree
)
{
{
...
@@ -593,6 +669,7 @@ flush_unicast(int dofree)
...
@@ -593,6 +669,7 @@ flush_unicast(int dofree)
memcpy
(
&
sin6
.
sin6_addr
,
unicast_neighbour
->
address
,
16
);
memcpy
(
&
sin6
.
sin6_addr
,
unicast_neighbour
->
address
,
16
);
sin6
.
sin6_port
=
htons
(
protocol_port
);
sin6
.
sin6_port
=
htons
(
protocol_port
);
sin6
.
sin6_scope_id
=
unicast_neighbour
->
network
->
ifindex
;
sin6
.
sin6_scope_id
=
unicast_neighbour
->
network
->
ifindex
;
DO_HTONS
(
packet_header
+
2
,
unicast_buffered
);
rc
=
babel_send
(
protocol_socket
,
rc
=
babel_send
(
protocol_socket
,
packet_header
,
sizeof
(
packet_header
),
packet_header
,
sizeof
(
packet_header
),
unicast_buffer
,
unicast_buffered
,
unicast_buffer
,
unicast_buffered
,
...
@@ -602,8 +679,7 @@ flush_unicast(int dofree)
...
@@ -602,8 +679,7 @@ flush_unicast(int dofree)
}
else
{
}
else
{
fprintf
(
stderr
,
fprintf
(
stderr
,
"Warning: bucket full, dropping unicast packet"
"Warning: bucket full, dropping unicast packet"
"to %s (%s) if %s.
\n
"
,
"to %s if %s.
\n
"
,
format_address
(
unicast_neighbour
->
id
),
format_address
(
unicast_neighbour
->
address
),
format_address
(
unicast_neighbour
->
address
),
unicast_neighbour
->
network
->
ifname
);
unicast_neighbour
->
network
->
ifname
);
}
}
...
@@ -620,140 +696,95 @@ flush_unicast(int dofree)
...
@@ -620,140 +696,95 @@ flush_unicast(int dofree)
unicast_flush_timeout
.
tv_usec
=
0
;
unicast_flush_timeout
.
tv_usec
=
0
;
}
}
static
void
send_unicast_message
(
struct
neighbour
*
neigh
,
unsigned
char
type
,
unsigned
char
plen
,
unsigned
char
hop_count
,
unsigned
short
seqno
,
unsigned
short
metric
,
const
unsigned
char
*
address
)
{
if
(
unicast_neighbour
)
{
if
(
neigh
!=
unicast_neighbour
||
unicast_buffered
+
24
>=
MIN
(
UNICAST_BUFSIZE
,
neigh
->
network
->
bufsize
))
flush_unicast
(
0
);
}
if
(
!
unicast_buffer
)
unicast_buffer
=
malloc
(
UNICAST_BUFSIZE
);
if
(
!
unicast_buffer
)
{
perror
(
"malloc(unicast_buffer)"
);
return
;
}
unicast_neighbour
=
neigh
;
assert
(
unicast_buffered
%
24
==
0
);
unicast_buffer
[
unicast_buffered
++
]
=
type
;
unicast_buffer
[
unicast_buffered
++
]
=
plen
;
unicast_buffer
[
unicast_buffered
++
]
=
0
;
unicast_buffer
[
unicast_buffered
++
]
=
hop_count
;
unicast_buffer
[
unicast_buffered
++
]
=
(
seqno
>>
8
)
&
0xFF
;
unicast_buffer
[
unicast_buffered
++
]
=
seqno
&
0xFF
;
unicast_buffer
[
unicast_buffered
++
]
=
(
metric
>>
8
)
&
0xFF
;
unicast_buffer
[
unicast_buffered
++
]
=
metric
&
0xFF
;
memcpy
(
unicast_buffer
+
unicast_buffered
,
address
,
16
);
unicast_buffered
+=
16
;
schedule_unicast_flush
();
}
void
send_unicast_request
(
struct
neighbour
*
neigh
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
unsigned
char
hop_count
,
unsigned
short
seqno
,
unsigned
short
router_hash
)
{
/* Make sure any buffered updates go out before this request. */
if
(
update_net
==
neigh
->
network
)
flushupdates
();
debugf
(
"Sending unicast request to %s (%s) for %s (%d hops).
\n
"
,
format_address
(
neigh
->
id
),
format_address
(
neigh
->
address
),
prefix
?
format_prefix
(
prefix
,
plen
)
:
"any"
,
hop_count
);
if
(
prefix
)
send_unicast_message
(
neigh
,
2
,
plen
,
hop_count
,
seqno
,
router_hash
,
prefix
);
else
send_unicast_message
(
neigh
,
2
,
0xFF
,
0
,
0
,
0
,
ones
);
}
/* Return the source-id of the last buffered update message. */
static
const
unsigned
char
*
message_source_id
(
struct
network
*
net
)
{
int
i
;
assert
(
net
->
buffered
%
24
==
0
);
i
=
net
->
buffered
/
24
-
1
;
while
(
i
>=
0
)
{
const
unsigned
char
*
message
;
message
=
(
const
unsigned
char
*
)(
net
->
sendbuf
+
i
*
24
);
if
(
message
[
0
]
==
3
)
return
message
+
8
;
else
if
(
message
[
0
]
==
4
||
message
[
0
]
==
5
)
i
--
;
else
break
;
}
return
NULL
;
}
static
void
static
void
really_send_update
(
struct
network
*
net
,
really_send_update
(
struct
network
*
net
,
const
unsigned
char
*
id
,
const
unsigned
char
*
id
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
unsigned
short
seqno
,
unsigned
short
metric
)
unsigned
short
seqno
,
unsigned
short
metric
)
{
{
int
add_metric
;
int
add_metric
,
v4
,
real_plen
,
omit
=
0
;
const
unsigned
char
*
real_prefix
;
unsigned
short
flags
=
0
;
if
(
!
net
->
up
)
if
(
!
net
->
up
)
return
;
return
;
add_metric
=
output_filter
(
id
,
prefix
,
plen
,
net
->
ifindex
);
add_metric
=
output_filter
(
id
,
prefix
,
plen
,
net
->
ifindex
);
if
(
add_metric
>=
INFINITY
)
return
;
if
(
add_metric
<
INFINITY
)
{
metric
=
MIN
(
metric
+
add_metric
,
INFINITY
);
metric
=
MIN
(
metric
+
add_metric
,
INFINITY
);
if
(
plen
>=
96
&&
v4mapped
(
prefix
))
{
/* Worst case */
const
unsigned
char
*
sid
;
ensure_space
(
net
,
12
+
20
+
20
);
unsigned
char
v4route
[
16
];
v4
=
plen
>=
96
&&
v4mapped
(
prefix
);
if
(
v4
)
{
if
(
!
net
->
ipv4
)
if
(
!
net
->
ipv4
)
return
;
return
;
memset
(
v4route
,
0
,
8
);
if
(
!
net
->
have_buffered_nh
||
memcpy
(
v4route
+
8
,
net
->
ipv4
,
4
);
memcmp
(
net
->
buffered_nh
,
net
->
ipv4
,
4
)
!=
0
)
{
memcpy
(
v4route
+
12
,
prefix
+
12
,
4
);
start_message
(
net
,
MESSAGE_NH
,
6
);
start_message
(
net
,
48
);
accumulate_byte
(
net
,
1
);
sid
=
message_source_id
(
net
);
accumulate_byte
(
net
,
0
);
if
(
sid
==
NULL
||
memcmp
(
id
,
sid
,
16
)
!=
0
)
accumulate_bytes
(
net
,
net
->
ipv4
,
4
);
send_message
(
net
,
3
,
0xFF
,
0
,
0
,
0xFFFF
,
id
);
end_message
(
net
,
MESSAGE_NH
,
6
);
send_message
(
net
,
5
,
plen
-
96
,
0
,
seqno
,
metric
,
v4route
);
memcpy
(
net
->
buffered_nh
,
net
->
ipv4
,
4
);
net
->
have_buffered_nh
=
1
;
}
real_prefix
=
prefix
+
12
;
real_plen
=
plen
-
96
;
}
else
{
}
else
{
if
(
in_prefix
(
id
,
prefix
,
plen
))
{
if
(
net
->
have_buffered_prefix
)
{
send_message
(
net
,
3
,
plen
,
0
,
seqno
,
metric
,
id
);
while
(
omit
<
plen
/
8
&&
net
->
buffered_prefix
[
omit
]
==
prefix
[
omit
])
omit
++
;
}
if
(
!
net
->
have_buffered_prefix
||
plen
>=
48
)
flags
|=
0x80
;
real_prefix
=
prefix
;
real_plen
=
plen
;
}
if
(
!
net
->
have_buffered_id
||
memcmp
(
id
,
net
->
buffered_id
,
16
)
!=
0
)
{
if
(
real_plen
==
128
&&
memcmp
(
real_prefix
+
8
,
id
,
8
)
==
0
)
{
flags
|=
0x40
;
}
else
{
}
else
{
const
unsigned
char
*
sid
;
start_message
(
net
,
MESSAGE_ROUTER_ID
,
10
);
start_message
(
net
,
48
);
accumulate_short
(
net
,
0
);
sid
=
message_source_id
(
net
);
accumulate_bytes
(
net
,
id
,
8
);
if
(
sid
==
NULL
||
memcmp
(
id
,
sid
,
16
)
!=
0
)
end_message
(
net
,
MESSAGE_ROUTER_ID
,
10
);
send_message
(
net
,
3
,
0xFF
,
0
,
0
,
0xFFFF
,
id
);
send_message
(
net
,
4
,
plen
,
0
,
seqno
,
metric
,
prefix
);
}
}
memcpy
(
net
->
buffered_id
,
id
,
16
);
net
->
have_buffered_id
=
1
;
}
}
start_message
(
net
,
MESSAGE_UPDATE
,
10
+
(
real_plen
+
7
)
/
8
-
omit
);
accumulate_byte
(
net
,
v4
?
1
:
2
);
accumulate_byte
(
net
,
flags
);
accumulate_byte
(
net
,
real_plen
);
accumulate_byte
(
net
,
omit
);
accumulate_short
(
net
,
(
update_interval
+
5
)
/
10
);
accumulate_short
(
net
,
seqno
);
accumulate_short
(
net
,
metric
);
accumulate_bytes
(
net
,
real_prefix
+
omit
,
(
real_plen
+
7
)
/
8
-
omit
);
end_message
(
net
,
MESSAGE_UPDATE
,
10
+
(
real_plen
+
7
)
/
8
-
omit
);
if
(
flags
&
0x80
)
{
memcpy
(
net
->
buffered_prefix
,
prefix
,
16
);
net
->
have_buffered_prefix
=
1
;
}
}
}
}
static
int
static
int
compare_buffered_updates
(
const
void
*
av
,
const
void
*
bv
)
compare_buffered_updates
(
const
void
*
av
,
const
void
*
bv
)
{
{
const
struct
buffered_update
*
a
=
av
,
*
b
=
bv
;
const
struct
buffered_update
*
a
=
av
,
*
b
=
bv
;
int
rc
,
v4a
,
v4b
,
ipa
,
ip
b
;
int
rc
,
v4a
,
v4b
,
ma
,
m
b
;
rc
=
memcmp
(
a
->
id
,
b
->
id
,
16
);
rc
=
memcmp
(
a
->
id
,
b
->
id
,
8
);
if
(
rc
!=
0
)
if
(
rc
!=
0
)
return
rc
;
return
rc
;
...
@@ -765,18 +796,18 @@ compare_buffered_updates(const void *av, const void *bv)
...
@@ -765,18 +796,18 @@ compare_buffered_updates(const void *av, const void *bv)
else
if
(
v4a
<
v4b
)
else
if
(
v4a
<
v4b
)
return
-
1
;
return
-
1
;
ipa
=
in_prefix
(
a
->
id
,
a
->
prefix
,
a
->
plen
);
ma
=
(
!
v4a
&&
a
->
plen
==
128
&&
memcmp
(
a
->
prefix
+
8
,
a
->
id
,
8
)
==
0
);
ipb
=
in_prefix
(
b
->
id
,
b
->
prefix
,
b
->
plen
);
mb
=
(
!
v4b
&&
b
->
plen
==
128
&&
memcmp
(
b
->
prefix
+
8
,
b
->
id
,
8
)
==
0
);
if
(
ipa
>
ip
b
)
if
(
ma
>
m
b
)
return
-
1
;
return
-
1
;
else
if
(
ipa
<
ipb
)
else
if
(
mb
>
ma
)
return
1
;
return
1
;
if
(
a
->
plen
<
b
->
plen
)
if
(
a
->
plen
<
b
->
plen
)
return
-
1
;
else
if
(
a
->
plen
>
b
->
plen
)
return
1
;
return
1
;
else
if
(
a
->
plen
>
b
->
plen
)
return
-
1
;
return
memcmp
(
a
->
prefix
,
b
->
prefix
,
16
);
return
memcmp
(
a
->
prefix
,
b
->
prefix
,
16
);
}
}
...
@@ -805,9 +836,9 @@ flushupdates(void)
...
@@ -805,9 +836,9 @@ flushupdates(void)
route
=
find_installed_route
(
buffered_updates
[
i
].
prefix
,
route
=
find_installed_route
(
buffered_updates
[
i
].
prefix
,
buffered_updates
[
i
].
plen
);
buffered_updates
[
i
].
plen
);
if
(
route
)
if
(
route
)
memcpy
(
buffered_updates
[
i
].
id
,
route
->
src
->
id
,
16
);
memcpy
(
buffered_updates
[
i
].
id
,
route
->
src
->
id
,
8
);
else
else
memcpy
(
buffered_updates
[
i
].
id
,
myid
,
16
);
memcpy
(
buffered_updates
[
i
].
id
,
myid
,
8
);
}
}
qsort
(
buffered_updates
,
n
,
sizeof
(
struct
buffered_update
),
qsort
(
buffered_updates
,
n
,
sizeof
(
struct
buffered_update
),
...
@@ -844,7 +875,7 @@ flushupdates(void)
...
@@ -844,7 +875,7 @@ flushupdates(void)
metric
=
route
->
metric
;
metric
=
route
->
metric
;
if
(
metric
<
INFINITY
)
if
(
metric
<
INFINITY
)
satisfy_request
(
route
->
src
->
prefix
,
route
->
src
->
plen
,
satisfy_request
(
route
->
src
->
prefix
,
route
->
src
->
plen
,
seqno
,
hash_id
(
route
->
src
->
id
)
,
net
);
seqno
,
route
->
src
->
id
,
net
);
if
(
split_horizon
&&
net
->
wired
&&
route
->
neigh
->
network
==
net
)
if
(
split_horizon
&&
net
->
wired
&&
route
->
neigh
->
network
==
net
)
continue
;
continue
;
really_send_update
(
net
,
route
->
src
->
id
,
really_send_update
(
net
,
route
->
src
->
id
,
...
@@ -899,21 +930,6 @@ send_update(struct network *net, int urgent,
...
@@ -899,21 +930,6 @@ send_update(struct network *net, int urgent,
const
unsigned
char
*
prefix
,
unsigned
char
plen
)
const
unsigned
char
*
prefix
,
unsigned
char
plen
)
{
{
int
i
,
selfonly
;
int
i
,
selfonly
;
struct
resend
*
request
;
if
(
prefix
)
{
/* This is needed here, since flushupdates only handles the
case where network is not null. */
request
=
find_request
(
prefix
,
plen
,
NULL
);
if
(
request
)
{
struct
route
*
route
=
find_installed_route
(
prefix
,
plen
);
if
(
route
&&
route
->
metric
<
INFINITY
)
{
urgent
=
1
;
satisfy_request
(
prefix
,
plen
,
route
->
seqno
,
hash_id
(
route
->
src
->
id
),
net
);
}
}
}
if
(
net
==
NULL
)
{
if
(
net
==
NULL
)
{
struct
network
*
n
;
struct
network
*
n
;
...
@@ -993,7 +1009,7 @@ send_self_update(struct network *net, int force_seqno)
...
@@ -993,7 +1009,7 @@ send_self_update(struct network *net, int force_seqno)
if
(
net
==
NULL
)
{
if
(
net
==
NULL
)
{
struct
network
*
n
;
struct
network
*
n
;
FOR_ALL_NETS
(
n
)
{
FOR_ALL_NETS
(
n
)
{
if
(
n
->
up
)
if
(
!
n
->
up
)
continue
;
continue
;
send_self_update
(
n
,
0
);
send_self_update
(
n
,
0
);
}
}
...
@@ -1012,6 +1028,9 @@ send_self_update(struct network *net, int force_seqno)
...
@@ -1012,6 +1028,9 @@ send_self_update(struct network *net, int force_seqno)
void
void
send_ihu
(
struct
neighbour
*
neigh
,
struct
network
*
net
)
send_ihu
(
struct
neighbour
*
neigh
,
struct
network
*
net
)
{
{
int
rxcost
,
interval
;
int
ll
;
if
(
neigh
==
NULL
&&
net
==
NULL
)
{
if
(
neigh
==
NULL
&&
net
==
NULL
)
{
struct
network
*
n
;
struct
network
*
n
;
FOR_ALL_NETS
(
n
)
{
FOR_ALL_NETS
(
n
)
{
...
@@ -1028,16 +1047,15 @@ send_ihu(struct neighbour *neigh, struct network *net)
...
@@ -1028,16 +1047,15 @@ send_ihu(struct neighbour *neigh, struct network *net)
if
(
ngh
->
network
==
net
)
if
(
ngh
->
network
==
net
)
send_ihu
(
ngh
,
net
);
send_ihu
(
ngh
,
net
);
}
}
}
else
{
return
;
int
rxcost
,
interval
;
}
if
(
net
&&
neigh
->
network
!=
net
)
if
(
net
&&
neigh
->
network
!=
net
)
return
;
return
;
net
=
neigh
->
network
;
net
=
neigh
->
network
;
rxcost
=
neighbour_rxcost
(
neigh
);
rxcost
=
neighbour_rxcost
(
neigh
);
interval
=
(
net
->
hello_interval
*
3
+
9
)
/
10
;
interval
=
(
net
->
hello_interval
*
3
+
9
)
/
10
;
/* Conceptually, an IHU is a unicast message. We usually send
/* Conceptually, an IHU is a unicast message. We usually send
...
@@ -1045,22 +1063,38 @@ send_ihu(struct neighbour *neigh, struct network *net)
...
@@ -1045,22 +1063,38 @@ send_ihu(struct neighbour *neigh, struct network *net)
a single packet and avoids an ARP exchange. If we already
a single packet and avoids an ARP exchange. If we already
have a unicast message queued for this neighbour, however,
have a unicast message queued for this neighbour, however,
we might as well piggyback the IHU onto it. */
we might as well piggyback the IHU onto it. */
debugf
(
"Sending %sihu %d on %s to %s (%s)
.
\n
"
,
debugf
(
"Sending %sihu %d on %s to %s
.
\n
"
,
unicast_neighbour
==
neigh
?
"unicast "
:
""
,
unicast_neighbour
==
neigh
?
"unicast "
:
""
,
rxcost
,
rxcost
,
neigh
->
network
->
ifname
,
neigh
->
network
->
ifname
,
format_address
(
neigh
->
id
),
format_address
(
neigh
->
address
));
format_address
(
neigh
->
address
));
if
(
unicast_neighbour
==
neigh
)
{
ll
=
in_prefix
(
neigh
->
address
,
ll_prefix
,
64
);
send_unicast_message
(
neigh
,
1
,
128
,
0
,
interval
<
0xFFFF
?
interval
:
0
,
if
(
unicast_neighbour
!=
neigh
)
{
rxcost
,
neigh
->
id
);
start_message
(
net
,
MESSAGE_IHU
,
ll
?
14
:
22
);
accumulate_byte
(
net
,
ll
?
3
:
2
);
accumulate_byte
(
net
,
0
);
accumulate_short
(
net
,
rxcost
);
accumulate_short
(
net
,
interval
);
if
(
ll
)
accumulate_bytes
(
net
,
neigh
->
address
+
8
,
8
);
else
accumulate_bytes
(
net
,
neigh
->
address
,
16
);
end_message
(
net
,
MESSAGE_IHU
,
ll
?
14
:
22
);
}
else
{
}
else
{
send_message
(
net
,
1
,
128
,
0
,
int
rc
;
interval
<
0xFFFF
?
interval
:
0
,
rc
=
start_unicast_message
(
neigh
,
MESSAGE_IHU
,
ll
?
14
:
22
);
rxcost
,
neigh
->
id
);
if
(
rc
<
0
)
return
;
}
accumulate_unicast_byte
(
neigh
,
ll
?
3
:
2
);
accumulate_unicast_byte
(
neigh
,
0
);
accumulate_unicast_short
(
neigh
,
rxcost
);
accumulate_unicast_short
(
neigh
,
interval
);
if
(
ll
)
accumulate_unicast_bytes
(
neigh
,
neigh
->
address
+
8
,
8
);
else
accumulate_unicast_bytes
(
neigh
,
neigh
->
address
,
16
);
end_unicast_message
(
neigh
,
MESSAGE_IHU
,
ll
?
14
:
22
);
}
}
}
}
...
@@ -1076,3 +1110,238 @@ send_marginal_ihu(struct network *net)
...
@@ -1076,3 +1110,238 @@ send_marginal_ihu(struct network *net)
send_ihu
(
neigh
,
net
);
send_ihu
(
neigh
,
net
);
}
}
}
}
void
send_request
(
struct
network
*
net
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
)
{
int
v4
,
len
;
if
(
net
==
NULL
)
{
struct
network
*
n
;
FOR_ALL_NETS
(
n
)
{
if
(
n
->
up
)
continue
;
send_request
(
n
,
prefix
,
plen
);
}
return
;
}
/* make sure any buffered updates go out before this request. */
if
(
!
net
||
update_net
==
net
)
flushupdates
();
debugf
(
"sending request to %s for %s.
\n
"
,
net
->
ifname
,
prefix
?
format_prefix
(
prefix
,
plen
)
:
"any"
);
v4
=
plen
>=
96
&&
v4mapped
(
prefix
);
len
=
!
prefix
?
2
:
v4
?
6
:
18
;
start_message
(
net
,
MESSAGE_REQUEST
,
len
);
accumulate_byte
(
net
,
!
prefix
?
0
:
v4
?
1
:
2
);
accumulate_byte
(
net
,
!
prefix
?
0
:
v4
?
plen
-
96
:
plen
);
if
(
prefix
)
{
if
(
v4
)
accumulate_bytes
(
net
,
prefix
+
12
,
4
);
else
accumulate_bytes
(
net
,
prefix
,
16
);
}
end_message
(
net
,
MESSAGE_REQUEST
,
len
);
}
void
send_unicast_request
(
struct
neighbour
*
neigh
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
)
{
int
rc
,
v4
,
len
;
/* make sure any buffered updates go out before this request. */
if
(
update_net
==
neigh
->
network
)
flushupdates
();
debugf
(
"sending unicast request to %s for %s.
\n
"
,
format_address
(
neigh
->
address
),
prefix
?
format_prefix
(
prefix
,
plen
)
:
"any"
);
v4
=
plen
>=
96
&&
v4mapped
(
prefix
);
len
=
!
prefix
?
2
:
v4
?
6
:
18
;
rc
=
start_unicast_message
(
neigh
,
MESSAGE_REQUEST
,
len
);
if
(
rc
<
0
)
return
;
accumulate_unicast_byte
(
neigh
,
!
prefix
?
0
:
v4
?
1
:
2
);
accumulate_unicast_byte
(
neigh
,
!
prefix
?
0
:
v4
?
plen
-
96
:
plen
);
if
(
prefix
)
{
if
(
v4
)
accumulate_unicast_bytes
(
neigh
,
prefix
+
12
,
4
);
else
accumulate_unicast_bytes
(
neigh
,
prefix
,
16
);
}
end_unicast_message
(
neigh
,
MESSAGE_REQUEST
,
len
);
}
void
send_multihop_request
(
struct
network
*
net
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
unsigned
short
seqno
,
const
unsigned
char
*
id
,
unsigned
short
hop_count
)
{
int
v4
,
pb
,
len
;
/* Make sure any buffered updates go out before this request. */
if
(
!
net
||
update_net
==
net
)
flushupdates
();
if
(
net
==
NULL
)
{
struct
network
*
n
;
FOR_ALL_NETS
(
n
)
{
if
(
!
n
->
up
)
continue
;
send_multihop_request
(
n
,
prefix
,
plen
,
seqno
,
id
,
hop_count
);
}
return
;
}
debugf
(
"Sending multi-hop request on %s for %s (%d hops).
\n
"
,
net
->
ifname
,
format_prefix
(
prefix
,
plen
),
hop_count
);
v4
=
plen
>=
96
&&
v4mapped
(
prefix
);
pb
=
v4
?
((
plen
-
96
)
+
7
)
/
8
:
(
plen
+
7
)
/
8
;
len
=
6
+
8
+
pb
;
start_message
(
net
,
MESSAGE_MH_REQUEST
,
len
);
accumulate_byte
(
net
,
v4
?
1
:
2
);
accumulate_byte
(
net
,
v4
?
plen
-
96
:
plen
);
accumulate_short
(
net
,
seqno
);
accumulate_byte
(
net
,
hop_count
);
accumulate_byte
(
net
,
0
);
accumulate_bytes
(
net
,
id
,
8
);
if
(
prefix
)
{
if
(
v4
)
accumulate_bytes
(
net
,
prefix
+
12
,
pb
);
else
accumulate_bytes
(
net
,
prefix
,
pb
);
}
end_message
(
net
,
MESSAGE_MH_REQUEST
,
len
);
}
void
send_unicast_multihop_request
(
struct
neighbour
*
neigh
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
unsigned
short
seqno
,
const
unsigned
char
*
id
,
unsigned
short
hop_count
)
{
int
rc
,
v4
,
pb
,
len
;
/* Make sure any buffered updates go out before this request. */
if
(
update_net
==
neigh
->
network
)
flushupdates
();
debugf
(
"Sending multi-hop request to %s for %s (%d hops).
\n
"
,
format_address
(
neigh
->
address
),
format_prefix
(
prefix
,
plen
),
hop_count
);
v4
=
plen
>=
96
&&
v4mapped
(
prefix
);
pb
=
v4
?
((
plen
-
96
)
+
7
)
/
8
:
(
plen
+
7
)
/
8
;
len
=
6
+
8
+
pb
;
rc
=
start_unicast_message
(
neigh
,
MESSAGE_MH_REQUEST
,
len
);
if
(
rc
<
0
)
return
;
accumulate_unicast_byte
(
neigh
,
v4
?
1
:
2
);
accumulate_unicast_byte
(
neigh
,
v4
?
plen
-
96
:
plen
);
accumulate_unicast_short
(
neigh
,
seqno
);
accumulate_unicast_byte
(
neigh
,
hop_count
);
accumulate_unicast_byte
(
neigh
,
0
);
accumulate_unicast_bytes
(
neigh
,
id
,
8
);
if
(
prefix
)
{
if
(
v4
)
accumulate_unicast_bytes
(
neigh
,
prefix
+
12
,
pb
);
else
accumulate_unicast_bytes
(
neigh
,
prefix
,
pb
);
}
end_unicast_message
(
neigh
,
MESSAGE_MH_REQUEST
,
len
);
}
void
send_request_resend
(
struct
neighbour
*
neigh
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
unsigned
short
seqno
,
unsigned
char
*
id
)
{
int
delay
;
if
(
neigh
)
send_unicast_multihop_request
(
neigh
,
prefix
,
plen
,
seqno
,
id
,
127
);
else
send_multihop_request
(
NULL
,
prefix
,
plen
,
seqno
,
id
,
127
);
delay
=
2000
;
delay
=
MIN
(
delay
,
wireless_hello_interval
/
2
);
delay
=
MIN
(
delay
,
wired_hello_interval
/
2
);
delay
=
MAX
(
delay
,
10
);
record_resend
(
RESEND_REQUEST
,
prefix
,
plen
,
seqno
,
id
,
neigh
?
neigh
->
network
:
NULL
,
delay
);
}
void
handle_request
(
struct
neighbour
*
neigh
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
unsigned
char
hop_count
,
unsigned
short
seqno
,
const
unsigned
char
*
id
)
{
struct
xroute
*
xroute
;
struct
route
*
route
;
struct
neighbour
*
successor
=
NULL
;
xroute
=
find_xroute
(
prefix
,
plen
);
if
(
xroute
)
{
if
(
hop_count
>
0
&&
memcmp
(
id
,
myid
,
8
)
==
0
)
{
if
(
seqno_compare
(
seqno
,
myseqno
)
>
0
)
{
if
(
seqno_minus
(
seqno
,
myseqno
)
>
100
)
{
/* Hopelessly out-of-date request */
return
;
}
update_myseqno
(
1
);
}
}
send_update
(
neigh
->
network
,
1
,
prefix
,
plen
);
return
;
}
route
=
find_installed_route
(
prefix
,
plen
);
if
(
route
&&
(
route
->
metric
<
INFINITY
&&
(
memcmp
(
id
,
route
->
src
->
id
,
8
)
!=
0
||
seqno_compare
(
seqno
,
route
->
seqno
)
<=
0
)))
{
send_update
(
neigh
->
network
,
1
,
prefix
,
plen
);
return
;
}
if
(
hop_count
<=
1
)
return
;
if
(
route
&&
memcmp
(
id
,
route
->
src
->
id
,
8
)
==
0
&&
seqno_minus
(
seqno
,
route
->
seqno
)
>
100
)
{
/* Hopelessly out-of-date */
return
;
}
if
(
request_redundant
(
neigh
->
network
,
prefix
,
plen
,
seqno
,
id
))
return
;
/* Let's try to forward this request. */
if
(
route
&&
route
->
metric
<
INFINITY
)
successor
=
route
->
neigh
;
if
(
!
successor
||
successor
==
neigh
)
{
/* We were about to forward a request to its requestor. Try to
find a different neighbour to forward the request to. */
struct
route
*
other_route
;
other_route
=
find_best_route
(
prefix
,
plen
,
0
,
neigh
);
if
(
other_route
&&
other_route
->
metric
<
INFINITY
)
successor
=
other_route
->
neigh
;
}
if
(
!
successor
||
successor
==
neigh
)
/* Give up */
return
;
send_unicast_multihop_request
(
successor
,
prefix
,
plen
,
seqno
,
id
,
hop_count
-
1
);
record_resend
(
RESEND_REQUEST
,
prefix
,
plen
,
seqno
,
id
,
neigh
->
network
,
0
);
}
message.h
View file @
7e7eafae
...
@@ -25,6 +25,19 @@ THE SOFTWARE.
...
@@ -25,6 +25,19 @@ THE SOFTWARE.
#define BUCKET_TOKENS_MAX 200
#define BUCKET_TOKENS_MAX 200
#define BUCKET_TOKENS_PER_SEC 40
#define BUCKET_TOKENS_PER_SEC 40
#define MESSAGE_PAD1 0
#define MESSAGE_PADN 1
#define MESSAGE_ACK_REQ 2
#define MESSAGE_ACK 3
#define MESSAGE_HELLO 4
#define MESSAGE_IHU 5
#define MESSAGE_ROUTER_ID 6
#define MESSAGE_NH 7
#define MESSAGE_UPDATE 8
#define MESSAGE_REQUEST 9
#define MESSAGE_MH_REQUEST 10
extern
unsigned
short
myseqno
;
extern
unsigned
short
myseqno
;
extern
struct
timeval
seqno_time
;
extern
struct
timeval
seqno_time
;
extern
int
seqno_interval
;
extern
int
seqno_interval
;
...
@@ -35,32 +48,20 @@ extern int broadcast_ihu;
...
@@ -35,32 +48,20 @@ extern int broadcast_ihu;
extern
int
split_horizon
;
extern
int
split_horizon
;
extern
struct
timeval
update_flush_timeout
;
extern
struct
timeval
update_flush_timeout
;
extern
const
unsigned
char
packet_header
[
8
];
extern
unsigned
char
packet_header
[
4
];
extern
struct
neighbour
*
unicast_neighbour
;
extern
struct
neighbour
*
unicast_neighbour
;
extern
struct
timeval
unicast_flush_timeout
;
extern
struct
timeval
unicast_flush_timeout
;
unsigned
short
hash_id
(
const
unsigned
char
*
id
)
ATTRIBUTE
((
pure
));
void
parse_packet
(
const
unsigned
char
*
from
,
struct
network
*
net
,
void
parse_packet
(
const
unsigned
char
*
from
,
struct
network
*
net
,
const
unsigned
char
*
packet
,
int
len
);
const
unsigned
char
*
packet
,
int
packetlen
);
void
handle_request
(
struct
neighbour
*
neigh
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
unsigned
char
hop_count
,
unsigned
short
seqno
,
unsigned
short
router_hash
);
void
flushbuf
(
struct
network
*
net
);
void
flushbuf
(
struct
network
*
net
);
void
flushupdates
(
void
);
void
send_ack
(
struct
neighbour
*
neigh
,
unsigned
short
nonce
,
unsigned
short
interval
);
void
send_hello_noupdate
(
struct
network
*
net
,
unsigned
interval
);
void
send_hello_noupdate
(
struct
network
*
net
,
unsigned
interval
);
void
send_hello
(
struct
network
*
net
);
void
send_hello
(
struct
network
*
net
);
void
send_request
(
struct
network
*
net
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
unsigned
char
hop_count
,
unsigned
short
seqno
,
unsigned
short
router_hash
);
void
send_request_resend
(
struct
neighbour
*
neigh
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
unsigned
short
seqno
,
unsigned
short
router_hash
);
void
flush_unicast
(
int
dofree
);
void
flush_unicast
(
int
dofree
);
void
send_unicast_request
(
struct
neighbour
*
neigh
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
unsigned
char
hop_count
,
unsigned
short
seqno
,
unsigned
short
router_hash
);
void
send_update
(
struct
network
*
net
,
int
urgent
,
void
send_update
(
struct
network
*
net
,
int
urgent
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
);
const
unsigned
char
*
prefix
,
unsigned
char
plen
);
void
send_update_resend
(
struct
network
*
net
,
void
send_update_resend
(
struct
network
*
net
,
...
@@ -69,5 +70,22 @@ void update_myseqno(int force);
...
@@ -69,5 +70,22 @@ void update_myseqno(int force);
void
send_self_update
(
struct
network
*
net
,
int
force_seqno
);
void
send_self_update
(
struct
network
*
net
,
int
force_seqno
);
void
send_ihu
(
struct
neighbour
*
neigh
,
struct
network
*
net
);
void
send_ihu
(
struct
neighbour
*
neigh
,
struct
network
*
net
);
void
send_marginal_ihu
(
struct
network
*
net
);
void
send_marginal_ihu
(
struct
network
*
net
);
void
schedule_flush_now
(
struct
network
*
net
);
void
send_request
(
struct
network
*
net
,
void
flushupdates
(
void
);
const
unsigned
char
*
prefix
,
unsigned
char
plen
);
void
send_unicast_request
(
struct
neighbour
*
neigh
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
);
void
send_multihop_request
(
struct
network
*
net
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
unsigned
short
seqno
,
const
unsigned
char
*
id
,
unsigned
short
hop_count
);
void
send_unicast_multihop_request
(
struct
neighbour
*
neigh
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
unsigned
short
seqno
,
const
unsigned
char
*
id
,
unsigned
short
hop_count
);
void
send_request_resend
(
struct
neighbour
*
neigh
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
unsigned
short
seqno
,
unsigned
char
*
id
);
void
handle_request
(
struct
neighbour
*
neigh
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
unsigned
char
hop_count
,
unsigned
short
seqno
,
const
unsigned
char
*
id
);
network.c
View file @
7e7eafae
...
@@ -287,7 +287,7 @@ network_up(struct network *net, int up)
...
@@ -287,7 +287,7 @@ network_up(struct network *net, int up)
delay_jitter
(
&
net
->
update_time
,
&
net
->
update_timeout
,
delay_jitter
(
&
net
->
update_time
,
&
net
->
update_timeout
,
update_interval
);
update_interval
);
send_hello
(
net
);
send_hello
(
net
);
send_request
(
net
,
NULL
,
0
,
0
,
0
,
0
);
send_request
(
net
,
NULL
,
0
);
}
else
{
}
else
{
net
->
buffered
=
0
;
net
->
buffered
=
0
;
net
->
bufsize
=
0
;
net
->
bufsize
=
0
;
...
@@ -359,7 +359,7 @@ check_networks(void)
...
@@ -359,7 +359,7 @@ check_networks(void)
rc
=
check_network_ipv4
(
net
);
rc
=
check_network_ipv4
(
net
);
if
(
rc
>
0
)
{
if
(
rc
>
0
)
{
send_request
(
net
,
NULL
,
0
,
0
,
0
,
0
);
send_request
(
net
,
NULL
,
0
);
send_update
(
net
,
0
,
NULL
,
0
);
send_update
(
net
,
0
,
NULL
,
0
);
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a 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