-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ping to check connection #84
Conversation
d469853
to
7e3ee49
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking good, but I think redefining the responsibilities of the various components (enftun_conn_state
, enftun_echo
, enftun_tls
, and enftun_netlink
) can make the code more clear.
-
enftun_tls
is now aware of theconn_state
internals to call things liketls->conn_state->echo.send_ping
andtls->conn_state->send_request_cb(...)
. This tight coupling makes the code hard to reason about (changing the internal ofconn_state
might break thetls
internals).Instead, let's look for a more generic mechanism. One option is to define a callback
typedef void (*enftun_tls_on_receive )()
.conn_state
can register a function of this type withtls
, which call it everytime a packet is received. (It would actually be better to define this on thechannel
, so that is could be used for any transport, not justtls
.)However, we already have a generic mechanism to examine incoming packets --- the ingress
chain
.conn_state
can register a handler at the head of the ingress chain. It will be called for each incoming packet. Rather than parsing or consuming the packet, it can just reset the echo request timer. -
The
enftun_echo
module is fairly anemic. This isn't necessarily a bad thing. However, here it can lead to some problems.For example, it is not safe to call the
enftun_echo_send_request
function if there is already an outstanding echo request queued. However, this is not enforced. The caller must track that state and manage it. If there are multiple callers, who knows...Extending the responsibilities of this module and making the public API more high-level will help. Specifically, move the request and reply timers out of
conn_state
into this module.So this module becomes responsible for sending heartbeats periodically and on-demand, waiting for a reply to the outstanding heartbeat, and notifying a registered callback if a heartbeat reply is not received. Renaming to
enftun_heartbeat
will better reflect this expanding functionality.enftun_heartbeat_init(..., int (*on_timeout)() )
-on_timeout
is called if a echo reply is not receivedenftun_heartbeat_start(...)
- start sending heartbeats periodicallyenftun_heartbeat_restart(...)
- reset the timer for periodic heartbeatsenftun_heartbeat_stop(...)
- stop sending heartbeats; cancel any outstandingcrb
s.enftun_heartbeat_now(...)
- send a heartbeat immediately (or schedule to send one, if one is already in flight)
-
The
enftun_netlink
module is now aware of the heartbeat stuff and has to return a special error codeNEEDS_PING
. That sort of coupling belongs in theconn_state
module, which ties everything together.enftun_netlink_read_message
is not longer properly returning the number of bytes read, etc.I suggest not modifying
enftun_netlink_read_message
. Instead, add helper function(s) inconn_state
for parsing the message.conn_state
can call bothenftun_netlink_read_message
and the helper functions to determine if it wants to do something with the message. The helper function(s) will need to#include
the netlink headers, but that's ok.
9bd260f
to
ff2eea9
Compare
b17ae2a
to
4ca1887
Compare
src/heartbeat.c
Outdated
send_heartbeat(struct enftun_heartbeat* heartbeat) | ||
{ | ||
heartbeat->hb_inflight = true; | ||
heartbeat->reply_recieved = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
recieved -> received
src/heartbeat.c
Outdated
} | ||
|
||
heartbeat->hb_inflight = false; | ||
enftun_log_info("Recieved ping reply\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make this enftun_log_debug
.
src/heartbeat.h
Outdated
{ | ||
struct enftun_channel* chan; | ||
|
||
const struct in6_addr* addr; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of addr
, call this source
or source_addr
.
Also, add a similar member,dest
or dest_addr
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, change the dest address from all_routers/nodes
to fe80::1
.
src/heartbeat.h
Outdated
enftun_heartbeat_init(struct enftun_heartbeat* heartbeat, | ||
uv_loop_t* loop, | ||
struct enftun_channel* chan, | ||
const struct in6_addr* ipv6, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of ipv6
, call this source
or source_addr
. Also, add the dest
or dest_addr
parameter.
src/heartbeat.c
Outdated
if (!icmph) | ||
goto pass; | ||
|
||
heartbeat->reply_recieved = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to cancel the reply timer here and start the request timer again.
{ | ||
if (crb->status) | ||
enftun_log_error("PING: failed to send heartbeat reply: %d\n", | ||
crb->status); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than ignoring the error, we should have enftun reconnect.
259c862
to
506d13e
Compare
@kathrynfejer Could you please rebase this on the latest master (with the just merged psock stuff). |
-ping the network every 12 seconds, waits for a response -after 3 seconds, if no response, reconnect
506d13e
to
16a0ab6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few comments, but this is looking pretty good.
Unfortunately, I don't have time to fully review the main reconnect logic today, to get this merged. Could you open three new PRs with the following subsets of changes --- those I can get merged today.
- Just the change to reserve 2 bytes in the
enftun_packet_reset
, rather than inenftun_crb_read
. - Just the addition of icmp6 echo request/reply creating and parsing (
enftun_icmp6_echo_reply_pull
andenftun_icmp6_echo_request
inicmp.h/c
). - Just the addition of the heartbeat service (
heartbeat.h,c
and the associated parameters inconfig.h/c
).
Those three I can approve and merge today.
Then a final PR with the changes to conn_state.c
, ip.h,c
and enftun.c
. That one won't get merged until next week, when I can spend more time reviewing the logic in conn_state.
ctx->config.fwmark)) < 0) | ||
if ((rc = enftun_conn_state_prepare( | ||
&ctx->conn_state, &ctx->loop, trigger_reconnect, (void*) ctx, | ||
ctx->config.fwmark, &ctx->tlschan, &ctx->ipv6, &ip6_self, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ip6_self
has the correct address, has a misleading name.
Instead, let's create a new constant ip6_enf_router
in ip.h,c
with the same value and use it instead. Add a comment stating that enftun
and the ENF router share the same IP since they split the duties of a traditional IPv6 router.
40d58e2
to
dc5e34c
Compare
@@ -102,6 +120,10 @@ enftun_conn_state_prepare(struct enftun_conn_state* conn_state, | |||
int | |||
enftun_conn_state_close(struct enftun_conn_state* conn_state) | |||
{ | |||
int rc = enftun_heartbeat_free(&conn_state->heartbeat); | |||
if (0 != rc) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still need to close netlink, even if the hearbeat free fails. Just log a warning and continue.
Replaced by #137. The core of this PR was cherry-picked into it. |
Currently
enftun
can determine if there has been a connectivity change on the client's end and reconnects, but if the router or ENF is down,enftun
does not recognize it for some time. By pinging the network we are connected to at configurable intervals, we can monitor our connectivity and increase availability.This pings the network at the configured timeouts and whenever a new address or new link netlink event occurs. If one of these two occurs at the same time or within the reply timeout, only one echo request is sent.
Fixes #6 and Connected to #7