/*----- Data structures ---------------------------------------------------*/
+typedef union addr {
+ struct sockaddr sa;
+ struct sockaddr_in sin;
+} addr;
+
typedef struct pk {
struct pk *next; /* Next packet in the chain */
octet *p, *o; /* Buffer start and current posn */
unsigned f; /* Various flags */
#define cwf_port 1u /* Port is defined => listen */
sel_file a; /* Selector */
- struct sockaddr_in me, peer; /* Who I'm meant to be; who peer is */
+ addr me, peer; /* Who I'm meant to be; who peer is */
} connwait;
/*----- Static variables --------------------------------------------------*/
static int cloexec(int fd)
{ return (fdflags(fd, 0, 0, FD_CLOEXEC, FD_CLOEXEC)); }
-static void initaddr(struct sockaddr_in *sin)
+static void initaddr(addr *a)
{
- sin->sin_family = AF_INET;
- sin->sin_addr.s_addr = INADDR_ANY;
- sin->sin_port = 0;
+ a->sin.sin_family = AF_INET;
+ a->sin.sin_addr.s_addr = INADDR_ANY;
+ a->sin.sin_port = 0;
}
static void dolisten(void);
static void doaccept(int fd_s, unsigned mode, void *p)
{
int fd;
- struct sockaddr_in sin;
- socklen_t sz = sizeof(sin);
+ addr a;
+ socklen_t sz = sizeof(a);
- if ((fd = accept(fd_s, (struct sockaddr *)&sin, &sz)) < 0) {
+ if ((fd = accept(fd_s, &a.sa, &sz)) < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) return;
moan("couldn't accept incoming connection: %s", strerror(errno));
return;
}
- if (cw.peer.sin_addr.s_addr != INADDR_ANY &&
- cw.peer.sin_addr.s_addr != sin.sin_addr.s_addr) {
- moan("rejecting connection from %s", inet_ntoa(sin.sin_addr));
+ if (cw.peer.sin.sin_addr.s_addr != INADDR_ANY &&
+ cw.peer.sin.sin_addr.s_addr != a.sin.sin_addr.s_addr) {
+ moan("rejecting connection from %s", inet_ntoa(a.sin.sin_addr));
close(fd); return;
}
if (nonblockify(fd) || cloexec(fd)) {
if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0 ||
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) ||
- bind(fd, (struct sockaddr *)&cw.me, sizeof(cw.me)) ||
+ bind(fd, &cw.me.sa, sizeof(cw.me.sin)) ||
listen(fd, 1) || nonblockify(fd) || cloexec(fd))
die(1, "couldn't set up listening socket: %s", strerror(errno));
sel_initfile(&sel, &cw.a, fd, SEL_READ, doaccept, 0);
}
#define paf_parse 1u
-static void parseaddr(const char *host, const char *svc, unsigned f,
- struct sockaddr_in *sin)
+static void parseaddr(const char *host, const char *svc, unsigned f, addr *a)
{
char *alloc = 0, *sep;
struct hostent *h;
if (host) {
if ((h = gethostbyname(host)) == 0) die(1, "unknown host `%s'", host);
- memcpy(&sin->sin_addr, h->h_addr, sizeof(sin->sin_addr));
+ memcpy(&a->sin.sin_addr, h->h_addr, sizeof(a->sin.sin_addr));
}
if (svc) {
if ((n = strtoul(svc, &qq, 0)) > 0 && !*qq && n <= 0xffff)
- sin->sin_port = htons(n);
+ a->sin.sin_port = htons(n);
else if ((s = getservbyname(svc, "tcp")) != 0)
- sin->sin_port = s->s_port;
+ a->sin.sin_port = s->s_port;
else
die(1, "bad service name/number `%s'", svc);
}
{
unsigned f = 0;
const char *bindhost = 0, *bindsvc = 0, *peerhost = 0;
- struct sockaddr_in bindaddr;
+ addr bindaddr;
const char *connhost = 0;
- struct sockaddr_in tmpaddr;
+ addr tmpaddr;
int fd = -1;
int len = 65536;
parseaddr(connhost, 0, paf_parse, &tmpaddr);
if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0 ||
(bindhost &&
- bind(fd, (struct sockaddr *)&bindaddr, sizeof(bindaddr))) ||
- connect(fd, (struct sockaddr *)&tmpaddr, sizeof(tmpaddr)))
+ bind(fd, &bindaddr.sa, sizeof(bindaddr.sin))) ||
+ connect(fd, &tmpaddr.sa, sizeof(tmpaddr.sin)))
die(1, "couldn't connect to TCP server: %s", strerror(errno));
if (nonblockify(fd) || cloexec(fd))
die(1, "couldn't connect to TCP server: %s", strerror(errno));
nonblockify(fd_udp) || cloexec(fd_udp) ||
setsockopt(fd_udp, SOL_SOCKET, SO_RCVBUF, &len, sizeof(len)) ||
setsockopt(fd_udp, SOL_SOCKET, SO_SNDBUF, &len, sizeof(len)) ||
- bind(fd_udp, (struct sockaddr *)&tmpaddr, sizeof(tmpaddr)))
+ bind(fd_udp, &tmpaddr.sa, sizeof(tmpaddr.sin)))
die(1, "couldn't set up UDP socket: %s", strerror(errno));
initaddr(&tmpaddr);
parseaddr(argv[optind + 1], 0, paf_parse, &tmpaddr);
- if (connect(fd_udp, (struct sockaddr *)&tmpaddr, sizeof(tmpaddr)))
+ if (connect(fd_udp, &tmpaddr.sa, sizeof(tmpaddr.sin)))
die(1, "couldn't set up UDP socket: %s", strerror(errno));
if (bindsvc) dolisten();