Commit Graph

566 Commits

Author SHA1 Message Date
Nicholas J. Kain
277f0f67c5 When converting timeout from ll to int, also guard against underflow. 2015-05-27 15:00:02 -04:00
Nicholas J. Kain
e02d30dcc5 renewTime, rebindTime should be unsigned long long.
While we're at it, rearrange the client state struct to
save some space lost to padding.
2015-05-27 13:11:23 -04:00
Nicholas J. Kain
abb1b54bfe Fix an overflow that can cause spuriously short epoll timeouts.
Lease times and arp timeouts are all calculated using long long,
but epoll takes its timeout argument as an int.  Guard against
timeouts > INT_MAX but < UINT_MAX wrapping and causing spuriously
short timeouts when converted to a signed int.

This problem has been observed in the wild.  Thanks to thypon
for a detailed strace that pointed me towards this issue.
2015-05-27 12:58:42 -04:00
Nicholas J. Kain
ba875d4b2e Failsafe should only trigger is the new timeout is also zero.
This is what I get for rushing!
2015-05-27 12:35:16 -04:00
Nicholas J. Kain
f061a78a18 Fix dumb mistake in patch before last; epoll timeout is in ms, not s. 2015-05-27 12:29:46 -04:00
Nicholas J. Kain
2057d7cd18 Improve compatibility with clang. 2015-05-27 12:23:50 -04:00
Nicholas J. Kain
8273b383ab Add a failsafe to prevent epoll busy-spin. 2015-05-27 12:23:16 -04:00
Nicholas J. Kain
6c136c3f85 Make add_option_(vendor|hostname)() not use ndhc internals.
This change makes it easier to fuzz test, but should have no
functional effect on ndhc's behavior.
2015-02-20 03:58:25 -05:00
Nicholas J. Kain
646931a2bf xid should be regenerated whenever we start a new discover cycle.
Somewhere along the line it quit being set at the start of discovery
and was always 0.  This is clearly not desired behavior.

Found by manual examination of packets while fuzzing the options
parser.
2015-02-20 03:48:13 -05:00
Nicholas J. Kain
b8df1b33f5 Fix the timeouts for rebinding and renewing.
Now renew/rebind requests will be sent every 60+/-10s.
2015-02-18 11:03:58 -05:00
Nicholas J. Kain
b3bd13d45f Fix the return values of dhcp_packet_get and arp_packet_get.
This corrects a bug where stale dhcp packets would get reprocessed,
causing very bad behavior; an issue that was introduced in the
coroutine conversion.
2015-02-18 11:02:13 -05:00
Nicholas J. Kain
a627e9dc9c Minor changes to log messages and comments. 2015-02-18 09:56:38 -05:00
Nicholas J. Kain
3ede5fbe33 Handle the release and renew signals again. 2015-02-18 07:31:19 -05:00
Nicholas J. Kain
731bd14f0a reinit_selecting() can't fail; convert it to void return. 2015-02-18 07:12:35 -05:00
Nicholas J. Kain
89d77313c6 Deconfigure the interface if we've failed a fingerprint check.
We've moved to a new network, so keeping the old information
is counterproductive.
2015-02-18 07:12:22 -05:00
Nicholas J. Kain
29da5d21a4 Tolerate DHCP ACKs in REQUESTING state that don't match the serverid.
Some networks have multiple DHCP servers that don't respect the
serverid that is specified in DHCPREQUESTs.

Instead we simply check to see that the yiaddr matches.

While we're at it, ignore DHCP NAK during REQUESTING state.  It
doesn't really make sense.  Instead we should just wait for
timeout.
2015-02-18 06:52:59 -05:00
Nicholas J. Kain
f28495a58b selecting_packet() shouldn't take the xid from the packet.
This change actually has no effect because incoming dhcp packets
that differ from our xid are dropped, so the xid is always changed
to the same value that it already has.
2015-02-18 06:01:43 -05:00
Nicholas J. Kain
da7d34a300 Bump version to 2.0.
When the coroutine restructuring is fully tested and debugged, it
will definitely be a significant enough change for a full version
bump.
2015-02-18 05:41:31 -05:00
Nicholas J. Kain
69cf41f1b1 Only process one epoll event at a time.
If ndhc were a high-performance program that handled lots of events,
this change would harm performance.  But it is not, and it implicitly
believes that events come in one at a time.  Processing batches
would make it harder to assure correctness while also never allocating
memory at runtime.

The previous structure was fine when everything was handled
immediately by callbacks, but it isn't now.
2015-02-18 05:36:13 -05:00
Nicholas J. Kain
99ce918a31 Use a coroutine instead of several callback state machines.
This change makes it much easier to reason about ndhc's behavior
and properly handle errors.

It is a very large changeset, but there is no way to make this
sort of change incrementally.  Lease acquisition is tested to
work.

