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 PID_FILE_DEFAULT "/var/run/ifchd.pid"
|
||||||
#define IFCHD_VERSION "0.8"
|
#define IFCHD_VERSION "0.8"
|
||||||
|
|
||||||
#define COMM_SOCKET_PATH "ifchange"
|
#define COMM_SOCKET_PATH "ifchange"
|
||||||
#define MAX_BUF 1024
|
#define MAX_BUF 1024
|
||||||
#define MAXLINE 1024
|
|
||||||
|
|
||||||
#define SOCK_QUEUE 2
|
#define SOCK_QUEUE 2
|
||||||
#define CONN_TIMEOUT 60
|
#define CONN_TIMEOUT 60
|
||||||
#define LINUX 1
|
|
||||||
|
#endif /* IFCHD_DEFINES_H_ */
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
/* ifchd.c - interface change daemon
|
/* 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>
|
* (C) 2004-2010 Nicholas J. Kain <njkain at gmail dot com>
|
||||||
*
|
*
|
||||||
@ -39,7 +39,7 @@
|
|||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
|
||||||
#include "defines.h"
|
#include "ifchd-defines.h"
|
||||||
#include "malloc.h"
|
#include "malloc.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "chroot.h"
|
#include "chroot.h"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* linux.c - ifchd Linux-specific functions
|
/* 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>
|
* (C) 2004-2010 Nicholas J. Kain <njkain at gmail dot com>
|
||||||
*
|
*
|
||||||
@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "defines.h"
|
#include "ifchd-defines.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "strlist.h"
|
#include "strlist.h"
|
||||||
#include "ifproto.h"
|
#include "ifproto.h"
|
||||||
|
17
ndhc/dhcpc.c
17
ndhc/dhcpc.c
@ -39,6 +39,7 @@
|
|||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
|
|
||||||
|
#include "ndhc-defines.h"
|
||||||
#include "dhcpd.h"
|
#include "dhcpd.h"
|
||||||
#include "dhcpc.h"
|
#include "dhcpc.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
@ -50,6 +51,7 @@
|
|||||||
#include "chroot.h"
|
#include "chroot.h"
|
||||||
#include "cap.h"
|
#include "cap.h"
|
||||||
#include "strl.h"
|
#include "strl.h"
|
||||||
|
#include "pidfile.h"
|
||||||
#include "malloc.h"
|
#include "malloc.h"
|
||||||
|
|
||||||
#define VERSION "1.0"
|
#define VERSION "1.0"
|
||||||
@ -456,7 +458,8 @@ static int do_work(void)
|
|||||||
|
|
||||||
int main(int argc, char **argv)
|
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;
|
int c, len;
|
||||||
struct passwd *pwd;
|
struct passwd *pwd;
|
||||||
uid_t uid = 0;
|
uid_t uid = 0;
|
||||||
@ -465,6 +468,7 @@ int main(int argc, char **argv)
|
|||||||
{"clientid", required_argument, 0, 'c'},
|
{"clientid", required_argument, 0, 'c'},
|
||||||
{"foreground", no_argument, 0, 'f'},
|
{"foreground", no_argument, 0, 'f'},
|
||||||
{"background", no_argument, 0, 'b'},
|
{"background", no_argument, 0, 'b'},
|
||||||
|
{"pidfile", required_argument, 0, 'p'},
|
||||||
{"hostname", required_argument, 0, 'H'},
|
{"hostname", required_argument, 0, 'H'},
|
||||||
{"hostname", required_argument, 0, 'h'},
|
{"hostname", required_argument, 0, 'h'},
|
||||||
{"interface", required_argument, 0, 'i'},
|
{"interface", required_argument, 0, 'i'},
|
||||||
@ -481,7 +485,7 @@ int main(int argc, char **argv)
|
|||||||
/* get options */
|
/* get options */
|
||||||
while (1) {
|
while (1) {
|
||||||
int option_index = 0;
|
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);
|
&option_index);
|
||||||
if (c == -1) break;
|
if (c == -1) break;
|
||||||
|
|
||||||
@ -502,6 +506,9 @@ int main(int argc, char **argv)
|
|||||||
case 'b':
|
case 'b':
|
||||||
client_config.background_if_no_lease = 1;
|
client_config.background_if_no_lease = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'p':
|
||||||
|
strlcpy(pidfile, optarg, MAX_PATH_LENGTH);
|
||||||
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
case 'H':
|
case 'H':
|
||||||
len = strlen(optarg) > 255 ? 255 : strlen(optarg);
|
len = strlen(optarg) > 255 ? 255 : strlen(optarg);
|
||||||
@ -549,6 +556,12 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
log_line("ndhc client " VERSION " started.");
|
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,
|
if (read_interface(client_config.interface, &client_config.ifindex,
|
||||||
NULL, client_config.arp) < 0)
|
NULL, client_config.arp) < 0)
|
||||||
exit(EXIT_FAILURE);
|
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.ttl = IPDEFTTL;
|
||||||
packet.ip.check = checksum(&(packet.ip), sizeof(packet.ip));
|
packet.ip.check = checksum(&(packet.ip), sizeof(packet.ip));
|
||||||
|
|
||||||
result = sendto(fd, &packet, sizeof(struct udp_dhcp_packet), 0,
|
int remain = sizeof(struct udp_dhcp_packet);
|
||||||
|
int sent = 0;
|
||||||
|
while (1) {
|
||||||
|
result = sendto(fd, &packet + sent, remain, 0,
|
||||||
(struct sockaddr *)&dest, sizeof dest);
|
(struct sockaddr *)&dest, sizeof dest);
|
||||||
if (result <= 0) {
|
if (result == -1) {
|
||||||
log_error("write on socket failed: %s",
|
if (errno == EINTR)
|
||||||
strerror(errno));
|
continue;
|
||||||
|
log_error("raw_packet: sendto failed: %s", strerror(errno));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
remain =- result;
|
||||||
|
sent += result;
|
||||||
|
if (remain == 0)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
out_fd:
|
out_fd:
|
||||||
close(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)
|
if (connect(fd, (struct sockaddr *)&client, sizeof(struct sockaddr)) == -1)
|
||||||
goto out_fd;
|
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:
|
out_fd:
|
||||||
close(fd);
|
close(fd);
|
||||||
out:
|
out:
|
||||||
|
@ -144,21 +144,23 @@ static int open_ifch(void) {
|
|||||||
return sockfd;
|
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;
|
int ret;
|
||||||
|
int remain = count;
|
||||||
sockwrite_again:
|
int sent = 0;
|
||||||
ret = write(fd, buf, count);
|
while (1) {
|
||||||
|
ret = write(fd, buf + sent, remain);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
if (errno == EAGAIN)
|
if (errno == EINTR)
|
||||||
goto sockwrite_again;
|
continue;
|
||||||
log_error("error while writing to unix socket!");
|
log_error("sockwrite: write failed: %s", strerror(errno));
|
||||||
exit(EXIT_FAILURE);
|
break;
|
||||||
}
|
}
|
||||||
if (ret < 0) ret = 0;
|
remain =- ret;
|
||||||
if ((unsigned int)ret < strlen(buf)) {
|
sent += ret;
|
||||||
log_error("incomplete write!");
|
if (remain == 0)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
log_line("writing: %s", (char *)buf);
|
log_line("writing: %s", (char *)buf);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user