From 6a72447c4192e413afcd7ebe5c8fbca20587275a Mon Sep 17 00:00:00 2001 From: kristopher tate Date: Sat, 17 Jun 2017 04:01:02 +0900 Subject: [PATCH 01/15] changes to support ever/ip; --- include/re_fmt.h | 7 +++ include/re_mbuf.h | 19 +++++++ include/re_net.h | 3 ++ include/re_odict.h | 3 +- mk/re.mk | 6 ++- src/fmt/pl.c | 87 ++++++++++++++++++++++++++++++ src/json/encode.c | 3 +- src/net/darwin/ifset.c | 120 +++++++++++++++++++++++++++++++++++++++++ src/net/linux/ifset.c | 117 ++++++++++++++++++++++++++++++++++++++++ src/net/mod.mk | 11 ++++ src/odict/entry.c | 7 +-- 11 files changed, 376 insertions(+), 7 deletions(-) create mode 100644 src/net/darwin/ifset.c create mode 100644 src/net/linux/ifset.c diff --git a/include/re_fmt.h b/include/re_fmt.h index 440bd589..2878b971 100644 --- a/include/re_fmt.h +++ b/include/re_fmt.h @@ -2,6 +2,7 @@ * @file re_fmt.h Interface to formatted text functions * * Copyright (C) 2010 Creytiv.com + * Copyright (C) 2017 kristopher tate & connectFree Corporation */ @@ -43,6 +44,12 @@ int pl_cmp(const struct pl *pl1, const struct pl *pl2); int pl_casecmp(const struct pl *pl1, const struct pl *pl2); const char *pl_strchr(const struct pl *pl, char c); +int pl_read_mem(struct pl *pl, uint8_t *buf, size_t size); +uint8_t pl_read_u8(struct pl *pl); +uint16_t pl_read_u16(struct pl *pl); +uint32_t pl_read_u32(struct pl *pl); +uint64_t pl_read_u64(struct pl *pl); + /** Advance pl position/length by +/- N bytes */ static inline void pl_advance(struct pl *pl, ssize_t n) { diff --git a/include/re_mbuf.h b/include/re_mbuf.h index feac6fd0..88fad46a 100644 --- a/include/re_mbuf.h +++ b/include/re_mbuf.h @@ -2,10 +2,12 @@ * @file re_mbuf.h Interface to memory buffers * * Copyright (C) 2010 Creytiv.com + * Copyright (C) 2017 kristopher tate & connectFree Corporation */ #include +#include #ifndef RELEASE @@ -81,6 +83,23 @@ static inline uint8_t *mbuf_buf(const struct mbuf *mb) return mb ? mb->buf + mb->pos : (uint8_t *)NULL; } +/** + * Clone a Memory buffer + * + * @param mb Memory buffer + * + * @return Cloned buffer + */ +static inline struct mbuf *mbuf_clone(const struct mbuf *mb) +{ + struct mbuf *out; + if (!mb) return NULL; + out = mbuf_alloc(mb->size); + memcpy(out->buf, mb->buf, mb->size); + out->pos = mb->pos; + out->end = mb->end; + return out; +} /** * Get number of bytes left in a memory buffer, from current position to end diff --git a/include/re_net.h b/include/re_net.h index 4e7c7acb..d98b19b3 100644 --- a/include/re_net.h +++ b/include/re_net.h @@ -2,6 +2,7 @@ * @file re_net.h Interface to Networking module. * * Copyright (C) 2010 Creytiv.com + * Copyright (C) 2017 kristopher tate & connectFree Corporation */ #ifdef CYGWIN #include @@ -86,6 +87,8 @@ int net_if_apply(net_ifaddr_h *ifh, void *arg); int net_if_debug(struct re_printf *pf, void *unused); int net_if_getlinklocal(const char *ifname, int af, struct sa *ip); +int net_if_setmtu(const char *ifname, uint32_t mtu); +int net_if_setaddr(const char *ifname, const struct sa *ip, int prefix_len); /* Net interface (ifaddrs.c) */ int net_getifaddrs(net_ifaddr_h *ifh, void *arg); diff --git a/include/re_odict.h b/include/re_odict.h index 02d32243..bae9a055 100644 --- a/include/re_odict.h +++ b/include/re_odict.h @@ -2,6 +2,7 @@ * @file re_odict.h Interface to Ordered Dictionary * * Copyright (C) 2010 - 2015 Creytiv.com + * Copyright (C) 2017 kristopher tate & connectFree Corporation */ enum odict_type { @@ -24,7 +25,7 @@ struct odict_entry { char *key; union { struct odict *odict; /* ODICT_OBJECT / ODICT_ARRAY */ - char *str; /* ODICT_STRING */ + struct pl pl; /* ODICT_STRING */ int64_t integer; /* ODICT_INT */ double dbl; /* ODICT_DOUBLE */ bool boolean; /* ODICT_BOOL */ diff --git a/mk/re.mk b/mk/re.mk index 3ba29a0e..843e6bb1 100644 --- a/mk/re.mk +++ b/mk/re.mk @@ -2,6 +2,7 @@ # re.mk - common make rules # # Copyright (C) 2010 Creytiv.com +# Copyright (C) 2017 kristopher tate & connectFree Corporation # # Imported variables: # @@ -251,6 +252,7 @@ ifeq ($(OS),gnu) endif ifeq ($(OS),darwin) CFLAGS += -fPIC -dynamic -DDARWIN + LFLAGS += -framework SystemConfiguration -framework CoreFoundation ifneq (,$(findstring Apple, $(CC_LONGVER))) CFLAGS += -Wshorten-64-to-32 endif @@ -459,7 +461,7 @@ endif # External libraries section # -USE_OPENSSL := $(shell [ -f $(SYSROOT)/include/openssl/ssl.h ] || \ +USE_OPENSSL ?= $(shell [ -f $(SYSROOT)/include/openssl/ssl.h ] || \ [ -f $(SYSROOT)/local/include/openssl/ssl.h ] || \ [ -f $(SYSROOT_ALT)/include/openssl/ssl.h ] && echo "yes") @@ -771,7 +773,7 @@ rpm: tar # - system installation # -LIBRE_PATH := ../re +LIBRE_PATH ?= ../re # Include path LIBRE_INC := $(shell [ -f $(LIBRE_PATH)/include/re.h ] && \ diff --git a/src/fmt/pl.c b/src/fmt/pl.c index a35fe77c..4a17a88d 100644 --- a/src/fmt/pl.c +++ b/src/fmt/pl.c @@ -2,6 +2,7 @@ * @file pl.c Pointer-length functions * * Copyright (C) 2010 Creytiv.com + * Copyright (C) 2017 kristopher tate & connectFree Corporation */ #include #include @@ -16,6 +17,9 @@ #include #include +#define DEBUG_MODULE "fmt" +#define DEBUG_LEVEL 4 +#include /** Pointer-length NULL initialiser */ const struct pl pl_null = {NULL, 0}; @@ -185,6 +189,89 @@ uint64_t pl_x64(const struct pl *pl) return v; } +/** + * Read a block of memory from a Pointer-length object + * + * @param pl Pointer-length object + * @param buf Buffer to read data to + * @param size Size of buffer + * + * @return 0 if success, otherwise errorcode + */ +int pl_read_mem(struct pl *pl, uint8_t *buf, size_t size) +{ + if (!pl || !buf) + return EINVAL; + + if (size > pl->l) { + DEBUG_WARNING("tried to read beyond pl end (%u > %u)\n", + size, pl->l); + return EOVERFLOW; + } + + memcpy(buf, pl->p, size); + + pl->p += size; + pl->l -= size; + + return 0; +} + +/** + * Read an 8-bit value from a Pointer-length object + * + * @param pl Pointer-length object + * + * @return 8-bit value + */ +uint8_t pl_read_u8(struct pl *pl) +{ + uint8_t v; + return (0 == pl_read_mem(pl, &v, sizeof(v))) ? v : 0; +} + + +/** + * Read a 16-bit value from a Pointer-length object + * + * @param pl Pointer-length object + * + * @return 16-bit value + */ +uint16_t pl_read_u16(struct pl *pl) +{ + uint16_t v; + return (0 == pl_read_mem(pl, (uint8_t *)&v, sizeof(v))) ? v : 0; +} + + +/** + * Read a 32-bit value from a Pointer-length object + * + * @param pl Pointer-length object + * + * @return 32-bit value + */ +uint32_t pl_read_u32(struct pl *pl) +{ + uint32_t v; + return (0 == pl_read_mem(pl, (uint8_t *)&v, sizeof(v))) ? v : 0; +} + + +/** + * Read a 64-bit value from a Pointer-length object + * + * @param pl Pointer-length object + * + * @return 64-bit value + */ +uint64_t pl_read_u64(struct pl *pl) +{ + uint64_t v; + return (0 == pl_read_mem(pl, (uint8_t *)&v, sizeof(v))) ? v : 0; +} + /** * Convert a pointer-length object to floating point representation. diff --git a/src/json/encode.c b/src/json/encode.c index fa56de3d..8df8484d 100644 --- a/src/json/encode.c +++ b/src/json/encode.c @@ -2,6 +2,7 @@ * @file json/encode.c JSON encoder * * Copyright (C) 2010 - 2015 Creytiv.com + * Copyright (C) 2017 kristopher tate & connectFree Corporation */ #include #include @@ -53,7 +54,7 @@ static int encode_entry(struct re_printf *pf, const struct odict_entry *e) break; case ODICT_STRING: - err = re_hprintf(pf, "\"%H\"", utf8_encode, e->u.str); + err = re_hprintf(pf, "\"%H\"", utf8_encode, e->u.pl.p); break; case ODICT_BOOL: diff --git a/src/net/darwin/ifset.c b/src/net/darwin/ifset.c new file mode 100644 index 00000000..96ffeb49 --- /dev/null +++ b/src/net/darwin/ifset.c @@ -0,0 +1,120 @@ +/** + * @file darwin/ifset.c + * + * Copyright (C) 2017 kristopher tate & connectFree Corporation + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include // ND6_INFINITE_LIFETIME +#include +#include +#include // struct sockaddr_dl +#include // AF_ROUTE things + + +#include +#include +#include +#include + + +#define DEBUG_MODULE "ifset" +#define DEBUG_LEVEL 5 +#include + + +int net_if_setmtu(const char *ifname, uint32_t mtu) +{ + + int s = socket(AF_INET6, SOCK_DGRAM, 0); + + if (s < 0) { + DEBUG_WARNING("net_if_setmtu: socket()\n"); + return EINVAL; + } + + struct ifreq ifRequest; + + strncpy(ifRequest.ifr_name, ifname, IFNAMSIZ); + ifRequest.ifr_mtu = mtu; + + DEBUG_INFO("net_if_setaddr: MTU for dev [%s] set to [%u", ifname, mtu); + + if (ioctl(s, SIOCSIFMTU, &ifRequest) < 0) { + DEBUG_WARNING( "net_if_setmtu: ioctl(SIOCSIFMTU)\n"); + } + + close(s); + + return 0; + +} + +int net_if_setaddr( const char *ifname + , const struct sa *ip + , int prefix_len ) +{ + + struct in6_aliasreq addreq6; + + if (!ifname || !ip) + return EINVAL; + + /* TODO: support ipv4 */ + if (ip->u.sa.sa_family != AF_INET6) + return EINVAL; + + + memset(&addreq6, 0, sizeof(struct in6_aliasreq)); + addreq6.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME; + addreq6.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME; + //addreq6.ifra_lifetime.ia6t_expire = ND6_INFINITE_LIFETIME; + //addreq6.ifra_lifetime.ia6t_preferred = ND6_INFINITE_LIFETIME; + + int fd = socket(AF_INET6, SOCK_DGRAM, 0); + if (fd < 0) { + DEBUG_WARNING("net_if_setaddr: socket()\n"); + return EINVAL; + } + + strncpy(addreq6.ifra_name, ifname, sizeof(addreq6.ifra_name)); + + memcpy(&addreq6.ifra_addr, &ip->u.in6, sizeof(struct sockaddr_in6)); + + addreq6.ifra_addr.sin6_family = AF_INET6; + addreq6.ifra_addr.sin6_len = sizeof(addreq6.ifra_addr); + + /* set prefix mask */ + struct sockaddr_in6* mask = &addreq6.ifra_prefixmask; + + mask->sin6_len = sizeof(*mask); + if (prefix_len >= 128 || prefix_len <= 0) { + memset(&mask->sin6_addr, 0xff, sizeof(struct in6_addr)); + } else { + memset((void *)&mask->sin6_addr, 0x00, sizeof(mask->sin6_addr)); + memset((void *)&mask->sin6_addr, 0xff, prefix_len>>3); + ((uint8_t*)&mask->sin6_addr)[prefix_len>>3] = 0xff << (8 - (prefix_len%8)); + } + + if(-1 == ioctl(fd, SIOCAIFADDR_IN6, &addreq6)) { + DEBUG_WARNING( "net_if_setaddr: ioctl(SIOCAIFADDR_IN6)\n"); + close(fd); + return EINVAL; + } + + close(fd); + return 0; +} + diff --git a/src/net/linux/ifset.c b/src/net/linux/ifset.c new file mode 100644 index 00000000..ee3d039f --- /dev/null +++ b/src/net/linux/ifset.c @@ -0,0 +1,117 @@ +/** + * @file linux/ifset.c + * + * Copyright (C) 2017 kristopher tate & connectFree Corporation + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#if !defined(_LINUX_IN6_H) && !defined(_UAPI_LINUX_IN6_H) + struct in6_ifreq { + struct in6_addr ifr6_addr; + uint32_t ifr6_prefixlen; + int ifr6_ifindex; + }; +#endif + +#define DEBUG_MODULE "ifset" +#define DEBUG_LEVEL 5 +#include + +#define _IFNAME_SOCK(af_type, ifr, ifname) {\ + if ((s = socket(af_type, SOCK_DGRAM, 0)) < 0) { \ + err = errno; \ + goto err; \ + } \ + memset(&ifr, 0, sizeof(struct ifreq)); \ + strncpy(ifr.ifr_name, ifname, IFNAMSIZ); \ + if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) { \ + err = errno; \ + goto err; \ + DEBUG_WARNING("ioctl(SIOCGIFINDEX) [%s]", strerror(err)); \ + } \ +} + + +int net_if_setmtu(const char *ifname, uint32_t mtu) +{ + int err = 0; + struct ifreq ifr; + int s = -1; + + _IFNAME_SOCK(AF_INET6, ifr, ifname); + + ifr.ifr_mtu = mtu; + if (ioctl(s, SIOCSIFMTU, &ifr) < 0) { + err = errno; + goto err; + DEBUG_WARNING("ioctl(SIOCSIFMTU) [%s]", strerror(err)); + } + +err: + if (s > 0) + close(s); + return err; +} + +int net_if_setaddr( const char *ifname + , const struct sa *ip + , int prefix_len ) +{ + int _idx; + int s = -1; + int err = 0; + struct ifreq ifr; + + _IFNAME_SOCK(sa_af(ip), ifr, ifname); + _idx = ifr.ifr_ifindex; + +/* BRING UP */ + if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0) { + err = errno; + goto err; + DEBUG_WARNING("ioctl(SIOCGIFFLAGS) [%s]", strerror(err)); + } + + if (!(ifr.ifr_flags & IFF_UP & IFF_RUNNING)) { + DEBUG_INFO("[%s] GOING UP", ifr.ifr_name); + ifr.ifr_flags |= IFF_UP | IFF_RUNNING; + if (ioctl(s, SIOCSIFFLAGS, &ifr) < 0) { + err = errno; + goto err; + DEBUG_WARNING("ioctl(SIOCSIFFLAGS) [%s]", strerror(err)); + } + } + + if (ip->u.sa.sa_family == AF_INET6) { + struct in6_ifreq ifr6 = { + .ifr6_ifindex = _idx, + .ifr6_prefixlen = prefix_len + }; + + memcpy(&ifr6.ifr6_addr, (void *)(&ip->u.in6.sin6_addr), 16); + + if (ioctl(s, SIOCSIFADDR, &ifr6) < 0) { + err = errno; + goto err; + DEBUG_WARNING("ioctl(SIOCSIFADDR) [%s]", strerror(err)); + } + } + +err: + if (s > 0) + close(s); + return err; +} diff --git a/src/net/mod.mk b/src/net/mod.mk index ccd1e0ea..89745d05 100644 --- a/src/net/mod.mk +++ b/src/net/mod.mk @@ -2,6 +2,7 @@ # mod.mk # # Copyright (C) 2010 Creytiv.com +# Copyright (C) 2017 kristopher tate & connectFree Corporation # # Generic files @@ -41,3 +42,13 @@ endif ifdef HAVE_GETIFADDRS SRCS += net/ifaddrs.c endif + +#ifset +ifeq ($(OS),darwin) +SRCS += net/darwin/ifset.c +CFLAGS += -DHAVE_NETIFSET +endif +ifeq ($(OS),linux) +SRCS += net/linux/ifset.c +CFLAGS += -DHAVE_NETIFSET +endif diff --git a/src/odict/entry.c b/src/odict/entry.c index fb6431ae..0adcecc7 100644 --- a/src/odict/entry.c +++ b/src/odict/entry.c @@ -2,6 +2,7 @@ * @file odict/entry.c Ordered Dictionary -- entry * * Copyright (C) 2010 - 2015 Creytiv.com + * Copyright (C) 2017 kristopher tate & connectFree Corporation */ #include "re_types.h" @@ -24,7 +25,7 @@ static void destructor(void *arg) break; case ODICT_STRING: - mem_deref(e->u.str); + mem_deref((void *)e->u.pl.p); break; default: @@ -67,7 +68,7 @@ int odict_entry_add(struct odict *o, const char *key, break; case ODICT_STRING: - err = str_dup(&e->u.str, va_arg(ap, const char *)); + err = pl_dup(&e->u.pl, va_arg(ap, const struct pl *)); break; case ODICT_INT: @@ -129,7 +130,7 @@ int odict_entry_debug(struct re_printf *pf, const struct odict_entry *e) break; case ODICT_STRING: - err |= re_hprintf(pf, ":%s", e->u.str); + err |= re_hprintf(pf, ":(%llu)[%w]", (uint64_t)e->u.pl.l, e->u.pl.p, e->u.pl.l); break; case ODICT_INT: From 8d14657e02c81bbaeba07a31853fa48c51b5ec74 Mon Sep 17 00:00:00 2001 From: kristopher tate Date: Sat, 1 Jul 2017 17:04:02 +0900 Subject: [PATCH 02/15] json: more changes to support ever/ip; --- include/re.h | 1 + include/re_bitv.h | 2 +- include/re_json.h | 2 +- src/json/decode.c | 8 ++++---- src/json/decode_odict.c | 2 +- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/include/re.h b/include/re.h index d557440d..5fdb6ca4 100644 --- a/include/re.h +++ b/include/re.h @@ -23,6 +23,7 @@ extern "C" { #include "re_aes.h" #include "re_base64.h" #include "re_bfcp.h" +#include "re_bitv.h" #include "re_conf.h" #include "re_crc32.h" #include "re_dns.h" diff --git a/include/re_bitv.h b/include/re_bitv.h index 7ed774ad..af95817e 100644 --- a/include/re_bitv.h +++ b/include/re_bitv.h @@ -5,7 +5,7 @@ */ -typedef unsigned long bitv_t; +typedef uint32_t bitv_t; enum { BITS_SZ = (8*sizeof(bitv_t)), diff --git a/include/re_json.h b/include/re_json.h index 0cc43db3..a3432e10 100644 --- a/include/re_json.h +++ b/include/re_json.h @@ -14,7 +14,7 @@ enum json_typ { struct json_value { union { - char *str; + struct pl pl; int64_t integer; double dbl; bool boolean; diff --git a/src/json/decode.c b/src/json/decode.c index cf1e9b51..2c66a857 100644 --- a/src/json/decode.c +++ b/src/json/decode.c @@ -137,8 +137,8 @@ static int decode_value(struct json_value *val, const struct pl *pl) return EBADMSG; if (is_string(&pls, pl)) { - - err = re_sdprintf(&val->v.str, "%H", utf8_decode, &pls); + err = re_sdprintf((char **)&val->v.pl.p, "%H", utf8_decode, &pls); + val->v.pl.l = str_len(val->v.pl.p); val->type = JSON_STRING; } else if (is_number(&dbl, &isfloat, pl)) { @@ -194,7 +194,7 @@ static int object_entry(const struct pl *pl_name, const struct pl *pl_val, err = oeh(name, &val, arg); if (val.type == JSON_STRING) - mem_deref(val.v.str); + mem_deref((void *)val.v.pl.p); out: mem_deref(name); @@ -217,7 +217,7 @@ static int array_entry(unsigned idx, const struct pl *pl_val, err = aeh(idx, &val, arg); if (val.type == JSON_STRING) - mem_deref(val.v.str); + mem_deref((void *)val.v.pl.p); return err; } diff --git a/src/json/decode_odict.c b/src/json/decode_odict.c index cd64affd..cf1c61a6 100644 --- a/src/json/decode_odict.c +++ b/src/json/decode_odict.c @@ -59,7 +59,7 @@ static int entry_add(struct odict *o, const char *name, switch (val->type) { case JSON_STRING: - return odict_entry_add(o, name, ODICT_STRING, val->v.str); + return odict_entry_add(o, name, ODICT_STRING, &val->v.pl); case JSON_INT: return odict_entry_add(o, name, ODICT_INT, val->v.integer); From 03617f48fac88e02f4906675cd5f2eea44d398ae Mon Sep 17 00:00:00 2001 From: kristopher tate Date: Fri, 18 Aug 2017 00:43:29 +0900 Subject: [PATCH 03/15] udp: changes to support net_sockopt_reuse_set in udp; --- include/re_udp.h | 6 ++++++ src/udp/udp.c | 42 +++++++++++++++++++++++++++++------------- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/include/re_udp.h b/include/re_udp.h index f744f2f9..c7f8fd9b 100644 --- a/include/re_udp.h +++ b/include/re_udp.h @@ -2,6 +2,7 @@ * @file re_udp.h Interface to User Datagram Protocol * * Copyright (C) 2010 Creytiv.com + * Copyright (C) 2017 kristopher tate & connectFree Corporation */ @@ -22,6 +23,11 @@ typedef void (udp_error_h)(int err, void *arg); int udp_listen(struct udp_sock **usp, const struct sa *local, udp_recv_h *rh, void *arg); +int udp_listen_advanced( struct udp_sock **usp + , const struct sa *local + , udp_recv_h *rh + , bool sockopt_reuse + , void *arg); int udp_connect(struct udp_sock *us, const struct sa *peer); int udp_send(struct udp_sock *us, const struct sa *dst, struct mbuf *mb); int udp_send_anon(const struct sa *dst, struct mbuf *mb); diff --git a/src/udp/udp.c b/src/udp/udp.c index 07ad55d7..0102ca6c 100644 --- a/src/udp/udp.c +++ b/src/udp/udp.c @@ -2,6 +2,7 @@ * @file udp.c User Datagram Protocol * * Copyright (C) 2010 Creytiv.com + * Copyright (C) 2017 kristopher tate & connectFree Corporation */ #include #ifdef HAVE_UNISTD_H @@ -242,19 +243,11 @@ static void udp_read_handler6(int flags, void *arg) udp_read(us, us->fd6); } - -/** - * Create and listen on a UDP Socket - * - * @param usp Pointer to returned UDP Socket - * @param local Local network address - * @param rh Receive handler - * @param arg Handler argument - * - * @return 0 if success, otherwise errorcode - */ -int udp_listen(struct udp_sock **usp, const struct sa *local, - udp_recv_h *rh, void *arg) +int udp_listen_advanced( struct udp_sock **usp + , const struct sa *local + , udp_recv_h *rh + , bool sockopt_reuse + , void *arg) { struct addrinfo hints, *res = NULL, *r; struct udp_sock *us = NULL; @@ -329,6 +322,13 @@ int udp_listen(struct udp_sock **usp, const struct sa *local, continue; } + err = net_sockopt_reuse_set(fd, sockopt_reuse); + if (err) { + DEBUG_WARNING("udp listen: reuse set: %m\n", err); + (void)close(fd); + continue; + } + if (bind(fd, r->ai_addr, SIZ_CAST r->ai_addrlen) < 0) { err = errno; DEBUG_INFO("listen: bind(): %m (%J)\n", err, local); @@ -390,6 +390,22 @@ int udp_listen(struct udp_sock **usp, const struct sa *local, return err; } +/** + * Create and listen on a UDP Socket + * + * @param usp Pointer to returned UDP Socket + * @param local Local network address + * @param rh Receive handler + * @param arg Handler argument + * + * @return 0 if success, otherwise errorcode + */ +int udp_listen(struct udp_sock **usp, const struct sa *local, + udp_recv_h *rh, void *arg) +{ + return udp_listen_advanced(usp, local, rh, false, arg); +} + /** * Connect a UDP Socket to a specific peer. From 655d3477882fb533122d51aaef2301aea6850aa9 Mon Sep 17 00:00:00 2001 From: kristopher tate Date: Fri, 18 Aug 2017 00:44:02 +0900 Subject: [PATCH 04/15] main: winsock.h to winsock2.h; --- src/main/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/main.c b/src/main/main.c index 762b0b4f..b8435532 100644 --- a/src/main/main.c +++ b/src/main/main.c @@ -13,7 +13,7 @@ #include #endif #ifdef WIN32 -#include +#include #endif #ifdef HAVE_SIGNAL #include From b3eef9e37219fce343d21aabdfffec7da7e580f2 Mon Sep 17 00:00:00 2001 From: kristopher tate Date: Fri, 18 Aug 2017 00:45:21 +0900 Subject: [PATCH 05/15] win32: ifset for windows; --- src/net/mod.mk | 4 ++ src/net/win32/ifset.c | 154 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 src/net/win32/ifset.c diff --git a/src/net/mod.mk b/src/net/mod.mk index 89745d05..4d697317 100644 --- a/src/net/mod.mk +++ b/src/net/mod.mk @@ -52,3 +52,7 @@ ifeq ($(OS),linux) SRCS += net/linux/ifset.c CFLAGS += -DHAVE_NETIFSET endif +ifeq ($(OS),win32) +SRCS += net/win32/ifset.c +CFLAGS += -DHAVE_NETIFSET +endif \ No newline at end of file diff --git a/src/net/win32/ifset.c b/src/net/win32/ifset.c new file mode 100644 index 00000000..88db596d --- /dev/null +++ b/src/net/win32/ifset.c @@ -0,0 +1,154 @@ +/** + * @file win32/ifset.c + * + * Copyright (C) 2017 kristopher tate & connectFree Corporation + */ + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG_MODULE "ifset" +#define DEBUG_LEVEL 5 +#include + +#if 0 +#define NET_LUID misalligned_NET_LUID +#define PNET_LUID misalligned_PNET_LUID +#define IF_LUID misalligned_IF_LUID +#define PIF_LUID misalligned_PIF_LUID +#include +#undef NET_LUID +#undef PNET_LUID +#undef IF_LUID +#undef PIF_LUID + +typedef union NET_LUID { + ULONG64 Value; + __C89_NAMELESS struct { + ULONG64 Reserved :24; + ULONG64 NetLuidIndex :24; + ULONG64 IfType :16; + } Info; +} NET_LUID, *PNET_LUID; +#endif + +static int _toluid(const char* name, PNET_LUID luid) +{ + NET_LUID out; + uint16_t ifName[IF_MAX_STRING_SIZE + 1] = {0}; + if (0 == MultiByteToWideChar(CP_ACP + , 0 + , name + , strlen(name) + , ifName + , IF_MAX_STRING_SIZE + 1)) { + return EINVAL; +} + if (NO_ERROR != ConvertInterfaceAliasToLuid(ifName, &out)) + return EINVAL; + memcpy(luid, &out, sizeof(NET_LUID)); + return 0; +} + +static LONG _flushaddrs(NET_LUID luid, MIB_UNICASTIPADDRESS_TABLE *table) +{ + LONG err = NO_ERROR; + for (int i = 0; i < (int)table->NumEntries; i++) { + if (table->Table[i].InterfaceLuid.Value == luid.Value) { + if ((err = DeleteUnicastIpAddressEntry(&table->Table[i]))) { + return err; + } + } + } + return err; +} + +static int _device_flushaddr(const char *ifname) +{ + LONG ret; + NET_LUID luid; + MIB_UNICASTIPADDRESS_TABLE* table; + + if (_toluid(ifname, &luid)) + return EINVAL; + + if (!GetUnicastIpAddressTable(AF_INET, &table)) + return EINVAL; + + ret = _flushaddrs(luid, table); + FreeMibTable(table); + if (ret) { + DEBUG_WARNING("DeleteUnicastIpAddressEntry(&table->Table[i])"); + return EINVAL; + } + + if (!GetUnicastIpAddressTable(AF_INET6, &table)) { + return EINVAL; + } + ret = _flushaddrs(luid, table); + FreeMibTable(table); + if (ret) { + DEBUG_WARNING("DeleteUnicastIpAddressEntry(&table->Table[i])"); + return EINVAL; + } + return 0; +} + +int net_if_setmtu(const char *ifname, uint32_t mtu) +{ + return 0; +} + +int net_if_setaddr( const char *ifname + , const struct sa *ip + , int prefix_len ) +{ + MIB_UNICASTIPADDRESS_ROW uip = { + .PrefixOrigin = IpPrefixOriginUnchanged, + .SuffixOrigin = IpSuffixOriginUnchanged, + .ValidLifetime = 0xFFFFFFFF, + .PreferredLifetime = 0xFFFFFFFF, + .OnLinkPrefixLength = 0xFF + }; + + _device_flushaddr(ifname); + + if (_toluid(ifname, &uip.InterfaceLuid)) + return EINVAL; + + uip.Address.si_family = ip->u.sa.sa_family; + + switch (ip->u.sa.sa_family) { + case AF_INET6: + memcpy(&uip.Address.Ipv6.sin6_addr, ip->u.in6.sin6_addr.s6_addr, 16); + break; + case AF_INET: + memcpy(&uip.Address.Ipv4.sin_addr, &ip->u.in.sin_addr.s_addr, 4); + break; + default: + return EINVAL; + } + + uip.OnLinkPrefixLength = prefix_len; + + if (!CreateUnicastIpAddressEntry(&uip)){ + return EINVAL; + } + + return 0; +} From 6bd4c879fd8a444eb9d102084041bd30e295b11b Mon Sep 17 00:00:00 2001 From: kristopher tate Date: Tue, 12 Sep 2017 22:03:24 +0900 Subject: [PATCH 06/15] unicode: add pl derivative of utf8_encode; --- include/re_fmt.h | 1 + src/fmt/unicode.c | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/include/re_fmt.h b/include/re_fmt.h index 2878b971..2def52c2 100644 --- a/include/re_fmt.h +++ b/include/re_fmt.h @@ -150,4 +150,5 @@ void fmt_param_apply(const struct pl *pl, fmt_param_h *ph, void *arg); /* unicode */ int utf8_encode(struct re_printf *pf, const char *str); +int utf8_encode_pl(struct re_printf *pf, const struct pl *pl); int utf8_decode(struct re_printf *pf, const struct pl *pl); diff --git a/src/fmt/unicode.c b/src/fmt/unicode.c index e7118359..1439a30d 100644 --- a/src/fmt/unicode.c +++ b/src/fmt/unicode.c @@ -2,6 +2,7 @@ * @file unicode.c Unicode character coding * * Copyright (C) 2010 Creytiv.com + * Copyright (C) 2017 kristopher tate & connectFree Corporation */ #include #include @@ -21,16 +22,28 @@ static const char *hex_chars = "0123456789ABCDEF"; */ int utf8_encode(struct re_printf *pf, const char *str) { + return utf8_encode_pl(pf, &(struct pl){ .p=str + , .l=str_len(str)}); +} + +int utf8_encode_pl(struct re_printf *pf, const struct pl *pl) +{ + struct pl pli; char ubuf[6] = "\\u00", ebuf[2] = "\\"; if (!pf) return EINVAL; - if (!str) + if (!pl) return 0; - while (*str) { - const uint8_t c = *str++; /* NOTE: must be unsigned 8-bit */ + pli.p = pl->p; + pli.l = pl->l; + + while (pli.l) { + const uint8_t c = *(pli.p); /* NOTE: must be unsigned 8-bit */ + pl_advance(&pli, 1); + bool unicode = false; char ec = 0; int err; From b484684fd81f0bacafee326a91308895871e3074 Mon Sep 17 00:00:00 2001 From: kristopher tate Date: Tue, 12 Sep 2017 22:03:46 +0900 Subject: [PATCH 07/15] json: update encode function to play well with pl type; --- src/json/encode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/json/encode.c b/src/json/encode.c index 8df8484d..7801e7a2 100644 --- a/src/json/encode.c +++ b/src/json/encode.c @@ -54,7 +54,7 @@ static int encode_entry(struct re_printf *pf, const struct odict_entry *e) break; case ODICT_STRING: - err = re_hprintf(pf, "\"%H\"", utf8_encode, e->u.pl.p); + err = re_hprintf(pf, "\"%H\"", utf8_encode_pl, &e->u.pl); break; case ODICT_BOOL: From ff4e51ad98366132ac2208a557bc3b7d15548980 Mon Sep 17 00:00:00 2001 From: kristopher tate Date: Wed, 20 Sep 2017 12:38:03 +0900 Subject: [PATCH 08/15] websock: don't trust blind msg; --- src/websock/websock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/websock/websock.c b/src/websock/websock.c index e5edffe6..c2001136 100644 --- a/src/websock/websock.c +++ b/src/websock/websock.c @@ -387,7 +387,7 @@ static void http_resp_handler(int err, const struct http_msg *msg, void *arg) struct pl key; char buf[32]; - if (err || msg->scode != 101) + if (err || !msg || msg->scode != 101) goto fail; if (!http_msg_hdr_has_value(msg, HTTP_HDR_UPGRADE, "websocket")) From 76bcb76fe80a3ea62a9e670800d3fcf9b0208234 Mon Sep 17 00:00:00 2001 From: kristopher tate Date: Wed, 20 Sep 2017 12:39:41 +0900 Subject: [PATCH 09/15] main: catch SIGPIPE for platforms that do not support MSG_NOSIGNAL; --- src/main/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/main.c b/src/main/main.c index b8435532..a496e57f 100644 --- a/src/main/main.c +++ b/src/main/main.c @@ -944,6 +944,7 @@ int re_main(re_signal_h *signalh) (void)signal(SIGINT, signal_handler); (void)signal(SIGALRM, signal_handler); (void)signal(SIGTERM, signal_handler); + (void)signal(SIGPIPE, signal_handler); } #endif From 09650a866521d86a3022719b2d250d49d1c871df Mon Sep 17 00:00:00 2001 From: kristopher tate Date: Mon, 25 Sep 2017 01:34:27 +0900 Subject: [PATCH 10/15] tcp: bind before connect functions; --- include/re_tcp.h | 4 +++ src/tcp/tcp_high.c | 78 +++++++++++++++++++++++++++++++++------------- 2 files changed, 61 insertions(+), 21 deletions(-) diff --git a/include/re_tcp.h b/include/re_tcp.h index 98dba715..c4e713c9 100644 --- a/include/re_tcp.h +++ b/include/re_tcp.h @@ -2,6 +2,7 @@ * @file re_tcp.h Interface to Transport Control Protocol * * Copyright (C) 2010 Creytiv.com + * Copyright (c) 2017 kristopher tate & connectFree Corporation */ struct sa; struct tcp_sock; @@ -79,6 +80,9 @@ size_t tcp_conn_txqsz(const struct tcp_conn *tc); /* High-level API */ int tcp_listen(struct tcp_sock **tsp, const struct sa *local, tcp_conn_h *ch, void *arg); +int tcp_bind_connect(struct tcp_conn **tcp, const struct sa *peer, + const struct sa *bind, tcp_estab_h *eh, tcp_recv_h *rh, + tcp_close_h *ch, void *arg); int tcp_connect(struct tcp_conn **tcp, const struct sa *peer, tcp_estab_h *eh, tcp_recv_h *rh, tcp_close_h *ch, void *arg); int tcp_local_get(const struct tcp_sock *ts, struct sa *local); diff --git a/src/tcp/tcp_high.c b/src/tcp/tcp_high.c index 7dd9d48b..d48f98e0 100644 --- a/src/tcp/tcp_high.c +++ b/src/tcp/tcp_high.c @@ -2,6 +2,7 @@ * @file tcp_high.c High-level TCP functions * * Copyright (C) 2010 Creytiv.com + * Copyright (c) 2017 kristopher tate & connectFree Corporation */ #include #include @@ -49,12 +50,12 @@ int tcp_listen(struct tcp_sock **tsp, const struct sa *local, return err; } - /** * Make a TCP Connection to a remote peer * * @param tcp Returned TCP Connection object * @param peer Network address of peer + * @param peer Network address to bind to * @param eh TCP Connection Established handler * @param rh TCP Connection Receive data handler * @param ch TCP Connection close handler @@ -62,30 +63,65 @@ int tcp_listen(struct tcp_sock **tsp, const struct sa *local, * * @return 0 if success, otherwise errorcode */ -int tcp_connect(struct tcp_conn **tcp, const struct sa *peer, - tcp_estab_h *eh, tcp_recv_h *rh, tcp_close_h *ch, void *arg) +int tcp_bind_connect( struct tcp_conn **tcp + , const struct sa *peer + , const struct sa *bind + , tcp_estab_h *eh + , tcp_recv_h *rh + , tcp_close_h *ch + , void *arg ) { - struct tcp_conn *tc = NULL; - int err; - - if (!tcp || !peer) - return EINVAL; - - err = tcp_conn_alloc(&tc, peer, eh,rh, ch, arg); - if (err) - goto out; - - err = tcp_conn_connect(tc, peer); - if (err) - goto out; + struct tcp_conn *tc = NULL; + int err; + + if (!tcp || !peer) + return EINVAL; + + err = tcp_conn_alloc(&tc, peer, eh,rh, ch, arg); + if (err) + goto out; + + if (bind) { + err = tcp_conn_bind(tc, bind); + if (err) + goto out; + } + + err = tcp_conn_connect(tc, peer); + if (err) + goto out; out: - if (err) - tc = mem_deref(tc); - else - *tcp = tc; + if (err) + tc = mem_deref(tc); + else + *tcp = tc; - return err; + return err; +} + +/** + * Make a TCP Connection to a remote peer (API compatibility) + * + * @param tcp Returned TCP Connection object + * @param peer Network address of peer + * @param eh TCP Connection Established handler + * @param rh TCP Connection Receive data handler + * @param ch TCP Connection close handler + * @param arg Handler argument + * + * @return 0 if success, otherwise errorcode + */ +int tcp_connect(struct tcp_conn **tcp, const struct sa *peer, + tcp_estab_h *eh, tcp_recv_h *rh, tcp_close_h *ch, void *arg) +{ + return tcp_bind_connect( tcp + , peer + , NULL + , eh + , rh + , ch + , arg ); } From 7afde1640b94b77b1061ee3adc78c81f167a6ba7 Mon Sep 17 00:00:00 2001 From: kristopher tate Date: Mon, 25 Sep 2017 01:35:10 +0900 Subject: [PATCH 11/15] http_client: address binding for clients; --- include/re_http.h | 3 +++ src/http/client.c | 53 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/include/re_http.h b/include/re_http.h index 58195f6a..738c0a47 100644 --- a/include/re_http.h +++ b/include/re_http.h @@ -2,6 +2,7 @@ * @file re_http.h Hypertext Transfer Protocol * * Copyright (C) 2010 Creytiv.com + * Copyright (c) 2017 kristopher tate & connectFree Corporation */ @@ -119,6 +120,8 @@ typedef void (http_resp_h)(int err, const struct http_msg *msg, void *arg); typedef void (http_data_h)(struct mbuf *mb, void *arg); int http_client_alloc(struct http_cli **clip, struct dnsc *dnsc); +int http_client_bind(struct http_cli *cli, const struct sa *local); +const struct sa *http_client_bound(struct http_cli *cli); int http_request(struct http_req **reqp, struct http_cli *cli, const char *met, const char *uri, http_resp_h *resph, http_data_h *datah, void *arg, const char *fmt, ...); diff --git a/src/http/client.c b/src/http/client.c index 8abec92e..0da419ed 100644 --- a/src/http/client.c +++ b/src/http/client.c @@ -34,6 +34,7 @@ struct http_cli { struct hash *ht_conn; struct dnsc *dnsc; struct tls *tls; + struct sa bind; }; struct conn; @@ -389,8 +390,14 @@ static int conn_connect(struct http_req *req) conn->addr = *addr; conn->usec = 1; - err = tcp_connect(&conn->tc, addr, estab_handler, recv_handler, - close_handler, conn); + err = tcp_bind_connect( &conn->tc + , addr + , (sa_isset(&req->cli->bind, SA_ADDR) ? &req->cli->bind + : NULL) + , estab_handler + , recv_handler + , close_handler + , conn); if (err) goto out; @@ -643,6 +650,48 @@ int http_client_alloc(struct http_cli **clip, struct dnsc *dnsc) return err; } +/** + * Bind an HTTP client instance to a local address + * + * @param cli HTTP client instance + * @param local Bindable network address + * + * @return 0 if success, otherwise errorcode + */ +int http_client_bind(struct http_cli *cli, const struct sa *local) +{ + int err = 0; + + if (!cli) + return EINVAL; + + if (local) { + sa_cpy(&cli->bind, local); + } else { + sa_init(&cli->bind, 0); + } + + return err; +} + +/** + * Get the bound address for an HTTP client instance + * + * @param cli HTTP client instance + * + * @return 0 if success, otherwise errorcode + */ +const struct sa *http_client_bound(struct http_cli *cli) +{ + if (!cli) + return NULL; + + if (sa_isset(&cli->bind, SA_ADDR)) { + return &cli->bind; + } + + return NULL; +} struct tcp_conn *http_req_tcp(struct http_req *req) { From a315f23582763a283dbd709e4e6befd48cb27058 Mon Sep 17 00:00:00 2001 From: kristopher tate Date: Fri, 29 Sep 2017 03:18:32 +0900 Subject: [PATCH 12/15] dns: make dns bindable; --- include/re_dns.h | 3 +++ src/dns/client.c | 25 +++++++++++++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/include/re_dns.h b/include/re_dns.h index 73ecd08a..329d69a4 100644 --- a/include/re_dns.h +++ b/include/re_dns.h @@ -2,6 +2,7 @@ * @file re_dns.h Interface to DNS module * * Copyright (C) 2010 Creytiv.com + * Copyright (C) 2017 kristopher tate & connectFree Corporation */ @@ -198,6 +199,8 @@ struct dnsc_conf { uint32_t idle_timeout; /* in [ms] */ }; +int dnsc_alloc_bind(struct dnsc **dcpp, const struct dnsc_conf *conf, + const struct sa *local, const struct sa *srvv, uint32_t srvc); int dnsc_alloc(struct dnsc **dcpp, const struct dnsc_conf *conf, const struct sa *srvv, uint32_t srvc); int dnsc_srv_set(struct dnsc *dnsc, const struct sa *srvv, uint32_t srvc); diff --git a/src/dns/client.c b/src/dns/client.c index 9535e07d..ff34813f 100644 --- a/src/dns/client.c +++ b/src/dns/client.c @@ -2,6 +2,7 @@ * @file dns/client.c DNS Client * * Copyright (C) 2010 Creytiv.com + * Copyright (C) 2017 kristopher tate & connectFree Corporation */ #include #include @@ -825,17 +826,18 @@ static void dnsc_destructor(void *data) /** - * Allocate a DNS Client + * Allocate a Bindable DNS Client * * @param dcpp Pointer to allocated DNS Client * @param conf Optional DNS configuration, NULL for default + * @param local Local network address * @param srvv DNS servers * @param srvc Number of DNS Servers * * @return 0 if success, otherwise errorcode */ -int dnsc_alloc(struct dnsc **dcpp, const struct dnsc_conf *conf, - const struct sa *srvv, uint32_t srvc) +int dnsc_alloc_bind(struct dnsc **dcpp, const struct dnsc_conf *conf, + const struct sa *local, const struct sa *srvv, uint32_t srvc) { struct dnsc *dnsc; int err; @@ -856,7 +858,7 @@ int dnsc_alloc(struct dnsc **dcpp, const struct dnsc_conf *conf, if (err) goto out; - err = udp_listen(&dnsc->us, NULL, udp_recv_handler, dnsc); + err = udp_listen(&dnsc->us, local, udp_recv_handler, dnsc); if (err) goto out; @@ -877,6 +879,21 @@ int dnsc_alloc(struct dnsc **dcpp, const struct dnsc_conf *conf, return err; } +/** + * Allocate a DNS Client + * + * @param dcpp Pointer to allocated DNS Client + * @param conf Optional DNS configuration, NULL for default + * @param srvv DNS servers + * @param srvc Number of DNS Servers + * + * @return 0 if success, otherwise errorcode + */ +int dnsc_alloc(struct dnsc **dcpp, const struct dnsc_conf *conf, + const struct sa *srvv, uint32_t srvc) +{ + return dnsc_alloc_bind(dcpp, conf, NULL, srvv, srvc); +} /** * Set the DNS Servers on a DNS Client From 6060debd0849503d08017fca8c8cabf557494278 Mon Sep 17 00:00:00 2001 From: kristopher tate Date: Mon, 2 Oct 2017 02:27:02 +0900 Subject: [PATCH 13/15] mcast.c: require index for mcast; --- include/re_udp.h | 4 ++-- src/udp/mcast.c | 15 +++++++++------ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/include/re_udp.h b/include/re_udp.h index c7f8fd9b..ff572b05 100644 --- a/include/re_udp.h +++ b/include/re_udp.h @@ -43,8 +43,8 @@ int udp_thread_attach(struct udp_sock *us); void udp_thread_detach(struct udp_sock *us); int udp_sock_fd(const struct udp_sock *us, int af); -int udp_multicast_join(struct udp_sock *us, const struct sa *group); -int udp_multicast_leave(struct udp_sock *us, const struct sa *group); +int udp_multicast_join(struct udp_sock *us, const struct sa *group, unsigned int index); +int udp_multicast_leave(struct udp_sock *us, const struct sa *group, unsigned int index); /* Helper API */ diff --git a/src/udp/mcast.c b/src/udp/mcast.c index 327257a3..d148b334 100644 --- a/src/udp/mcast.c +++ b/src/udp/mcast.c @@ -2,6 +2,7 @@ * @file mcast.c UDP Multicast * * Copyright (C) 2010 Creytiv.com + * Copyright (C) 2017 kristopher tate & connectFree Corporation */ #define _BSD_SOURCE 1 @@ -13,7 +14,7 @@ static int multicast_update(struct udp_sock *us, const struct sa *group, - bool join) + bool join, unsigned int index) { struct ip_mreq mreq; #ifdef HAVE_INET6 @@ -40,7 +41,7 @@ static int multicast_update(struct udp_sock *us, const struct sa *group, #ifdef HAVE_INET6 case AF_INET6: mreq6.ipv6mr_multiaddr = group->u.in6.sin6_addr; - mreq6.ipv6mr_interface = 0; + mreq6.ipv6mr_interface = index; err = udp_setsockopt(us, IPPROTO_IPV6, join @@ -58,13 +59,15 @@ static int multicast_update(struct udp_sock *us, const struct sa *group, } -int udp_multicast_join(struct udp_sock *us, const struct sa *group) +int udp_multicast_join( struct udp_sock *us, const struct sa *group + , unsigned int index ) { - return multicast_update(us, group, true); + return multicast_update(us, group, true, index); } -int udp_multicast_leave(struct udp_sock *us, const struct sa *group) +int udp_multicast_leave(struct udp_sock *us, const struct sa *group + , unsigned int index ) { - return multicast_update(us, group, false); + return multicast_update(us, group, false, index); } From a55824581062ecbe81e1f8ab9c913853726a58fc Mon Sep 17 00:00:00 2001 From: kristopher tate Date: Mon, 2 Oct 2017 03:50:33 +0900 Subject: [PATCH 14/15] win32/wif.c: up address buffer; sometimes we may get back error 111 (ERROR_BUFFER_OVERFLOW) which we should perhaps handle in the future; --- src/net/win32/wif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/net/win32/wif.c b/src/net/win32/wif.c index 74d03fd7..f24894f5 100644 --- a/src/net/win32/wif.c +++ b/src/net/win32/wif.c @@ -24,7 +24,7 @@ */ static int if_list_gaa(net_ifaddr_h *ifh, void *arg) { - IP_ADAPTER_ADDRESSES addrv[16], *cur; + IP_ADAPTER_ADDRESSES addrv[64], *cur; ULONG ret, len = sizeof(addrv); const ULONG flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST; HANDLE hLib; From 7fdb90c1c9f277ce949224557263b7a747cbfc77 Mon Sep 17 00:00:00 2001 From: kristopher tate Date: Mon, 2 Oct 2017 03:51:41 +0900 Subject: [PATCH 15/15] tcp.c: handle windows error cases; --- src/tcp/tcp.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/tcp/tcp.c b/src/tcp/tcp.c index 68dc2d68..f1ed4b8e 100644 --- a/src/tcp/tcp.c +++ b/src/tcp/tcp.c @@ -2,6 +2,7 @@ * @file tcp.c Transport Control Protocol * * Copyright (C) 2010 Creytiv.com + * Copyright (C) 2017 kristopher tate & connectFree Corporation */ #include #ifdef HAVE_UNISTD_H @@ -378,6 +379,33 @@ static void tcp_recv_handler(int flags, void *arg) } else if (n < 0) { DEBUG_WARNING("recv handler: recv(): %m\n", errno); +#ifdef WIN32 + /* Special error handling for Windows */ + switch (WSAGetLastError()) { + case WSAENETDOWN: + /*@FALLTHROUGH@*/ + case WSAEFAULT: + /*@FALLTHROUGH@*/ + case WSAENOTCONN: + /*@FALLTHROUGH@*/ + case WSAEINTR: + /*@FALLTHROUGH@*/ + case WSAENOTSOCK: + /*@FALLTHROUGH@*/ + case WSAESHUTDOWN: + /*@FALLTHROUGH@*/ + case WSAEINVAL: + /*@FALLTHROUGH@*/ + case WSAECONNABORTED: + /*@FALLTHROUGH@*/ + case WSAETIMEDOUT: + /*@FALLTHROUGH@*/ + case WSAECONNRESET: + conn_close(tc, errno); + default: + break; + } +#endif goto out; }