/* -*-c-*-
*
- * $Id: socket.c,v 1.9 2002/02/23 00:08:00 mdw Exp $
+ * $Id: socket.c,v 1.10 2003/11/25 14:08:23 mdw Exp $
*
* Socket source and target definitions
*
/*----- Revision history --------------------------------------------------*
*
* $Log: socket.c,v $
+ * Revision 1.10 2003/11/25 14:08:23 mdw
+ * Debianization. Socket target options. Internet binding.
+ *
* Revision 1.9 2002/02/23 00:08:00 mdw
* Fix stupid bugs from the listen(2) change.
*
/*----- Other persistent variables ----------------------------------------*/
-static addr_opts gao = { 0 };
+static addr_opts gsao = { 0 }, gtao = { 0 };
/*----- Parsing address types ---------------------------------------------*/
DESTROY(ee);
}
-/* --- @stept_go@ --- *
+/* --- @starget_connected@ --- *
*
* Arguments: @int fd@ = file descriptor now ready for use
* @void *p@ = pointer to an endpoint structure
* Use: Handles successful connection of the target endpoint.
*/
-static void stept_go(int fd, void *p)
+void starget_connected(int fd, void *p)
{
stept *e = p;
endpt_kill(&e->e);
} else {
reffd *r = reffd_init(fd);
+ int opt = 1;
REFFD_INC(r);
+ fdflags(fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
+ setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(opt));
e->e.in = e->e.out = r;
e->e.f &= ~EPF_PENDING;
if (e->e.other)
ssource *ss = (ssource *)s;
ssource_opts *sso = ss ? &ss->o : &ssgo;
- CONF_BEGIN(sc, "socket", "socket")
+ CONF_BEGIN(sc, "socket", "socket source")
/* --- Make sure the next token is a word --- */
if (strcmp(sc->d.buf, "logging") == 0 ||
strcmp(sc->d.buf, "log") == 0) {
- addr_opts *ao = ss ? ss->ao : &gao;
+ addr_opts *ao = ss ? ss->ao : &gsao;
token(sc);
if (sc->t == '=')
token(sc);
/* --- Pass the option around the various address types --- */
if (ss) {
- if (ss->a->ops->option && ss->a->ops->option(sc, ss ? ss->ao : 0))
+ if (ss->a->ops->option && ss->a->ops->option(sc, ss->ao, ADDR_SRC))
CONF_ACCEPT;
} else {
addr_ops **a;
for (a = addrs; *a; a++) {
- if ((*a)->option && (*a)->option(sc, 0))
+ if ((*a)->option && (*a)->option(sc, 0, ADDR_GLOBAL))
CONF_ACCEPT;
}
}
ss->s.desc = 0;
ss->t = 0;
ss->a = getaddr(sc, ADDR_SRC);
- if (ss->a->ops->initopts)
- ss->ao = ss->a->ops->initopts();
+ if (ss->a->ops->initsrcopts)
+ ss->ao = ss->a->ops->initsrcopts();
else
ss->ao = CREATE(addr_opts);
- *ss->ao = gao;
+ *ss->ao = gsao;
ss->o = ssgo;
return (&ss->s);
}
static void ss_listen(ssource *ss)
{
- gen_addr *ga = (gen_addr *)ss->a;
int fd;
+ int opt = 1;
if (!(ss->ao->f & ADDRF_NOLOG))
fw_log(-1, "[%s] reattaching listener", ss->s.desc);
/* --- Make the socket --- */
- if ((fd = socket(ga->a.ops->pf, SOCK_STREAM, 0)) < 0) {
+ if ((fd = ss->a->ops->bind(ss->a, ss->ao)) < 0) {
fw_log(-1, "[%s] couldn't create socket: %s",
ss->s.desc, strerror(errno));
goto fail_0;
}
- /* --- Set it to allow address reuse --- */
-
- {
- int opt = 1;
- setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
- fdflags(fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
- }
-
- /* --- Bind it to the right port --- */
-
- if (bind(fd, &ga->sa, ga->a.sz)) {
- fw_log(-1, "[%s] couldn't bind socket: %s", ss->s.desc, strerror(errno));
- goto fail_1;
- }
- if (ga->a.ops->bound)
- ga->a.ops->bound(&ga->a, ss->ao);
-
/* --- Set it to listen for connections --- */
+ setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(opt));
+ fdflags(fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
if (listen(fd, ss->o.listen)) {
fw_log(-1, "[%s] couldn't listen on socket: %s",
ss->s.desc, strerror(errno));
{
ssource *ss = (ssource *)s;
int fd;
+ int opt = 1;
ss->t = t;
/* --- Initialize the socket for listening --- */
- {
- gen_addr *ga = (gen_addr *)ss->a;
-
- /* --- Make the socket --- */
-
- if ((fd = socket(ga->a.ops->pf, SOCK_STREAM, 0)) < 0)
- error(sc, "couldn't create socket: %s", strerror(errno));
-
- /* --- Set it to allow address reuse --- */
+ if ((fd = ss->a->ops->bind(ss->a, ss->ao)) < 0)
+ error(sc, "couldn't bind socket `%s': %s", ss->s.desc, strerror(errno));
- {
- int opt = 1;
- setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
- fdflags(fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
- }
-
- /* --- Bind it to the right port --- */
-
- if (bind(fd, &ga->sa, ga->a.sz))
- error(sc, "couldn't bind to %s: %s", ss->s.desc, strerror(errno));
- if (ga->a.ops->bound)
- ga->a.ops->bound(&ga->a, ss->ao);
-
- /* --- Set it to listen for connections --- */
+ /* --- Set it to listen for connections --- */
- if (listen(fd, ss->o.listen))
- error(sc, "couldn't listen on socket: %s", strerror(errno));
+ setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(opt));
+ fdflags(fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
+ if (listen(fd, ss->o.listen)) {
+ error(sc, "couldn't listen on socket `%s': %s",
+ ss->s.desc, strerror(errno));
}
/* --- We're ready to go now --- */
if (ss->a->ops->unbind)
ss->a->ops->unbind(ss->a);
}
- if (ss->a->ops->freeopts)
- ss->a->ops->freeopts(ss->ao);
+ if (ss->a->ops->freesrcopts)
+ ss->a->ops->freesrcopts(ss->ao);
else
DESTROY(ss->ao);
xfree(ss->s.desc);
/*----- Target definition -------------------------------------------------*/
+/* --- @options@ --- */
+
+static int starget_option(target *t, scanner *sc)
+{
+ starget *st = (starget *)t;
+
+ CONF_BEGIN(sc, "starget", "socket target")
+
+ /* --- Pass the option around the various address types --- */
+
+ if (st) {
+ if (st->a->ops->option && st->a->ops->option(sc, st->ao, ADDR_DEST))
+ CONF_ACCEPT;
+ }
+ /* We'd have done it already if it was global */
+
+ /* --- Done --- */
+
+ CONF_END;
+}
+
/* --- @read@ --- */
static target *starget_read(scanner *sc)
st = CREATE(starget);
st->t.ops = &starget_ops;
st->a = getaddr(sc, ADDR_DEST);
+ if (st->a->ops->inittargopts)
+ st->ao = st->a->ops->inittargopts();
+ else
+ st->ao = CREATE(addr_opts);
+ *st->ao = gtao;
dstr_puts(&d, "socket.");
st->a->ops->print(st->a, ADDR_DEST, &d);
st->t.desc = xstrdup(d.buf);
{
starget *st = (starget *)t;
stept *e = CREATE(stept);
- int fd;
- gen_addr *ga = (gen_addr *)st->a;
- int opt;
- if ((fd = socket(st->a->ops->pf, SOCK_STREAM, 0)) < 0)
- return (0);
- setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(opt));
- fdflags(fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
e->e.ops = &stept_ops;
e->e.other = 0;
e->e.f = EPF_FILE | EPF_PENDING;
e->e.t = 0;
e->desc = xstrdup(desc);
-
- if (conn_init(&e->c, sel, fd, &ga->sa, ga->a.sz, stept_go, e)) {
- fw_log(-1, "[%s] connection failed: %s", e->desc, strerror(errno));
+ if (st->a->ops->connect(st->a, st->ao, &e->c, &e->e)) {
+ fw_log(-1, "[%s] couldn't connect: %s", e->desc, strerror(errno));
DESTROY(e);
return (0);
}
static void starget_destroy(target *t)
{
starget *st = (starget *)t;
+ if (st->a->ops->freetargopts)
+ st->a->ops->freetargopts(st->ao);
+ else
+ DESTROY(st->ao);
st->a->ops->destroy(st->a);
xfree(st->t.desc);
DESTROY(st);
target_ops starget_ops = {
"socket",
- 0, starget_read, starget_create, starget_destroy
+ starget_option, starget_read, starget_create, starget_destroy
};
/*----- That's all, folks -------------------------------------------------*/