MFC
This commit is contained in:
commit
1a53b3fd04
@ -301,7 +301,7 @@ the include file
|
||||
.It Dv "P_PPWAIT" Ta No "0x00010 Parent is waiting for child to exec/exit"
|
||||
.It Dv "P_PROFIL" Ta No "0x00020 Has started profiling"
|
||||
.It Dv "P_STOPPROF" Ta No "0x00040 Has thread in requesting to stop prof"
|
||||
.It Dv "P_HASTHREADS" Ta No "0x00080 Has had threads (no cleanup shortcuts)"
|
||||
.It Dv "P_HADTHREADS" Ta No "0x00080 Has had threads (no cleanup shortcuts)"
|
||||
.It Dv "P_SUGID" Ta No "0x00100 Had set id privileges since last exec"
|
||||
.It Dv "P_SYSTEM" Ta No "0x00200 System proc: no sigs, stats or swapping"
|
||||
.It Dv "P_SINGLE_EXIT" Ta No "0x00400 Threads suspending should exit, not wait"
|
||||
@ -549,7 +549,7 @@ wait channel (as an address)
|
||||
total blocks written (alias
|
||||
.Cm oublock )
|
||||
.It Cm paddr
|
||||
swap address
|
||||
process pointer
|
||||
.It Cm pagein
|
||||
pageins (same as majflt)
|
||||
.It Cm pgid
|
||||
|
@ -12,7 +12,7 @@ SRCS+= metadata.c
|
||||
SRCS+= nv.c
|
||||
SRCS+= secondary.c
|
||||
SRCS+= parse.y pjdlog.c primary.c
|
||||
SRCS+= proto.c proto_common.c proto_socketpair.c proto_tcp4.c proto_uds.c
|
||||
SRCS+= proto.c proto_common.c proto_socketpair.c proto_tcp.c proto_uds.c
|
||||
SRCS+= rangelock.c
|
||||
SRCS+= subr.c
|
||||
SRCS+= token.l
|
||||
@ -20,7 +20,7 @@ SRCS+= y.tab.h
|
||||
MAN= hastd.8 hast.conf.5
|
||||
|
||||
NO_WFORMAT=
|
||||
CFLAGS+=-DPROTO_TCP4_DEFAULT_PORT=8457
|
||||
CFLAGS+=-DPROTO_TCP_DEFAULT_PORT=8457
|
||||
CFLAGS+=-I${.CURDIR}
|
||||
CFLAGS+=-DINET
|
||||
.if ${MK_INET6_SUPPORT} != "no"
|
||||
|
@ -28,7 +28,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd April 2, 2011
|
||||
.Dd May 20, 2011
|
||||
.Dt HAST.CONF 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -159,8 +159,14 @@ tcp4://0.0.0.0
|
||||
tcp4://0.0.0.0:8457
|
||||
.Ed
|
||||
.Pp
|
||||
The default value is
|
||||
.Pa tcp4://0.0.0.0:8457 .
|
||||
Multiple listen addresses can be specified.
|
||||
By default
|
||||
.Nm hastd
|
||||
listens on
|
||||
.Pa tcp4://0.0.0.0:8457
|
||||
and
|
||||
.Pa tcp6://[::]:8457
|
||||
if kernel supports IPv4 and IPv6 respectively.
|
||||
.It Ic replication Aq mode
|
||||
.Pp
|
||||
Replication mode should be one of the following:
|
||||
@ -364,26 +370,35 @@ daemon.
|
||||
.Sh EXAMPLES
|
||||
The example configuration file can look as follows:
|
||||
.Bd -literal -offset indent
|
||||
listen tcp://0.0.0.0
|
||||
|
||||
on hasta {
|
||||
listen tcp://2001:db8::1/64
|
||||
}
|
||||
on hastb {
|
||||
listen tcp://2001:db8::2/64
|
||||
}
|
||||
|
||||
resource shared {
|
||||
local /dev/da0
|
||||
|
||||
on hasta {
|
||||
remote tcp4://10.0.0.2
|
||||
remote tcp://10.0.0.2
|
||||
}
|
||||
on hastb {
|
||||
remote tcp4://10.0.0.1
|
||||
remote tcp://10.0.0.1
|
||||
}
|
||||
}
|
||||
resource tank {
|
||||
on hasta {
|
||||
local /dev/mirror/tanka
|
||||
source tcp4://10.0.0.1
|
||||
remote tcp4://10.0.0.2
|
||||
source tcp://10.0.0.1
|
||||
remote tcp://10.0.0.2
|
||||
}
|
||||
on hastb {
|
||||
local /dev/mirror/tankb
|
||||
source tcp4://10.0.0.2
|
||||
remote tcp4://10.0.0.1
|
||||
source tcp://10.0.0.2
|
||||
remote tcp://10.0.0.1
|
||||
}
|
||||
}
|
||||
.Ed
|
||||
|
@ -82,12 +82,13 @@
|
||||
#define HIO_FLUSH 4
|
||||
#define HIO_KEEPALIVE 5
|
||||
|
||||
#define HAST_USER "hast"
|
||||
#define HAST_TIMEOUT 20
|
||||
#define HAST_CONFIG "/etc/hast.conf"
|
||||
#define HAST_CONTROL "/var/run/hastctl"
|
||||
#define HASTD_LISTEN "tcp4://0.0.0.0:8457"
|
||||
#define HASTD_PIDFILE "/var/run/hastd.pid"
|
||||
#define HAST_USER "hast"
|
||||
#define HAST_TIMEOUT 20
|
||||
#define HAST_CONFIG "/etc/hast.conf"
|
||||
#define HAST_CONTROL "/var/run/hastctl"
|
||||
#define HASTD_LISTEN_TCP4 "tcp4://0.0.0.0:8457"
|
||||
#define HASTD_LISTEN_TCP6 "tcp6://[::]:8457"
|
||||
#define HASTD_PIDFILE "/var/run/hastd.pid"
|
||||
|
||||
/* Default extent size. */
|
||||
#define HAST_EXTENTSIZE 2097152
|
||||
@ -100,6 +101,14 @@
|
||||
/* Number of seconds to sleep between reconnect retries or keepalive packets. */
|
||||
#define HAST_KEEPALIVE 10
|
||||
|
||||
struct hastd_listen {
|
||||
/* Address to listen on. */
|
||||
char hl_addr[HAST_ADDRSIZE];
|
||||
/* Protocol-specific data. */
|
||||
struct proto_conn *hl_conn;
|
||||
TAILQ_ENTRY(hastd_listen) hl_next;
|
||||
};
|
||||
|
||||
struct hastd_config {
|
||||
/* Address to communicate with hastctl(8). */
|
||||
char hc_controladdr[HAST_ADDRSIZE];
|
||||
@ -107,10 +116,8 @@ struct hastd_config {
|
||||
struct proto_conn *hc_controlconn;
|
||||
/* Incoming control connection. */
|
||||
struct proto_conn *hc_controlin;
|
||||
/* Address to listen on. */
|
||||
char hc_listenaddr[HAST_ADDRSIZE];
|
||||
/* Protocol-specific data. */
|
||||
struct proto_conn *hc_listenconn;
|
||||
/* List of addresses to listen on. */
|
||||
TAILQ_HEAD(, hastd_listen) hc_listen;
|
||||
/* List of resources. */
|
||||
TAILQ_HEAD(, hast_resource) hc_resources;
|
||||
};
|
||||
|
@ -98,6 +98,7 @@ void
|
||||
descriptors_cleanup(struct hast_resource *res)
|
||||
{
|
||||
struct hast_resource *tres;
|
||||
struct hastd_listen *lst;
|
||||
|
||||
TAILQ_FOREACH(tres, &cfg->hc_resources, hr_next) {
|
||||
if (tres == res) {
|
||||
@ -120,7 +121,10 @@ descriptors_cleanup(struct hast_resource *res)
|
||||
if (cfg->hc_controlin != NULL)
|
||||
proto_close(cfg->hc_controlin);
|
||||
proto_close(cfg->hc_controlconn);
|
||||
proto_close(cfg->hc_listenconn);
|
||||
TAILQ_FOREACH(lst, &cfg->hc_listen, hl_next) {
|
||||
if (lst->hl_conn != NULL)
|
||||
proto_close(lst->hl_conn);
|
||||
}
|
||||
(void)pidfile_close(pfh);
|
||||
hook_fini();
|
||||
pjdlog_fini();
|
||||
@ -462,6 +466,8 @@ hastd_reload(void)
|
||||
{
|
||||
struct hastd_config *newcfg;
|
||||
struct hast_resource *nres, *cres, *tres;
|
||||
struct hastd_listen *nlst, *clst;
|
||||
unsigned int nlisten;
|
||||
uint8_t role;
|
||||
|
||||
pjdlog_info("Reloading configuration...");
|
||||
@ -483,19 +489,37 @@ hastd_reload(void)
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Check if listen address has changed.
|
||||
* Check if any listen address has changed.
|
||||
*/
|
||||
if (strcmp(cfg->hc_listenaddr, newcfg->hc_listenaddr) != 0) {
|
||||
if (proto_server(newcfg->hc_listenaddr,
|
||||
&newcfg->hc_listenconn) < 0) {
|
||||
pjdlog_errno(LOG_ERR, "Unable to listen on address %s",
|
||||
newcfg->hc_listenaddr);
|
||||
goto failed;
|
||||
nlisten = 0;
|
||||
TAILQ_FOREACH(nlst, &newcfg->hc_listen, hl_next) {
|
||||
TAILQ_FOREACH(clst, &cfg->hc_listen, hl_next) {
|
||||
if (strcmp(nlst->hl_addr, clst->hl_addr) == 0)
|
||||
break;
|
||||
}
|
||||
if (clst != NULL && clst->hl_conn != NULL) {
|
||||
pjdlog_info("Keep listening on address %s.",
|
||||
nlst->hl_addr);
|
||||
nlst->hl_conn = clst->hl_conn;
|
||||
nlisten++;
|
||||
} else if (proto_server(nlst->hl_addr, &nlst->hl_conn) == 0) {
|
||||
pjdlog_info("Listening on new address %s.",
|
||||
nlst->hl_addr);
|
||||
nlisten++;
|
||||
} else {
|
||||
pjdlog_errno(LOG_WARNING,
|
||||
"Unable to listen on address %s", nlst->hl_addr);
|
||||
}
|
||||
}
|
||||
if (nlisten == 0) {
|
||||
pjdlog_error("No addresses to listen on.");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* No failures from now on. */
|
||||
|
||||
/*
|
||||
* Only when both control and listen sockets are successfully
|
||||
* initialized switch them to new configuration.
|
||||
* Switch to new control socket.
|
||||
*/
|
||||
if (newcfg->hc_controlconn != NULL) {
|
||||
pjdlog_info("Control socket changed from %s to %s.",
|
||||
@ -506,15 +530,23 @@ hastd_reload(void)
|
||||
strlcpy(cfg->hc_controladdr, newcfg->hc_controladdr,
|
||||
sizeof(cfg->hc_controladdr));
|
||||
}
|
||||
if (newcfg->hc_listenconn != NULL) {
|
||||
pjdlog_info("Listen socket changed from %s to %s.",
|
||||
cfg->hc_listenaddr, newcfg->hc_listenaddr);
|
||||
proto_close(cfg->hc_listenconn);
|
||||
cfg->hc_listenconn = newcfg->hc_listenconn;
|
||||
newcfg->hc_listenconn = NULL;
|
||||
strlcpy(cfg->hc_listenaddr, newcfg->hc_listenaddr,
|
||||
sizeof(cfg->hc_listenaddr));
|
||||
/*
|
||||
* Switch to new listen addresses. Close all that were removed.
|
||||
*/
|
||||
while ((clst = TAILQ_FIRST(&cfg->hc_listen)) != NULL) {
|
||||
TAILQ_FOREACH(nlst, &newcfg->hc_listen, hl_next) {
|
||||
if (strcmp(nlst->hl_addr, clst->hl_addr) == 0)
|
||||
break;
|
||||
}
|
||||
if (nlst == NULL && clst->hl_conn != NULL) {
|
||||
proto_close(clst->hl_conn);
|
||||
pjdlog_info("No longer listening on address %s.",
|
||||
clst->hl_addr);
|
||||
}
|
||||
TAILQ_REMOVE(&cfg->hc_listen, clst, hl_next);
|
||||
free(clst);
|
||||
}
|
||||
TAILQ_CONCAT(&cfg->hc_listen, &newcfg->hc_listen, hl_next);
|
||||
|
||||
/*
|
||||
* Stop and remove resources that were removed from the configuration.
|
||||
@ -607,8 +639,20 @@ failed:
|
||||
if (newcfg != NULL) {
|
||||
if (newcfg->hc_controlconn != NULL)
|
||||
proto_close(newcfg->hc_controlconn);
|
||||
if (newcfg->hc_listenconn != NULL)
|
||||
proto_close(newcfg->hc_listenconn);
|
||||
while ((nlst = TAILQ_FIRST(&newcfg->hc_listen)) != NULL) {
|
||||
if (nlst->hl_conn != NULL) {
|
||||
TAILQ_FOREACH(clst, &cfg->hc_listen, hl_next) {
|
||||
if (strcmp(nlst->hl_addr,
|
||||
clst->hl_addr) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (clst == NULL || clst->hl_conn == NULL)
|
||||
proto_close(nlst->hl_conn);
|
||||
}
|
||||
TAILQ_REMOVE(&newcfg->hc_listen, nlst, hl_next);
|
||||
free(nlst);
|
||||
}
|
||||
yy_config_free(newcfg);
|
||||
}
|
||||
pjdlog_warning("Configuration not reloaded.");
|
||||
@ -634,7 +678,7 @@ terminate_workers(void)
|
||||
}
|
||||
|
||||
static void
|
||||
listen_accept(void)
|
||||
listen_accept(struct hastd_listen *lst)
|
||||
{
|
||||
struct hast_resource *res;
|
||||
struct proto_conn *conn;
|
||||
@ -646,10 +690,10 @@ listen_accept(void)
|
||||
pid_t pid;
|
||||
int status;
|
||||
|
||||
proto_local_address(cfg->hc_listenconn, laddr, sizeof(laddr));
|
||||
proto_local_address(lst->hl_conn, laddr, sizeof(laddr));
|
||||
pjdlog_debug(1, "Accepting connection to %s.", laddr);
|
||||
|
||||
if (proto_accept(cfg->hc_listenconn, &conn) < 0) {
|
||||
if (proto_accept(lst->hl_conn, &conn) < 0) {
|
||||
pjdlog_errno(LOG_ERR, "Unable to accept connection %s", laddr);
|
||||
return;
|
||||
}
|
||||
@ -943,6 +987,7 @@ static void
|
||||
main_loop(void)
|
||||
{
|
||||
struct hast_resource *res;
|
||||
struct hastd_listen *lst;
|
||||
struct timeval seltimeout;
|
||||
int fd, maxfd, ret;
|
||||
time_t lastcheck, now;
|
||||
@ -952,9 +997,6 @@ main_loop(void)
|
||||
seltimeout.tv_sec = REPORT_INTERVAL;
|
||||
seltimeout.tv_usec = 0;
|
||||
|
||||
pjdlog_info("Started successfully, running protocol version %d.",
|
||||
HAST_PROTO_VERSION);
|
||||
|
||||
for (;;) {
|
||||
check_signals();
|
||||
|
||||
@ -963,10 +1005,14 @@ main_loop(void)
|
||||
maxfd = fd = proto_descriptor(cfg->hc_controlconn);
|
||||
PJDLOG_ASSERT(fd >= 0);
|
||||
FD_SET(fd, &rfds);
|
||||
fd = proto_descriptor(cfg->hc_listenconn);
|
||||
PJDLOG_ASSERT(fd >= 0);
|
||||
FD_SET(fd, &rfds);
|
||||
maxfd = fd > maxfd ? fd : maxfd;
|
||||
TAILQ_FOREACH(lst, &cfg->hc_listen, hl_next) {
|
||||
if (lst->hl_conn == NULL)
|
||||
continue;
|
||||
fd = proto_descriptor(lst->hl_conn);
|
||||
PJDLOG_ASSERT(fd >= 0);
|
||||
FD_SET(fd, &rfds);
|
||||
maxfd = fd > maxfd ? fd : maxfd;
|
||||
}
|
||||
TAILQ_FOREACH(res, &cfg->hc_resources, hr_next) {
|
||||
if (res->hr_event == NULL)
|
||||
continue;
|
||||
@ -1014,8 +1060,12 @@ main_loop(void)
|
||||
|
||||
if (FD_ISSET(proto_descriptor(cfg->hc_controlconn), &rfds))
|
||||
control_handle(cfg);
|
||||
if (FD_ISSET(proto_descriptor(cfg->hc_listenconn), &rfds))
|
||||
listen_accept();
|
||||
TAILQ_FOREACH(lst, &cfg->hc_listen, hl_next) {
|
||||
if (lst->hl_conn == NULL)
|
||||
continue;
|
||||
if (FD_ISSET(proto_descriptor(lst->hl_conn), &rfds))
|
||||
listen_accept(lst);
|
||||
}
|
||||
TAILQ_FOREACH(res, &cfg->hc_resources, hr_next) {
|
||||
if (res->hr_event == NULL)
|
||||
continue;
|
||||
@ -1053,6 +1103,7 @@ dummy_sighandler(int sig __unused)
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct hastd_listen *lst;
|
||||
const char *pidfile;
|
||||
pid_t otherpid;
|
||||
bool foreground;
|
||||
@ -1136,10 +1187,12 @@ main(int argc, char *argv[])
|
||||
cfg->hc_controladdr);
|
||||
}
|
||||
/* Listen for remote connections. */
|
||||
if (proto_server(cfg->hc_listenaddr, &cfg->hc_listenconn) < 0) {
|
||||
KEEP_ERRNO((void)pidfile_remove(pfh));
|
||||
pjdlog_exit(EX_OSERR, "Unable to listen on address %s",
|
||||
cfg->hc_listenaddr);
|
||||
TAILQ_FOREACH(lst, &cfg->hc_listen, hl_next) {
|
||||
if (proto_server(lst->hl_addr, &lst->hl_conn) < 0) {
|
||||
KEEP_ERRNO((void)pidfile_remove(pfh));
|
||||
pjdlog_exit(EX_OSERR, "Unable to listen on address %s",
|
||||
lst->hl_addr);
|
||||
}
|
||||
}
|
||||
|
||||
if (!foreground) {
|
||||
@ -1158,6 +1211,14 @@ main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
pjdlog_info("Started successfully, running protocol version %d.",
|
||||
HAST_PROTO_VERSION);
|
||||
|
||||
pjdlog_debug(1, "Listening on control address %s.",
|
||||
cfg->hc_controladdr);
|
||||
TAILQ_FOREACH(lst, &cfg->hc_listen, hl_next)
|
||||
pjdlog_info("Listening on address %s.", lst->hl_addr);
|
||||
|
||||
hook_init();
|
||||
|
||||
main_loop();
|
||||
|
@ -33,12 +33,14 @@
|
||||
|
||||
#include <sys/param.h> /* MAXHOSTNAMELEN */
|
||||
#include <sys/queue.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
@ -59,7 +61,9 @@ static struct hast_resource *curres;
|
||||
static bool mynode, hadmynode;
|
||||
|
||||
static char depth0_control[HAST_ADDRSIZE];
|
||||
static char depth0_listen[HAST_ADDRSIZE];
|
||||
static char depth0_listen_tcp4[HAST_ADDRSIZE];
|
||||
static char depth0_listen_tcp6[HAST_ADDRSIZE];
|
||||
static TAILQ_HEAD(, hastd_listen) depth0_listen;
|
||||
static int depth0_replication;
|
||||
static int depth0_checksum;
|
||||
static int depth0_compression;
|
||||
@ -114,6 +118,19 @@ isitme(const char *name)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static bool
|
||||
family_supported(int family)
|
||||
{
|
||||
int sock;
|
||||
|
||||
sock = socket(family, SOCK_STREAM, 0);
|
||||
if (sock == -1 && errno == EPROTONOSUPPORT)
|
||||
return (false);
|
||||
if (sock >= 0)
|
||||
(void)close(sock);
|
||||
return (true);
|
||||
}
|
||||
|
||||
static int
|
||||
node_names(char **namesp)
|
||||
{
|
||||
@ -175,7 +192,11 @@ yy_config_parse(const char *config, bool exitonerror)
|
||||
depth0_checksum = HAST_CHECKSUM_NONE;
|
||||
depth0_compression = HAST_COMPRESSION_HOLE;
|
||||
strlcpy(depth0_control, HAST_CONTROL, sizeof(depth0_control));
|
||||
strlcpy(depth0_listen, HASTD_LISTEN, sizeof(depth0_listen));
|
||||
TAILQ_INIT(&depth0_listen);
|
||||
strlcpy(depth0_listen_tcp4, HASTD_LISTEN_TCP4,
|
||||
sizeof(depth0_listen_tcp4));
|
||||
strlcpy(depth0_listen_tcp6, HASTD_LISTEN_TCP6,
|
||||
sizeof(depth0_listen_tcp6));
|
||||
depth0_exec[0] = '\0';
|
||||
|
||||
lconfig = calloc(1, sizeof(*lconfig));
|
||||
@ -186,6 +207,7 @@ yy_config_parse(const char *config, bool exitonerror)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
TAILQ_INIT(&lconfig->hc_listen);
|
||||
TAILQ_INIT(&lconfig->hc_resources);
|
||||
|
||||
yyin = fopen(config, "r");
|
||||
@ -214,9 +236,50 @@ yy_config_parse(const char *config, bool exitonerror)
|
||||
strlcpy(lconfig->hc_controladdr, depth0_control,
|
||||
sizeof(lconfig->hc_controladdr));
|
||||
}
|
||||
if (lconfig->hc_listenaddr[0] == '\0') {
|
||||
strlcpy(lconfig->hc_listenaddr, depth0_listen,
|
||||
sizeof(lconfig->hc_listenaddr));
|
||||
if (!TAILQ_EMPTY(&depth0_listen))
|
||||
TAILQ_CONCAT(&lconfig->hc_listen, &depth0_listen, hl_next);
|
||||
if (TAILQ_EMPTY(&lconfig->hc_listen)) {
|
||||
struct hastd_listen *lst;
|
||||
|
||||
if (family_supported(AF_INET)) {
|
||||
lst = calloc(1, sizeof(*lst));
|
||||
if (lst == NULL) {
|
||||
pjdlog_error("Unable to allocate memory for listen address.");
|
||||
yy_config_free(lconfig);
|
||||
if (exitonerror)
|
||||
exit(EX_TEMPFAIL);
|
||||
return (NULL);
|
||||
}
|
||||
(void)strlcpy(lst->hl_addr, depth0_listen_tcp4,
|
||||
sizeof(lst->hl_addr));
|
||||
TAILQ_INSERT_TAIL(&lconfig->hc_listen, lst, hl_next);
|
||||
} else {
|
||||
pjdlog_debug(1,
|
||||
"No IPv4 support in the kernel, not listening on IPv4 address.");
|
||||
}
|
||||
if (family_supported(AF_INET6)) {
|
||||
lst = calloc(1, sizeof(*lst));
|
||||
if (lst == NULL) {
|
||||
pjdlog_error("Unable to allocate memory for listen address.");
|
||||
yy_config_free(lconfig);
|
||||
if (exitonerror)
|
||||
exit(EX_TEMPFAIL);
|
||||
return (NULL);
|
||||
}
|
||||
(void)strlcpy(lst->hl_addr, depth0_listen_tcp6,
|
||||
sizeof(lst->hl_addr));
|
||||
TAILQ_INSERT_TAIL(&lconfig->hc_listen, lst, hl_next);
|
||||
} else {
|
||||
pjdlog_debug(1,
|
||||
"No IPv6 support in the kernel, not listening on IPv6 address.");
|
||||
}
|
||||
if (TAILQ_EMPTY(&lconfig->hc_listen)) {
|
||||
pjdlog_error("No address to listen on.");
|
||||
yy_config_free(lconfig);
|
||||
if (exitonerror)
|
||||
exit(EX_TEMPFAIL);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
TAILQ_FOREACH(curres, &lconfig->hc_resources, hr_next) {
|
||||
assert(curres->hr_provname[0] != '\0');
|
||||
@ -274,8 +337,17 @@ yy_config_parse(const char *config, bool exitonerror)
|
||||
void
|
||||
yy_config_free(struct hastd_config *config)
|
||||
{
|
||||
struct hastd_listen *lst;
|
||||
struct hast_resource *res;
|
||||
|
||||
while ((lst = TAILQ_FIRST(&depth0_listen)) != NULL) {
|
||||
TAILQ_REMOVE(&depth0_listen, lst, hl_next);
|
||||
free(lst);
|
||||
}
|
||||
while ((lst = TAILQ_FIRST(&config->hc_listen)) != NULL) {
|
||||
TAILQ_REMOVE(&config->hc_listen, lst, hl_next);
|
||||
free(lst);
|
||||
}
|
||||
while ((res = TAILQ_FIRST(&config->hc_resources)) != NULL) {
|
||||
TAILQ_REMOVE(&config->hc_resources, res, hr_next);
|
||||
free(res);
|
||||
@ -362,26 +434,30 @@ control_statement: CONTROL STR
|
||||
|
||||
listen_statement: LISTEN STR
|
||||
{
|
||||
struct hastd_listen *lst;
|
||||
|
||||
lst = calloc(1, sizeof(*lst));
|
||||
if (lst == NULL) {
|
||||
pjdlog_error("Unable to allocate memory for listen address.");
|
||||
free($2);
|
||||
return (1);
|
||||
}
|
||||
if (strlcpy(lst->hl_addr, $2, sizeof(lst->hl_addr)) >=
|
||||
sizeof(lst->hl_addr)) {
|
||||
pjdlog_error("listen argument is too long.");
|
||||
free($2);
|
||||
free(lst);
|
||||
return (1);
|
||||
}
|
||||
switch (depth) {
|
||||
case 0:
|
||||
if (strlcpy(depth0_listen, $2,
|
||||
sizeof(depth0_listen)) >=
|
||||
sizeof(depth0_listen)) {
|
||||
pjdlog_error("listen argument is too long.");
|
||||
free($2);
|
||||
return (1);
|
||||
}
|
||||
TAILQ_INSERT_TAIL(&depth0_listen, lst, hl_next);
|
||||
break;
|
||||
case 1:
|
||||
if (!mynode)
|
||||
break;
|
||||
if (strlcpy(lconfig->hc_listenaddr, $2,
|
||||
sizeof(lconfig->hc_listenaddr)) >=
|
||||
sizeof(lconfig->hc_listenaddr)) {
|
||||
pjdlog_error("listen argument is too long.");
|
||||
free($2);
|
||||
return (1);
|
||||
}
|
||||
if (mynode)
|
||||
TAILQ_INSERT_TAIL(&depth0_listen, lst, hl_next);
|
||||
else
|
||||
free(lst);
|
||||
break;
|
||||
default:
|
||||
assert(!"listen at wrong depth level");
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2009-2010 The FreeBSD Foundation
|
||||
* Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Pawel Jakub Dawidek under sponsorship from
|
||||
@ -51,37 +52,19 @@ __FBSDID("$FreeBSD$");
|
||||
#include "proto_impl.h"
|
||||
#include "subr.h"
|
||||
|
||||
#define TCP4_CTX_MAGIC 0x7c441c
|
||||
struct tcp4_ctx {
|
||||
#define TCP_CTX_MAGIC 0x7c41c
|
||||
struct tcp_ctx {
|
||||
int tc_magic;
|
||||
struct sockaddr_in tc_sin;
|
||||
struct sockaddr_storage tc_sa;
|
||||
int tc_fd;
|
||||
int tc_side;
|
||||
#define TCP4_SIDE_CLIENT 0
|
||||
#define TCP4_SIDE_SERVER_LISTEN 1
|
||||
#define TCP4_SIDE_SERVER_WORK 2
|
||||
#define TCP_SIDE_CLIENT 0
|
||||
#define TCP_SIDE_SERVER_LISTEN 1
|
||||
#define TCP_SIDE_SERVER_WORK 2
|
||||
};
|
||||
|
||||
static int tcp4_connect_wait(void *ctx, int timeout);
|
||||
static void tcp4_close(void *ctx);
|
||||
|
||||
static in_addr_t
|
||||
str2ip(const char *str)
|
||||
{
|
||||
struct hostent *hp;
|
||||
in_addr_t ip;
|
||||
|
||||
ip = inet_addr(str);
|
||||
if (ip != INADDR_NONE) {
|
||||
/* It is a valid IP address. */
|
||||
return (ip);
|
||||
}
|
||||
/* Check if it is a valid host name. */
|
||||
hp = gethostbyname(str);
|
||||
if (hp == NULL)
|
||||
return (INADDR_NONE);
|
||||
return (((struct in_addr *)(void *)hp->h_addr)->s_addr);
|
||||
}
|
||||
static int tcp_connect_wait(void *ctx, int timeout);
|
||||
static void tcp_close(void *ctx);
|
||||
|
||||
/*
|
||||
* Function converts the given string to unsigned number.
|
||||
@ -114,70 +97,106 @@ invalid:
|
||||
}
|
||||
|
||||
static int
|
||||
tcp4_addr(const char *addr, int defport, struct sockaddr_in *sinp)
|
||||
tcp_addr(const char *addr, int defport, struct sockaddr_storage *sap)
|
||||
{
|
||||
char iporhost[MAXHOSTNAMELEN];
|
||||
char iporhost[MAXHOSTNAMELEN], portstr[6];
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *res;
|
||||
const char *pp;
|
||||
intmax_t port;
|
||||
size_t size;
|
||||
in_addr_t ip;
|
||||
int error;
|
||||
|
||||
if (addr == NULL)
|
||||
return (-1);
|
||||
|
||||
if (strncasecmp(addr, "tcp4://", 7) == 0)
|
||||
bzero(&hints, sizeof(hints));
|
||||
hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV;
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
|
||||
if (strncasecmp(addr, "tcp4://", 7) == 0) {
|
||||
addr += 7;
|
||||
else if (strncasecmp(addr, "tcp://", 6) == 0)
|
||||
hints.ai_family = PF_INET;
|
||||
} else if (strncasecmp(addr, "tcp6://", 7) == 0) {
|
||||
addr += 7;
|
||||
hints.ai_family = PF_INET6;
|
||||
} else if (strncasecmp(addr, "tcp://", 6) == 0) {
|
||||
addr += 6;
|
||||
else {
|
||||
} else {
|
||||
/*
|
||||
* Because TCP4 is the default assume IP or host is given without
|
||||
* Because TCP is the default assume IP or host is given without
|
||||
* prefix.
|
||||
*/
|
||||
}
|
||||
|
||||
sinp->sin_family = AF_INET;
|
||||
sinp->sin_len = sizeof(*sinp);
|
||||
/* Extract optional port. */
|
||||
pp = strrchr(addr, ':');
|
||||
/*
|
||||
* Extract optional port.
|
||||
* There are three cases to consider.
|
||||
* 1. hostname with port, eg. freefall.freebsd.org:8457
|
||||
* 2. IPv4 address with port, eg. 192.168.0.101:8457
|
||||
* 3. IPv6 address with port, eg. [fe80::1]:8457
|
||||
* We discover IPv6 address by checking for two colons and if port is
|
||||
* given, the address has to start with [.
|
||||
*/
|
||||
pp = NULL;
|
||||
if (strchr(addr, ':') != strrchr(addr, ':')) {
|
||||
if (addr[0] == '[')
|
||||
pp = strrchr(addr, ':');
|
||||
} else {
|
||||
pp = strrchr(addr, ':');
|
||||
}
|
||||
if (pp == NULL) {
|
||||
/* Port not given, use the default. */
|
||||
sinp->sin_port = htons(defport);
|
||||
port = defport;
|
||||
} else {
|
||||
intmax_t port;
|
||||
|
||||
if (numfromstr(pp + 1, 1, 65535, &port) < 0)
|
||||
return (errno);
|
||||
sinp->sin_port = htons(port);
|
||||
}
|
||||
(void)snprintf(portstr, sizeof(portstr), "%jd", (intmax_t)port);
|
||||
/* Extract host name or IP address. */
|
||||
if (pp == NULL) {
|
||||
size = sizeof(iporhost);
|
||||
if (strlcpy(iporhost, addr, size) >= size)
|
||||
return (ENAMETOOLONG);
|
||||
} else if (addr[0] == '[' && pp[-1] == ']') {
|
||||
size = (size_t)(pp - addr - 2 + 1);
|
||||
if (size > sizeof(iporhost))
|
||||
return (ENAMETOOLONG);
|
||||
(void)strlcpy(iporhost, addr + 1, size);
|
||||
} else {
|
||||
size = (size_t)(pp - addr + 1);
|
||||
if (size > sizeof(iporhost))
|
||||
return (ENAMETOOLONG);
|
||||
(void)strlcpy(iporhost, addr, size);
|
||||
}
|
||||
/* Convert string (IP address or host name) to in_addr_t. */
|
||||
ip = str2ip(iporhost);
|
||||
if (ip == INADDR_NONE)
|
||||
|
||||
error = getaddrinfo(iporhost, portstr, &hints, &res);
|
||||
if (error != 0) {
|
||||
pjdlog_debug(1, "getaddrinfo(%s, %s) failed: %s.", iporhost,
|
||||
portstr, gai_strerror(error));
|
||||
return (EINVAL);
|
||||
sinp->sin_addr.s_addr = ip;
|
||||
}
|
||||
if (res == NULL)
|
||||
return (ENOENT);
|
||||
|
||||
memcpy(sap, res->ai_addr, res->ai_addrlen);
|
||||
|
||||
freeaddrinfo(res);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
tcp4_setup_new(const char *addr, int side, void **ctxp)
|
||||
tcp_setup_new(const char *addr, int side, void **ctxp)
|
||||
{
|
||||
struct tcp4_ctx *tctx;
|
||||
struct tcp_ctx *tctx;
|
||||
int ret, nodelay;
|
||||
|
||||
PJDLOG_ASSERT(addr != NULL);
|
||||
PJDLOG_ASSERT(side == TCP4_SIDE_CLIENT ||
|
||||
side == TCP4_SIDE_SERVER_LISTEN);
|
||||
PJDLOG_ASSERT(side == TCP_SIDE_CLIENT ||
|
||||
side == TCP_SIDE_SERVER_LISTEN);
|
||||
PJDLOG_ASSERT(ctxp != NULL);
|
||||
|
||||
tctx = malloc(sizeof(*tctx));
|
||||
@ -185,22 +204,21 @@ tcp4_setup_new(const char *addr, int side, void **ctxp)
|
||||
return (errno);
|
||||
|
||||
/* Parse given address. */
|
||||
if ((ret = tcp4_addr(addr, PROTO_TCP4_DEFAULT_PORT,
|
||||
&tctx->tc_sin)) != 0) {
|
||||
if ((ret = tcp_addr(addr, PROTO_TCP_DEFAULT_PORT, &tctx->tc_sa)) != 0) {
|
||||
free(tctx);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
PJDLOG_ASSERT(tctx->tc_sin.sin_family != AF_UNSPEC);
|
||||
PJDLOG_ASSERT(tctx->tc_sa.ss_family != AF_UNSPEC);
|
||||
|
||||
tctx->tc_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
tctx->tc_fd = socket(tctx->tc_sa.ss_family, SOCK_STREAM, 0);
|
||||
if (tctx->tc_fd == -1) {
|
||||
ret = errno;
|
||||
free(tctx);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
PJDLOG_ASSERT(tctx->tc_sin.sin_family != AF_UNSPEC);
|
||||
PJDLOG_ASSERT(tctx->tc_sa.ss_family != AF_UNSPEC);
|
||||
|
||||
/* Socket settings. */
|
||||
nodelay = 1;
|
||||
@ -210,20 +228,20 @@ tcp4_setup_new(const char *addr, int side, void **ctxp)
|
||||
}
|
||||
|
||||
tctx->tc_side = side;
|
||||
tctx->tc_magic = TCP4_CTX_MAGIC;
|
||||
tctx->tc_magic = TCP_CTX_MAGIC;
|
||||
*ctxp = tctx;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
tcp4_setup_wrap(int fd, int side, void **ctxp)
|
||||
tcp_setup_wrap(int fd, int side, void **ctxp)
|
||||
{
|
||||
struct tcp4_ctx *tctx;
|
||||
struct tcp_ctx *tctx;
|
||||
|
||||
PJDLOG_ASSERT(fd >= 0);
|
||||
PJDLOG_ASSERT(side == TCP4_SIDE_CLIENT ||
|
||||
side == TCP4_SIDE_SERVER_WORK);
|
||||
PJDLOG_ASSERT(side == TCP_SIDE_CLIENT ||
|
||||
side == TCP_SIDE_SERVER_WORK);
|
||||
PJDLOG_ASSERT(ctxp != NULL);
|
||||
|
||||
tctx = malloc(sizeof(*tctx));
|
||||
@ -231,51 +249,51 @@ tcp4_setup_wrap(int fd, int side, void **ctxp)
|
||||
return (errno);
|
||||
|
||||
tctx->tc_fd = fd;
|
||||
tctx->tc_sin.sin_family = AF_UNSPEC;
|
||||
tctx->tc_sa.ss_family = AF_UNSPEC;
|
||||
tctx->tc_side = side;
|
||||
tctx->tc_magic = TCP4_CTX_MAGIC;
|
||||
tctx->tc_magic = TCP_CTX_MAGIC;
|
||||
*ctxp = tctx;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
tcp4_client(const char *srcaddr, const char *dstaddr, void **ctxp)
|
||||
tcp_client(const char *srcaddr, const char *dstaddr, void **ctxp)
|
||||
{
|
||||
struct tcp4_ctx *tctx;
|
||||
struct sockaddr_in sin;
|
||||
struct tcp_ctx *tctx;
|
||||
struct sockaddr_storage sa;
|
||||
int ret;
|
||||
|
||||
ret = tcp4_setup_new(dstaddr, TCP4_SIDE_CLIENT, ctxp);
|
||||
ret = tcp_setup_new(dstaddr, TCP_SIDE_CLIENT, ctxp);
|
||||
if (ret != 0)
|
||||
return (ret);
|
||||
tctx = *ctxp;
|
||||
if (srcaddr == NULL)
|
||||
return (0);
|
||||
ret = tcp4_addr(srcaddr, 0, &sin);
|
||||
ret = tcp_addr(srcaddr, 0, &sa);
|
||||
if (ret != 0) {
|
||||
tcp4_close(tctx);
|
||||
tcp_close(tctx);
|
||||
return (ret);
|
||||
}
|
||||
if (bind(tctx->tc_fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
|
||||
if (bind(tctx->tc_fd, (struct sockaddr *)&sa, sa.ss_len) < 0) {
|
||||
ret = errno;
|
||||
tcp4_close(tctx);
|
||||
tcp_close(tctx);
|
||||
return (ret);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
tcp4_connect(void *ctx, int timeout)
|
||||
tcp_connect(void *ctx, int timeout)
|
||||
{
|
||||
struct tcp4_ctx *tctx = ctx;
|
||||
struct tcp_ctx *tctx = ctx;
|
||||
int error, flags;
|
||||
|
||||
PJDLOG_ASSERT(tctx != NULL);
|
||||
PJDLOG_ASSERT(tctx->tc_magic == TCP4_CTX_MAGIC);
|
||||
PJDLOG_ASSERT(tctx->tc_side == TCP4_SIDE_CLIENT);
|
||||
PJDLOG_ASSERT(tctx->tc_magic == TCP_CTX_MAGIC);
|
||||
PJDLOG_ASSERT(tctx->tc_side == TCP_SIDE_CLIENT);
|
||||
PJDLOG_ASSERT(tctx->tc_fd >= 0);
|
||||
PJDLOG_ASSERT(tctx->tc_sin.sin_family != AF_UNSPEC);
|
||||
PJDLOG_ASSERT(tctx->tc_sa.ss_family != AF_UNSPEC);
|
||||
PJDLOG_ASSERT(timeout >= -1);
|
||||
|
||||
flags = fcntl(tctx->tc_fd, F_GETFL);
|
||||
@ -295,8 +313,8 @@ tcp4_connect(void *ctx, int timeout)
|
||||
return (errno);
|
||||
}
|
||||
|
||||
if (connect(tctx->tc_fd, (struct sockaddr *)&tctx->tc_sin,
|
||||
sizeof(tctx->tc_sin)) == 0) {
|
||||
if (connect(tctx->tc_fd, (struct sockaddr *)&tctx->tc_sa,
|
||||
tctx->tc_sa.ss_len) == 0) {
|
||||
if (timeout == -1)
|
||||
return (0);
|
||||
error = 0;
|
||||
@ -309,7 +327,7 @@ tcp4_connect(void *ctx, int timeout)
|
||||
}
|
||||
if (timeout == -1)
|
||||
return (0);
|
||||
return (tcp4_connect_wait(ctx, timeout));
|
||||
return (tcp_connect_wait(ctx, timeout));
|
||||
done:
|
||||
flags &= ~O_NONBLOCK;
|
||||
if (fcntl(tctx->tc_fd, F_SETFL, flags) == -1) {
|
||||
@ -322,17 +340,17 @@ done:
|
||||
}
|
||||
|
||||
static int
|
||||
tcp4_connect_wait(void *ctx, int timeout)
|
||||
tcp_connect_wait(void *ctx, int timeout)
|
||||
{
|
||||
struct tcp4_ctx *tctx = ctx;
|
||||
struct tcp_ctx *tctx = ctx;
|
||||
struct timeval tv;
|
||||
fd_set fdset;
|
||||
socklen_t esize;
|
||||
int error, flags, ret;
|
||||
|
||||
PJDLOG_ASSERT(tctx != NULL);
|
||||
PJDLOG_ASSERT(tctx->tc_magic == TCP4_CTX_MAGIC);
|
||||
PJDLOG_ASSERT(tctx->tc_side == TCP4_SIDE_CLIENT);
|
||||
PJDLOG_ASSERT(tctx->tc_magic == TCP_CTX_MAGIC);
|
||||
PJDLOG_ASSERT(tctx->tc_side == TCP_SIDE_CLIENT);
|
||||
PJDLOG_ASSERT(tctx->tc_fd >= 0);
|
||||
PJDLOG_ASSERT(timeout >= 0);
|
||||
|
||||
@ -387,12 +405,12 @@ done:
|
||||
}
|
||||
|
||||
static int
|
||||
tcp4_server(const char *addr, void **ctxp)
|
||||
tcp_server(const char *addr, void **ctxp)
|
||||
{
|
||||
struct tcp4_ctx *tctx;
|
||||
struct tcp_ctx *tctx;
|
||||
int ret, val;
|
||||
|
||||
ret = tcp4_setup_new(addr, TCP4_SIDE_SERVER_LISTEN, ctxp);
|
||||
ret = tcp_setup_new(addr, TCP_SIDE_SERVER_LISTEN, ctxp);
|
||||
if (ret != 0)
|
||||
return (ret);
|
||||
|
||||
@ -403,17 +421,17 @@ tcp4_server(const char *addr, void **ctxp)
|
||||
(void)setsockopt(tctx->tc_fd, SOL_SOCKET, SO_REUSEADDR, &val,
|
||||
sizeof(val));
|
||||
|
||||
PJDLOG_ASSERT(tctx->tc_sin.sin_family != AF_UNSPEC);
|
||||
PJDLOG_ASSERT(tctx->tc_sa.ss_family != AF_UNSPEC);
|
||||
|
||||
if (bind(tctx->tc_fd, (struct sockaddr *)&tctx->tc_sin,
|
||||
sizeof(tctx->tc_sin)) < 0) {
|
||||
if (bind(tctx->tc_fd, (struct sockaddr *)&tctx->tc_sa,
|
||||
tctx->tc_sa.ss_len) < 0) {
|
||||
ret = errno;
|
||||
tcp4_close(tctx);
|
||||
tcp_close(tctx);
|
||||
return (ret);
|
||||
}
|
||||
if (listen(tctx->tc_fd, 8) < 0) {
|
||||
ret = errno;
|
||||
tcp4_close(tctx);
|
||||
tcp_close(tctx);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -421,25 +439,25 @@ tcp4_server(const char *addr, void **ctxp)
|
||||
}
|
||||
|
||||
static int
|
||||
tcp4_accept(void *ctx, void **newctxp)
|
||||
tcp_accept(void *ctx, void **newctxp)
|
||||
{
|
||||
struct tcp4_ctx *tctx = ctx;
|
||||
struct tcp4_ctx *newtctx;
|
||||
struct tcp_ctx *tctx = ctx;
|
||||
struct tcp_ctx *newtctx;
|
||||
socklen_t fromlen;
|
||||
int ret;
|
||||
|
||||
PJDLOG_ASSERT(tctx != NULL);
|
||||
PJDLOG_ASSERT(tctx->tc_magic == TCP4_CTX_MAGIC);
|
||||
PJDLOG_ASSERT(tctx->tc_side == TCP4_SIDE_SERVER_LISTEN);
|
||||
PJDLOG_ASSERT(tctx->tc_magic == TCP_CTX_MAGIC);
|
||||
PJDLOG_ASSERT(tctx->tc_side == TCP_SIDE_SERVER_LISTEN);
|
||||
PJDLOG_ASSERT(tctx->tc_fd >= 0);
|
||||
PJDLOG_ASSERT(tctx->tc_sin.sin_family != AF_UNSPEC);
|
||||
PJDLOG_ASSERT(tctx->tc_sa.ss_family != AF_UNSPEC);
|
||||
|
||||
newtctx = malloc(sizeof(*newtctx));
|
||||
if (newtctx == NULL)
|
||||
return (errno);
|
||||
|
||||
fromlen = sizeof(tctx->tc_sin);
|
||||
newtctx->tc_fd = accept(tctx->tc_fd, (struct sockaddr *)&tctx->tc_sin,
|
||||
fromlen = tctx->tc_sa.ss_len;
|
||||
newtctx->tc_fd = accept(tctx->tc_fd, (struct sockaddr *)&tctx->tc_sa,
|
||||
&fromlen);
|
||||
if (newtctx->tc_fd < 0) {
|
||||
ret = errno;
|
||||
@ -447,28 +465,28 @@ tcp4_accept(void *ctx, void **newctxp)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
newtctx->tc_side = TCP4_SIDE_SERVER_WORK;
|
||||
newtctx->tc_magic = TCP4_CTX_MAGIC;
|
||||
newtctx->tc_side = TCP_SIDE_SERVER_WORK;
|
||||
newtctx->tc_magic = TCP_CTX_MAGIC;
|
||||
*newctxp = newtctx;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
tcp4_wrap(int fd, bool client, void **ctxp)
|
||||
tcp_wrap(int fd, bool client, void **ctxp)
|
||||
{
|
||||
|
||||
return (tcp4_setup_wrap(fd,
|
||||
client ? TCP4_SIDE_CLIENT : TCP4_SIDE_SERVER_WORK, ctxp));
|
||||
return (tcp_setup_wrap(fd,
|
||||
client ? TCP_SIDE_CLIENT : TCP_SIDE_SERVER_WORK, ctxp));
|
||||
}
|
||||
|
||||
static int
|
||||
tcp4_send(void *ctx, const unsigned char *data, size_t size, int fd)
|
||||
tcp_send(void *ctx, const unsigned char *data, size_t size, int fd)
|
||||
{
|
||||
struct tcp4_ctx *tctx = ctx;
|
||||
struct tcp_ctx *tctx = ctx;
|
||||
|
||||
PJDLOG_ASSERT(tctx != NULL);
|
||||
PJDLOG_ASSERT(tctx->tc_magic == TCP4_CTX_MAGIC);
|
||||
PJDLOG_ASSERT(tctx->tc_magic == TCP_CTX_MAGIC);
|
||||
PJDLOG_ASSERT(tctx->tc_fd >= 0);
|
||||
PJDLOG_ASSERT(fd == -1);
|
||||
|
||||
@ -476,12 +494,12 @@ tcp4_send(void *ctx, const unsigned char *data, size_t size, int fd)
|
||||
}
|
||||
|
||||
static int
|
||||
tcp4_recv(void *ctx, unsigned char *data, size_t size, int *fdp)
|
||||
tcp_recv(void *ctx, unsigned char *data, size_t size, int *fdp)
|
||||
{
|
||||
struct tcp4_ctx *tctx = ctx;
|
||||
struct tcp_ctx *tctx = ctx;
|
||||
|
||||
PJDLOG_ASSERT(tctx != NULL);
|
||||
PJDLOG_ASSERT(tctx->tc_magic == TCP4_CTX_MAGIC);
|
||||
PJDLOG_ASSERT(tctx->tc_magic == TCP_CTX_MAGIC);
|
||||
PJDLOG_ASSERT(tctx->tc_fd >= 0);
|
||||
PJDLOG_ASSERT(fdp == NULL);
|
||||
|
||||
@ -489,82 +507,105 @@ tcp4_recv(void *ctx, unsigned char *data, size_t size, int *fdp)
|
||||
}
|
||||
|
||||
static int
|
||||
tcp4_descriptor(const void *ctx)
|
||||
tcp_descriptor(const void *ctx)
|
||||
{
|
||||
const struct tcp4_ctx *tctx = ctx;
|
||||
const struct tcp_ctx *tctx = ctx;
|
||||
|
||||
PJDLOG_ASSERT(tctx != NULL);
|
||||
PJDLOG_ASSERT(tctx->tc_magic == TCP4_CTX_MAGIC);
|
||||
PJDLOG_ASSERT(tctx->tc_magic == TCP_CTX_MAGIC);
|
||||
|
||||
return (tctx->tc_fd);
|
||||
}
|
||||
|
||||
static bool
|
||||
tcp4_address_match(const void *ctx, const char *addr)
|
||||
tcp_address_match(const void *ctx, const char *addr)
|
||||
{
|
||||
const struct tcp4_ctx *tctx = ctx;
|
||||
struct sockaddr_in sin;
|
||||
socklen_t sinlen;
|
||||
in_addr_t ip1, ip2;
|
||||
const struct tcp_ctx *tctx = ctx;
|
||||
struct sockaddr_storage sa1, sa2;
|
||||
socklen_t salen;
|
||||
|
||||
PJDLOG_ASSERT(tctx != NULL);
|
||||
PJDLOG_ASSERT(tctx->tc_magic == TCP4_CTX_MAGIC);
|
||||
PJDLOG_ASSERT(tctx->tc_magic == TCP_CTX_MAGIC);
|
||||
|
||||
if (tcp4_addr(addr, PROTO_TCP4_DEFAULT_PORT, &sin) != 0)
|
||||
if (tcp_addr(addr, PROTO_TCP_DEFAULT_PORT, &sa1) != 0)
|
||||
return (false);
|
||||
ip1 = sin.sin_addr.s_addr;
|
||||
|
||||
sinlen = sizeof(sin);
|
||||
if (getpeername(tctx->tc_fd, (struct sockaddr *)&sin, &sinlen) < 0)
|
||||
salen = sizeof(sa2);
|
||||
if (getpeername(tctx->tc_fd, (struct sockaddr *)&sa2, &salen) < 0)
|
||||
return (false);
|
||||
ip2 = sin.sin_addr.s_addr;
|
||||
|
||||
return (ip1 == ip2);
|
||||
if (sa1.ss_family != sa2.ss_family || sa1.ss_len != sa2.ss_len)
|
||||
return (false);
|
||||
|
||||
switch (sa1.ss_family) {
|
||||
case AF_INET:
|
||||
{
|
||||
struct sockaddr_in *sin1, *sin2;
|
||||
|
||||
sin1 = (struct sockaddr_in *)&sa1;
|
||||
sin2 = (struct sockaddr_in *)&sa2;
|
||||
|
||||
return (memcmp(&sin1->sin_addr, &sin2->sin_addr,
|
||||
sizeof(sin1->sin_addr)) == 0);
|
||||
}
|
||||
case AF_INET6:
|
||||
{
|
||||
struct sockaddr_in6 *sin1, *sin2;
|
||||
|
||||
sin1 = (struct sockaddr_in6 *)&sa1;
|
||||
sin2 = (struct sockaddr_in6 *)&sa2;
|
||||
|
||||
return (memcmp(&sin1->sin6_addr, &sin2->sin6_addr,
|
||||
sizeof(sin1->sin6_addr)) == 0);
|
||||
}
|
||||
default:
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tcp4_local_address(const void *ctx, char *addr, size_t size)
|
||||
tcp_local_address(const void *ctx, char *addr, size_t size)
|
||||
{
|
||||
const struct tcp4_ctx *tctx = ctx;
|
||||
struct sockaddr_in sin;
|
||||
socklen_t sinlen;
|
||||
const struct tcp_ctx *tctx = ctx;
|
||||
struct sockaddr_storage sa;
|
||||
socklen_t salen;
|
||||
|
||||
PJDLOG_ASSERT(tctx != NULL);
|
||||
PJDLOG_ASSERT(tctx->tc_magic == TCP4_CTX_MAGIC);
|
||||
PJDLOG_ASSERT(tctx->tc_magic == TCP_CTX_MAGIC);
|
||||
|
||||
sinlen = sizeof(sin);
|
||||
if (getsockname(tctx->tc_fd, (struct sockaddr *)&sin, &sinlen) < 0) {
|
||||
salen = sizeof(sa);
|
||||
if (getsockname(tctx->tc_fd, (struct sockaddr *)&sa, &salen) < 0) {
|
||||
PJDLOG_VERIFY(strlcpy(addr, "N/A", size) < size);
|
||||
return;
|
||||
}
|
||||
PJDLOG_VERIFY(snprintf(addr, size, "tcp4://%S", &sin) < (ssize_t)size);
|
||||
PJDLOG_VERIFY(snprintf(addr, size, "tcp://%S", &sa) < (ssize_t)size);
|
||||
}
|
||||
|
||||
static void
|
||||
tcp4_remote_address(const void *ctx, char *addr, size_t size)
|
||||
tcp_remote_address(const void *ctx, char *addr, size_t size)
|
||||
{
|
||||
const struct tcp4_ctx *tctx = ctx;
|
||||
struct sockaddr_in sin;
|
||||
socklen_t sinlen;
|
||||
const struct tcp_ctx *tctx = ctx;
|
||||
struct sockaddr_storage sa;
|
||||
socklen_t salen;
|
||||
|
||||
PJDLOG_ASSERT(tctx != NULL);
|
||||
PJDLOG_ASSERT(tctx->tc_magic == TCP4_CTX_MAGIC);
|
||||
PJDLOG_ASSERT(tctx->tc_magic == TCP_CTX_MAGIC);
|
||||
|
||||
sinlen = sizeof(sin);
|
||||
if (getpeername(tctx->tc_fd, (struct sockaddr *)&sin, &sinlen) < 0) {
|
||||
salen = sizeof(sa);
|
||||
if (getpeername(tctx->tc_fd, (struct sockaddr *)&sa, &salen) < 0) {
|
||||
PJDLOG_VERIFY(strlcpy(addr, "N/A", size) < size);
|
||||
return;
|
||||
}
|
||||
PJDLOG_VERIFY(snprintf(addr, size, "tcp4://%S", &sin) < (ssize_t)size);
|
||||
PJDLOG_VERIFY(snprintf(addr, size, "tcp://%S", &sa) < (ssize_t)size);
|
||||
}
|
||||
|
||||
static void
|
||||
tcp4_close(void *ctx)
|
||||
tcp_close(void *ctx)
|
||||
{
|
||||
struct tcp4_ctx *tctx = ctx;
|
||||
struct tcp_ctx *tctx = ctx;
|
||||
|
||||
PJDLOG_ASSERT(tctx != NULL);
|
||||
PJDLOG_ASSERT(tctx->tc_magic == TCP4_CTX_MAGIC);
|
||||
PJDLOG_ASSERT(tctx->tc_magic == TCP_CTX_MAGIC);
|
||||
|
||||
if (tctx->tc_fd >= 0)
|
||||
close(tctx->tc_fd);
|
||||
@ -572,26 +613,26 @@ tcp4_close(void *ctx)
|
||||
free(tctx);
|
||||
}
|
||||
|
||||
static struct proto tcp4_proto = {
|
||||
.prt_name = "tcp4",
|
||||
.prt_client = tcp4_client,
|
||||
.prt_connect = tcp4_connect,
|
||||
.prt_connect_wait = tcp4_connect_wait,
|
||||
.prt_server = tcp4_server,
|
||||
.prt_accept = tcp4_accept,
|
||||
.prt_wrap = tcp4_wrap,
|
||||
.prt_send = tcp4_send,
|
||||
.prt_recv = tcp4_recv,
|
||||
.prt_descriptor = tcp4_descriptor,
|
||||
.prt_address_match = tcp4_address_match,
|
||||
.prt_local_address = tcp4_local_address,
|
||||
.prt_remote_address = tcp4_remote_address,
|
||||
.prt_close = tcp4_close
|
||||
static struct proto tcp_proto = {
|
||||
.prt_name = "tcp",
|
||||
.prt_client = tcp_client,
|
||||
.prt_connect = tcp_connect,
|
||||
.prt_connect_wait = tcp_connect_wait,
|
||||
.prt_server = tcp_server,
|
||||
.prt_accept = tcp_accept,
|
||||
.prt_wrap = tcp_wrap,
|
||||
.prt_send = tcp_send,
|
||||
.prt_recv = tcp_recv,
|
||||
.prt_descriptor = tcp_descriptor,
|
||||
.prt_address_match = tcp_address_match,
|
||||
.prt_local_address = tcp_local_address,
|
||||
.prt_remote_address = tcp_remote_address,
|
||||
.prt_close = tcp_close
|
||||
};
|
||||
|
||||
static __constructor void
|
||||
tcp4_ctor(void)
|
||||
tcp_ctor(void)
|
||||
{
|
||||
|
||||
proto_register(&tcp4_proto, true);
|
||||
proto_register(&tcp_proto, true);
|
||||
}
|
@ -68,7 +68,7 @@ sha256 { DP; return SHA256; }
|
||||
hole { DP; return HOLE; }
|
||||
lzf { DP; return LZF; }
|
||||
[0-9]+ { DP; yylval.num = atoi(yytext); return NUM; }
|
||||
[a-zA-Z0-9\.\-_/\:]+ { DP; yylval.str = strdup(yytext); return STR; }
|
||||
[a-zA-Z0-9\.\-_/\:\[\]]+ { DP; yylval.str = strdup(yytext); return STR; }
|
||||
\{ { DP; depth++; return OB; }
|
||||
\} { DP; depth--; return CB; }
|
||||
#.*$ /* ignore comments */;
|
||||
|
@ -17,12 +17,12 @@
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMATES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMATE.
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
@ -17,12 +17,12 @@
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMATES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMATE.
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
@ -86,8 +86,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <vm/uma_int.h>
|
||||
#include <vm/uma_dbg.h>
|
||||
|
||||
#include <machine/vmparam.h>
|
||||
|
||||
#include <ddb/ddb.h>
|
||||
|
||||
/*
|
||||
|
@ -358,7 +358,7 @@ arscp_copy(int ifd, int ofd)
|
||||
|
||||
/*
|
||||
* Add all modules of archive to current archive, if list != NULL,
|
||||
* only those modules speicifed in 'list' will be added.
|
||||
* only those modules specified in 'list' will be added.
|
||||
*/
|
||||
static void
|
||||
arscp_addlib(char *archive, struct list *list)
|
||||
@ -545,7 +545,7 @@ arscp_end(int eval)
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if target spcified, i.e, whether OPEN or CREATE has been
|
||||
* Check if target specified, i.e, whether OPEN or CREATE has been
|
||||
* issued by user.
|
||||
*/
|
||||
static int
|
||||
|
@ -109,7 +109,7 @@ main(int argc, char **argv)
|
||||
bsdar->progname = "ar";
|
||||
|
||||
/* Act like ranlib if our name ends in "ranlib"; this
|
||||
* accomodates arm-freebsd7.1-ranlib, bsdranlib, etc. */
|
||||
* accommodates arm-freebsd7.1-ranlib, bsdranlib, etc. */
|
||||
len = strlen(bsdar->progname);
|
||||
if (len >= strlen("ranlib") &&
|
||||
strcmp(bsdar->progname + len - strlen("ranlib"), "ranlib") == 0) {
|
||||
|
@ -113,7 +113,7 @@ ar_mode_A(struct bsdar *bsdar)
|
||||
/*
|
||||
* Create object from file, return created obj upon success, or NULL
|
||||
* when an error occurs or the member is not newer than existing
|
||||
* one while -u is specifed.
|
||||
* one while -u is specified.
|
||||
*/
|
||||
static struct ar_obj *
|
||||
create_obj_from_file(struct bsdar *bsdar, const char *name, time_t mtime)
|
||||
@ -220,7 +220,7 @@ insert_obj(struct bsdar *bsdar, struct ar_obj *obj, struct ar_obj *pos)
|
||||
|
||||
if (pos == NULL || obj == pos)
|
||||
/*
|
||||
* If the object to move happens to be the posistion obj,
|
||||
* If the object to move happens to be the position obj,
|
||||
* or if there is not a pos obj, move it to tail.
|
||||
*/
|
||||
goto tail;
|
||||
@ -418,7 +418,7 @@ write_archive(struct bsdar *bsdar, char mode)
|
||||
if (mode == 'A') {
|
||||
/*
|
||||
* Read objects from the target archive of ADDLIB command.
|
||||
* If there are members spcified in argv, read those members
|
||||
* If there are members specified in argv, read those members
|
||||
* only, otherwise the entire archive will be read.
|
||||
*/
|
||||
read_objs(bsdar, bsdar->addlib, 1);
|
||||
@ -438,7 +438,7 @@ write_archive(struct bsdar *bsdar, char mode)
|
||||
|
||||
/*
|
||||
* If can't find `pos' specified by user,
|
||||
* sliently insert objects at tail.
|
||||
* silently insert objects at tail.
|
||||
*/
|
||||
if (pos == NULL)
|
||||
bsdar->options &= ~(AR_A | AR_B);
|
||||
@ -699,7 +699,7 @@ create_symtab_entry(struct bsdar *bsdar, void *maddr, size_t size)
|
||||
return;
|
||||
}
|
||||
if (elf_kind(e) != ELF_K_ELF) {
|
||||
/* Sliently ignore non-elf member. */
|
||||
/* Silently ignore non-elf member. */
|
||||
elf_end(e);
|
||||
return;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user