Make write() and sendto() properly handle short writes and errors in ndhc.
Make ndhc write a pidfile. Clean up defines.h and split out ifchd and ndhc specifics.
This commit is contained in:
parent
e781322b4d
commit
eb6009a5ee
@ -1,12 +1,14 @@
|
||||
#define MAX_PATH_LENGTH 1024
|
||||
#ifndef IFCHD_DEFINES_H_
|
||||
#define IFCHD_DEFINES_H_
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
#define PID_FILE_DEFAULT "/var/run/ifchd.pid"
|
||||
#define IFCHD_VERSION "0.8"
|
||||
|
||||
#define COMM_SOCKET_PATH "ifchange"
|
||||
#define MAX_BUF 1024
|
||||
#define MAXLINE 1024
|
||||
|
||||
#define SOCK_QUEUE 2
|
||||
#define CONN_TIMEOUT 60
|
||||
#define LINUX 1
|
||||
|
||||
#endif /* IFCHD_DEFINES_H_ */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ifchd.c - interface change daemon
|
||||
* Time-stamp: <2010-11-12 17:22:34 njk>
|
||||
* Time-stamp: <2010-11-12 18:40:54 njk>
|
||||
*
|
||||
* (C) 2004-2010 Nicholas J. Kain <njkain at gmail dot com>
|
||||
*
|
||||
@ -39,7 +39,7 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <getopt.h>
|
||||
|
||||
#include "defines.h"
|
||||
#include "ifchd-defines.h"
|
||||
#include "malloc.h"
|
||||
#include "log.h"
|
||||
#include "chroot.h"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* linux.c - ifchd Linux-specific functions
|
||||
* Time-stamp: <2010-11-12 14:29:32 njk>
|
||||
* Time-stamp: <2010-11-12 18:41:15 njk>
|
||||
*
|
||||
* (C) 2004-2010 Nicholas J. Kain <njkain at gmail dot com>
|
||||
*
|
||||
@ -37,7 +37,7 @@
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "defines.h"
|
||||
#include "ifchd-defines.h"
|
||||
#include "log.h"
|
||||
#include "strlist.h"
|
||||
#include "ifproto.h"
|
||||
|
17
ndhc/dhcpc.c
17
ndhc/dhcpc.c
@ -39,6 +39,7 @@
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
|
||||
#include "ndhc-defines.h"
|
||||
#include "dhcpd.h"
|
||||
#include "dhcpc.h"
|
||||
#include "options.h"
|
||||
@ -50,6 +51,7 @@
|
||||
#include "chroot.h"
|
||||
#include "cap.h"
|
||||
#include "strl.h"
|
||||
#include "pidfile.h"
|
||||
#include "malloc.h"
|
||||
|
||||
#define VERSION "1.0"
|
||||
@ -456,7 +458,8 @@ static int do_work(void)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char chroot_dir[255];
|
||||
char pidfile[MAX_PATH_LENGTH] = "";
|
||||
char chroot_dir[MAX_PATH_LENGTH] = PID_FILE_DEFAULT;
|
||||
int c, len;
|
||||
struct passwd *pwd;
|
||||
uid_t uid = 0;
|
||||
@ -465,6 +468,7 @@ int main(int argc, char **argv)
|
||||
{"clientid", required_argument, 0, 'c'},
|
||||
{"foreground", no_argument, 0, 'f'},
|
||||
{"background", no_argument, 0, 'b'},
|
||||
{"pidfile", required_argument, 0, 'p'},
|
||||
{"hostname", required_argument, 0, 'H'},
|
||||
{"hostname", required_argument, 0, 'h'},
|
||||
{"interface", required_argument, 0, 'i'},
|
||||
@ -481,7 +485,7 @@ int main(int argc, char **argv)
|
||||
/* get options */
|
||||
while (1) {
|
||||
int option_index = 0;
|
||||
c = getopt_long(argc, argv, "c:fbH:h:i:np:qr:u:C:v", arg_options,
|
||||
c = getopt_long(argc, argv, "c:fbp:H:h:i:np:qr:u:C:v", arg_options,
|
||||
&option_index);
|
||||
if (c == -1) break;
|
||||
|
||||
@ -502,6 +506,9 @@ int main(int argc, char **argv)
|
||||
case 'b':
|
||||
client_config.background_if_no_lease = 1;
|
||||
break;
|
||||
case 'p':
|
||||
strlcpy(pidfile, optarg, MAX_PATH_LENGTH);
|
||||
break;
|
||||
case 'h':
|
||||
case 'H':
|
||||
len = strlen(optarg) > 255 ? 255 : strlen(optarg);
|
||||
@ -549,6 +556,12 @@ int main(int argc, char **argv)
|
||||
|
||||
log_line("ndhc client " VERSION " started.");
|
||||
|
||||
if (file_exists(pidfile, "w") == -1) {
|
||||
log_line("FATAL - cannot open pidfile for write!");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
write_pid(pidfile);
|
||||
|
||||
if (read_interface(client_config.interface, &client_config.ifindex,
|
||||
NULL, client_config.arp) < 0)
|
||||
exit(EXIT_FAILURE);
|
||||
|
11
ndhc/ndhc-defines.h
Normal file
11
ndhc/ndhc-defines.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef NDHC_DEFINES_H_
|
||||
#define NDHC_DEFINES_H_
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
#define PID_FILE_DEFAULT "/var/run/ndhc.pid"
|
||||
#define NDHC_VERSION "1.0"
|
||||
#define MAX_BUF 1024
|
||||
|
||||
#endif /* NDHC_DEFINES_H_ */
|
||||
|
@ -149,11 +149,21 @@ int raw_packet(struct dhcpMessage *payload, uint32_t source_ip,
|
||||
packet.ip.ttl = IPDEFTTL;
|
||||
packet.ip.check = checksum(&(packet.ip), sizeof(packet.ip));
|
||||
|
||||
result = sendto(fd, &packet, sizeof(struct udp_dhcp_packet), 0,
|
||||
(struct sockaddr *)&dest, sizeof dest);
|
||||
if (result <= 0) {
|
||||
log_error("write on socket failed: %s",
|
||||
strerror(errno));
|
||||
int remain = sizeof(struct udp_dhcp_packet);
|
||||
int sent = 0;
|
||||
while (1) {
|
||||
result = sendto(fd, &packet + sent, remain, 0,
|
||||
(struct sockaddr *)&dest, sizeof dest);
|
||||
if (result == -1) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
log_error("raw_packet: sendto failed: %s", strerror(errno));
|
||||
break;
|
||||
}
|
||||
remain =- result;
|
||||
sent += result;
|
||||
if (remain == 0)
|
||||
break;
|
||||
}
|
||||
out_fd:
|
||||
close(fd);
|
||||
@ -190,7 +200,21 @@ int kernel_packet(struct dhcpMessage *payload, uint32_t source_ip,
|
||||
if (connect(fd, (struct sockaddr *)&client, sizeof(struct sockaddr)) == -1)
|
||||
goto out_fd;
|
||||
|
||||
result = write(fd, payload, sizeof(struct dhcpMessage));
|
||||
int remain = sizeof(struct dhcpMessage);
|
||||
int sent = 0;
|
||||
while (1) {
|
||||
result = write(fd, payload + sent, remain);
|
||||
if (result == -1) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
log_error("kernel_packet: write failed: %s", strerror(errno));
|
||||
break;
|
||||
}
|
||||
remain =- result;
|
||||
sent += result;
|
||||
if (remain == 0)
|
||||
break;
|
||||
}
|
||||
out_fd:
|
||||
close(fd);
|
||||
out:
|
||||
|
@ -144,21 +144,23 @@ static int open_ifch(void) {
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
static void sockwrite(int fd, const void *buf, size_t count)
|
||||
static void sockwrite(int fd, const char *buf, size_t count)
|
||||
{
|
||||
int ret;
|
||||
|
||||
sockwrite_again:
|
||||
ret = write(fd, buf, count);
|
||||
if (ret == -1) {
|
||||
if (errno == EAGAIN)
|
||||
goto sockwrite_again;
|
||||
log_error("error while writing to unix socket!");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (ret < 0) ret = 0;
|
||||
if ((unsigned int)ret < strlen(buf)) {
|
||||
log_error("incomplete write!");
|
||||
int remain = count;
|
||||
int sent = 0;
|
||||
while (1) {
|
||||
ret = write(fd, buf + sent, remain);
|
||||
if (ret == -1) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
log_error("sockwrite: write failed: %s", strerror(errno));
|
||||
break;
|
||||
}
|
||||
remain =- ret;
|
||||
sent += ret;
|
||||
if (remain == 0)
|
||||
break;
|
||||
}
|
||||
log_line("writing: %s", (char *)buf);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user