It is highly likely that some bugs were both introduced and
squashed here.  Some obvious code cleanups will quickly follow.
2015-02-18 05:31:13 -05:00
Nicholas J. Kain
37aa866ae4 Move action dispatch out of main epoll loop. 2015-02-15 06:48:49 -05:00
Nicholas J. Kain
61387408d0 Separate event state gathering from action dispatch in main epoll loop.
This is the first step towards using coroutines.
2015-02-15 06:38:03 -05:00
Nicholas J. Kain
658d2954b8 Reduce log spam. 2015-02-15 02:58:51 -05:00
Nicholas J. Kain
e874373dcd Check link carrier via ifch and netlink instead of ioctl.
Thus, ioctl can once again be removed from the ndhc seccomp whitelist.
2015-02-15 02:50:29 -05:00
Nicholas J. Kain
6c9ca9eecd If ifchd commands fail, propagate the failure back to ndhc. 2015-02-15 02:29:37 -05:00
Nicholas J. Kain
33aa5b13de Recommend using a process supervisor for high reliability in README. 2015-02-14 20:50:46 -05:00
Nicholas J. Kain
5b82be8b00 If ifchd interactions fail, terminate.
Ideally we would pause and resume state, but for now just bail out.
If ndhc is process-supervised, it will recover to the proper state
quickly.
2015-02-14 20:47:14 -05:00
Nicholas J. Kain
170f87c0e7 Propagate returns through ifchange_(deconfig|bind).
While doing so remove unnecessary argument null checks and
make sure not to alter the stored interface state if the
ifch requests failed.
2015-02-14 19:10:23 -05:00
Nicholas J. Kain
44175bd77c Make ifch requests synchronous just like sockd requests.
This change paves the way for allowing ifch to notify the core ndhc
about failures.  It would be far too difficult to reason about the
state machine if the requests to ifch were asynchronous.

Currently ndhc assumes that ifch requests never fail, but this
is not always true because of eg, rfkill.
2015-02-14 16:49:50 -05:00
Nicholas J. Kain
61a48b0fb6 Fix the rfkill waiting. 2015-02-14 15:33:02 -05:00
Nicholas J. Kain
56cc05599a Add error handling for un-notified carrier downs in ifup_action. 2015-02-14 05:39:15 -05:00
Nicholas J. Kain
b6b778831c Add error handling for un-notified carrier downs when sending packets.
If a packet send failed because the carrier went down without a
netlink notification, then assume the hardware carrier was lost while
the machine was suspended (eg, ethernet cable pulled during suspend).

Simulate a netlink carrier down event and freeze the dhcp state
machine until a netlink carrier up event is received.

The ARP code is not yet handling this issue everywhere, but the
window of opportunity for it to happen there is much shorter.
2015-02-14 05:20:04 -05:00
Nicholas J. Kain
d0d8bcf3ff options.[ch] must still be valid C++11 because it is used in ndhs.
That means the [static 1] arg specifier cannot be used.
2015-02-14 02:14:30 -05:00
Nicholas J. Kain
00c9479c4c Mark more pointer arguments as never being null. 2015-02-14 01:46:02 -05:00
Nicholas J. Kain
0535b36534 dhcp.c: Make init_packet() not return a struct.
Just work via a pointer to not rely on the compiler being intelligent
and inlining.
2015-02-14 01:41:52 -05:00
Nicholas J. Kain
70c750f50c get_raw_packet: The read length check is stricter than necessary.
Allow reads with excess data beyond the packet to succeed if the
packet is still well-formed.
2015-02-14 01:40:06 -05:00
Nicholas J. Kain
a7cb063f0c state.c: cosmetic cleanups and a constification 2015-02-14 00:44:21 -05:00
Nicholas J. Kain
04840c261d Fix some c99 struct initializer uninitialized member warnings
that clang detects and GCC misses.
2015-02-13 23:25:42 -05:00
Nicholas J. Kain
702d8b0c5b Mark pointer arguments that cannot ever be null as [static 1].
Also constify some cases, too.
2015-02-13 23:14:08 -05:00
Nicholas J. Kain
cc806acc0b Indicate that client_state_t and client_config_t pointer args
cannot ever be null.

Could possibly improve code generation, and makes the intention clear.
2015-02-13 22:29:03 -05:00
Nicholas J. Kain
b6554c2931 Quiet the 'UDP length [] does not match header length' message.
It is triggered frequently when discarding invalid packets that were
received on the DHCP port and it seems to have little significance.
2015-02-13 21:56:34 -05:00
Nicholas J. Kain
b4b6ed8fd5 Check for carrier before sendto() or write() on interface fd.
Linux will quietly proceed as if the data were sent even if the carrier
is down and nothing actually happened.  There is still a tiny race
condition where the carrier could drop between the check and the actual
write, but we really can't do anything about that and it is a very
small race.
2015-02-13 21:53:15 -05:00
Nicholas J. Kain
911d4cc58e Fix the dhcp state bootstrapping when rfkill is set #3. 2015-02-13 19:08:50 -05:00
Nicholas J. Kain
2e679ed491 Fix the dhcp state bootstrapping when rfkill is set #2. 2015-02-13 18:35:44 -05:00
Nicholas J. Kain
a8af406307 Fix the dhcp state bootstrapping when rfkill is set. 2015-02-13 18:07:14 -05:00
Nicholas J. Kain
79a97131bc Handle the case where the rfkill is set when ndhc is initializing. 2015-02-13 17:50:24 -05:00
Nicholas J. Kain
5b050ba498 If the rfkill switch is enabled, do not react to netlink notifications
until the rfkill is disabled.  They will mostly fail outright.
2015-02-13 17:20:36 -05:00
Nicholas J. Kain
cf81573082 Fix a dumb typo in the previous commit. 2015-02-13 16:56:56 -05:00
Nicholas J. Kain
e3d4d4c1aa rfkill: Add support for reacting to radio kill switch events.
In order for this to work, the correct rfkill index must be specified
with the rfkill-idx option.

It might be possible to auto-detect the corresponding rfkill-idx option,
but I'm not sure if there's a guaranteed mapping between rfkill name and
interface name, as it seems that rfkills should represent phy devices
and not wlan devices.

The rfkill indexes can be found by checking
/sys/class/rfkill/rfkill<IDX>.
2015-02-13 16:25:36 -05:00
Nicholas J. Kain
3421f0c585 CMAKE_CROSSCOMPILE should be CMAKE_CROSSCOMPILING. 2015-02-13 05:12:55 -05:00