struct sd_dhcp_client {
DHCPState state;
sd_event *event;
+ int event_priority;
sd_event_source *timeout_resend;
int index;
int fd;
usec_t next_timeout = 0;
uint32_t time_left;
uint16_t secs;
- int err = 0;
+ int r = 0;
+
+ assert(s);
+ assert(client);
+ assert(client->event);
switch (client->state) {
case DHCP_STATE_RENEWING:
next_timeout += (random_u32() & 0x1fffff);
- err = sd_event_add_monotonic(client->event, next_timeout,
+ r = sd_event_add_monotonic(client->event, next_timeout,
10 * USEC_PER_MSEC,
client_timeout_resend, client,
&client->timeout_resend);
- if (err < 0)
+ if (r < 0)
+ goto error;
+
+ r = sd_event_source_set_priority(client->timeout_resend, client->event_priority);
+ if (r < 0)
goto error;
secs = (usec - client->start_time) / USEC_PER_SEC;
switch (client->state) {
case DHCP_STATE_INIT:
- err = client_send_discover(client, secs);
- if (err >= 0) {
+ r = client_send_discover(client, secs);
+ if (r >= 0) {
client->state = DHCP_STATE_SELECTING;
client->attempt = 1;
} else {
break;
case DHCP_STATE_SELECTING:
- err = client_send_discover(client, secs);
- if (err < 0 && client->attempt >= 64)
+ r = client_send_discover(client, secs);
+ if (r < 0 && client->attempt >= 64)
goto error;
break;
case DHCP_STATE_REQUESTING:
case DHCP_STATE_RENEWING:
case DHCP_STATE_REBINDING:
- err = client_send_request(client, secs);
- if (err < 0 && client->attempt >= 64)
+ r = client_send_request(client, secs);
+ if (r < 0 && client->attempt >= 64)
goto error;
client->request_sent = usec;
return 0;
error:
- client_stop(client, err);
+ client_stop(client, r);
/* Errors were dealt with when stopping the client, don't spill
errors into the event loop handler */
static int client_initialize_events(sd_dhcp_client *client, usec_t usec) {
int r;
+ assert(client);
+ assert(client->event);
+
r = sd_event_add_io(client->event, client->fd, EPOLLIN,
client_receive_message, client,
&client->receive_message);
if (r < 0)
goto error;
+ r = sd_event_source_set_priority(client->receive_message, client->event_priority);
+ if (r < 0)
+ goto error;
+
r = sd_event_add_monotonic(client->event, usec, 0,
client_timeout_resend, client,
&client->timeout_resend);
+ if (r < 0)
+ goto error;
+
+ r = sd_event_source_set_priority(client->timeout_resend, client->event_priority);
error:
if (r < 0)
uint64_t next_timeout;
int r;
+ assert(client);
+ assert(client->event);
+
if (client->lease->lifetime < 10)
return -EINVAL;
if (r < 0)
return r;
+ r = sd_event_source_set_priority(client->timeout_t1, client->event_priority);
+ if (r < 0)
+ return r;
+
if (!client->lease->t2)
client->lease->t2 = client->lease->lifetime * 7 / 8;
if (r < 0)
return r;
+ r = sd_event_source_set_priority(client->timeout_t2, client->event_priority);
+ if (r < 0)
+ return r;
+
next_timeout = client_compute_timeout(client->request_sent,
client->lease->lifetime);
if (next_timeout < usec)
if (r < 0)
return r;
+ r = sd_event_source_set_priority(client->timeout_expire, client->event_priority);
+ if (r < 0)
+ return r;
+
return 0;
}
DHCPPacket *message;
usec_t time_now;
+ assert(s);
+ assert(client);
+ assert(client->event);
+
len = read(fd, &buf, buflen);
if (len < 0)
return 0;
&client->timeout_resend);
if (r < 0)
goto error;
+
+ r = sd_event_source_set_priority(client->timeout_resend, client->event_priority);
+ if (r < 0)
+ goto error;
}
break;
int r;
assert_return(client, -EINVAL);
+ assert_return(client->event, -EINVAL);
assert_return(client->index > 0, -EINVAL);
assert_return(client->state == DHCP_STATE_INIT ||
client->state == DHCP_STATE_INIT_REBOOT, -EBUSY);
return client_stop(client, DHCP_EVENT_STOP);
}
-sd_dhcp_client *sd_dhcp_client_free(sd_dhcp_client *client) {
- assert_return(client, NULL);
+int sd_dhcp_client_attach_event(sd_dhcp_client *client, sd_event *event, int priority) {
+ int r;
+
+ assert_return(client, -EINVAL);
+ assert_return(!client->event, -EBUSY);
+
+ if (event)
+ client->event = sd_event_ref(event);
+ else {
+ r = sd_event_default(&client->event);
+ if (r < 0)
+ return 0;
+ }
+
+ client->event_priority = priority;
+
+ return 0;
+}
+
+int sd_dhcp_client_detach_event(sd_dhcp_client *client) {
+ assert_return(client, -EINVAL);
+
+ client->event = sd_event_unref(client->event);
+
+ return 0;
+}
+
+sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client) {
+ if (!client)
+ return NULL;
+
+ return client->event;
+}
+
+void sd_dhcp_client_free(sd_dhcp_client *client) {
+ if (!client)
+ return;
sd_dhcp_client_stop(client);
+ sd_dhcp_client_detach_event(client);
- sd_event_unref(client->event);
free(client->req_opts);
free(client);
-
- return NULL;
}
-sd_dhcp_client *sd_dhcp_client_new(sd_event *event) {
- sd_dhcp_client *client;
+DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_client*, sd_dhcp_client_free);
+#define _cleanup_dhcp_client_free_ _cleanup_(sd_dhcp_client_freep)
+
+int sd_dhcp_client_new(sd_dhcp_client **ret) {
+ _cleanup_dhcp_client_free_ sd_dhcp_client *client = NULL;
- assert_return(event, NULL);
+ assert_return(ret, -EINVAL);
client = new0(sd_dhcp_client, 1);
if (!client)
- return NULL;
+ return -ENOMEM;
- client->event = sd_event_ref(event);
client->state = DHCP_STATE_INIT;
client->index = -1;
client->fd = -1;
client->req_opts_size = ELEMENTSOF(default_req_opts);
client->req_opts = memdup(default_req_opts, client->req_opts_size);
- if (!client->req_opts) {
- free(client);
- return NULL;
- }
+ if (!client->req_opts)
+ return -ENOMEM;
+
+ *ret = client;
+ client = NULL;
- return client;
+ return 0;
}