pause on "serious failure to receive".
Some misc fixes are also folded in here.
/* Returns -1 on errors that are fatal for the socket, -2 for those that aren't */
-int get_raw_packet(struct dhcpMessage *payload, int fd)
+int udhcp_recv_raw_packet(struct dhcpMessage *payload, int fd)
{
int bytes;
struct udp_dhcp_packet packet;
bytes = safe_read(fd, &packet, sizeof(packet));
if (bytes < 0) {
DEBUG("Cannot read on raw listening socket - ignoring");
- sleep(1); /* possible down interface, looping condition */
+ /* NB: possible down interface, etc. Caller should pause. */
return bytes; /* returns -1 */
}
void udhcp_init_header(struct dhcpMessage *packet, char type);
-int udhcp_recv_packet(struct dhcpMessage *packet, int fd);
+/*int udhcp_recv_raw_packet(struct dhcpMessage *payload, int fd); - in dhcpc.h */
+int udhcp_recv_kernel_packet(struct dhcpMessage *packet, int fd);
+
int udhcp_send_raw_packet(struct dhcpMessage *payload,
uint32_t source_ip, int source_port,
uint32_t dest_ip, int dest_port,
unsigned opt;
int max_fd;
int retval;
- int len;
struct timeval tv;
- struct in_addr temp_addr;
struct dhcpMessage packet;
fd_set rfds;
if (packet_num == 0)
xid = random_xid();
- /* send discover packet */
send_discover(xid, requested_ip); /* broadcast */
timeout = discover_timeout;
retval = 1;
goto ret;
}
- /* wait to try again */
+ /* wait before trying again */
timeout = tryagain_timeout;
packet_num = 0;
continue;
case REQUESTING:
if (packet_num < discover_retries) {
/* send request packet */
- if (state == RENEW_REQUESTED)
- send_renew(xid, server_addr, requested_ip); /* unicast */
- else send_selecting(xid, server_addr, requested_ip); /* broadcast */
+ if (state == RENEW_REQUESTED) /* unicast */
+ send_renew(xid, server_addr, requested_ip);
+ else /* broadcast */
+ send_selecting(xid, server_addr, requested_ip);
- timeout = ((packet_num == 2) ? 10 : 2);
+ timeout = discover_timeout;
packet_num++;
continue;
}
/* Timed out, enter rebinding state */
DEBUG("Entering rebinding state");
state = REBINDING;
- continue;
+ /* fall right through */
case REBINDING:
/* Lease is *really* about to run out,
* try to find DHCP server using broadcast */
/* select() didn't timeout, something did happen. */
/* Is is a packet? */
if (listen_mode != LISTEN_NONE && FD_ISSET(sockfd, &rfds)) {
+ int len;
/* A packet is ready, read it */
if (listen_mode == LISTEN_KERNEL)
- len = udhcp_recv_packet(&packet, sockfd);
+ len = udhcp_recv_kernel_packet(&packet, sockfd);
else
- len = get_raw_packet(&packet, sockfd);
-
- /* If this packet will turn out to be unrelated/bogus,
- * we will go back and wait for next one.
- * Be sure timeout is properly decreased. */
- already_waited_sec += (unsigned)monotonic_sec() - timestamp_before_wait;
-
+ len = udhcp_recv_raw_packet(&packet, sockfd);
if (len == -1) { /* error is severe, reopen socket */
DEBUG("error on read, %s, reopening socket", strerror(errno));
+ sleep(discover_timeout); /* 3 seconds by default */
change_listen_mode(listen_mode); /* just close and reopen */
}
- if (len < 0) continue;
+ /* If this packet will turn out to be unrelated/bogus,
+ * we will go back and wait for next one.
+ * Be sure timeout is properly decreased. */
+ already_waited_sec += (unsigned)monotonic_sec() - timestamp_before_wait;
+ if (len < 0)
+ continue;
if (packet.xid != xid) {
DEBUG("Ignoring XID %x (our xid is %x)",
#endif
/* enter bound state */
timeout = lease_seconds / 2;
- temp_addr.s_addr = packet.yiaddr;
- bb_info_msg("Lease of %s obtained, lease time %u",
- inet_ntoa(temp_addr), (unsigned)lease_seconds);
+ {
+ struct in_addr temp_addr;
+ temp_addr.s_addr = packet.yiaddr;
+ bb_info_msg("Lease of %s obtained, lease time %u",
+ inet_ntoa(temp_addr), (unsigned)lease_seconds);
+ }
requested_ip = packet.yiaddr;
udhcp_run_script(&packet,
((state == RENEWING || state == REBINDING) ? "renew" : "bound"));
int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr);
int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr);
int send_release(uint32_t server, uint32_t ciaddr);
-int get_raw_packet(struct dhcpMessage *payload, int fd);
+
+int udhcp_recv_raw_packet(struct dhcpMessage *payload, int fd);
#if __GNUC_PREREQ(4,1)
# pragma GCC visibility pop
default: continue; /* signal or error (probably EINTR) */
}
- bytes = udhcp_recv_packet(&packet, server_socket); /* this waits for a packet - idle */
+ bytes = udhcp_recv_kernel_packet(&packet, server_socket); /* this waits for a packet - idle */
if (bytes < 0) {
if (bytes == -1 && errno != EINTR) {
DEBUG("error on read, %s, reopening socket", strerror(errno));
case DHCPDISCOVER:
DEBUG("Received DISCOVER");
- if (sendOffer(&packet) < 0) {
+ if (send_offer(&packet) < 0) {
bb_error_msg("send OFFER failed");
}
break;
if (server_id_align == server_config.server && requested
&& requested_align == lease->yiaddr
) {
- sendACK(&packet, lease->yiaddr);
+ send_ACK(&packet, lease->yiaddr);
}
} else if (requested) {
/* INIT-REBOOT State */
if (lease->yiaddr == requested_align)
- sendACK(&packet, lease->yiaddr);
+ send_ACK(&packet, lease->yiaddr);
else
- sendNAK(&packet);
+ send_NAK(&packet);
} else if (lease->yiaddr == packet.ciaddr) {
/* RENEWING or REBINDING State */
- sendACK(&packet, lease->yiaddr);
- } else {
- /* don't know what to do!!!! */
- sendNAK(&packet);
+ send_ACK(&packet, lease->yiaddr);
+ } else { /* don't know what to do!!!! */
+ send_NAK(&packet);
}
/* what to do if we have no record of the client */
memset(lease->chaddr, 0, 16);
/* make some contention for this address */
} else
- sendNAK(&packet);
+ send_NAK(&packet);
} else {
uint32_t r = ntohl(requested_align);
if (r < server_config.start_ip
|| r > server_config.end_ip
) {
- sendNAK(&packet);
+ send_NAK(&packet);
}
/* else remain silent */
}
/*** serverpacket.h ***/
-int sendOffer(struct dhcpMessage *oldpacket);
-int sendNAK(struct dhcpMessage *oldpacket);
-int sendACK(struct dhcpMessage *oldpacket, uint32_t yiaddr);
+int send_offer(struct dhcpMessage *oldpacket);
+int send_NAK(struct dhcpMessage *oldpacket);
+int send_ACK(struct dhcpMessage *oldpacket, uint32_t yiaddr);
int send_inform(struct dhcpMessage *oldpacket);
if (select(max_socket + 1, &rfds, NULL, NULL, &tv) > 0) {
/* server */
if (FD_ISSET(fds[0], &rfds)) {
- packlen = udhcp_recv_packet(&dhcp_msg, fds[0]);
+ packlen = udhcp_recv_kernel_packet(&dhcp_msg, fds[0]);
if (packlen > 0) {
pass_back(&dhcp_msg, packlen, fds);
}
/* read a packet from socket fd, return -1 on read error, -2 on packet error */
-int udhcp_recv_packet(struct dhcpMessage *packet, int fd)
+int udhcp_recv_kernel_packet(struct dhcpMessage *packet, int fd)
{
int bytes;
unsigned char *vendor;
/* send a dhcp packet, if force broadcast is set, the packet will be broadcast to the client */
static int send_packet(struct dhcpMessage *payload, int force_broadcast)
{
- int ret;
-
if (payload->giaddr)
- ret = send_packet_to_relay(payload);
- else ret = send_packet_to_client(payload, force_broadcast);
- return ret;
+ return send_packet_to_relay(payload);
+ return send_packet_to_client(payload, force_broadcast);
}
/* send a DHCP OFFER to a DHCP DISCOVER */
-int sendOffer(struct dhcpMessage *oldpacket)
+int send_offer(struct dhcpMessage *oldpacket)
{
struct dhcpMessage packet;
struct dhcpOfferedAddr *lease = NULL;
}
-int sendNAK(struct dhcpMessage *oldpacket)
+int send_NAK(struct dhcpMessage *oldpacket)
{
struct dhcpMessage packet;
}
-int sendACK(struct dhcpMessage *oldpacket, uint32_t yiaddr)
+int send_ACK(struct dhcpMessage *oldpacket, uint32_t yiaddr)
{
struct dhcpMessage packet;
struct option_set *curr;