From: Guus Sliepen Date: Sat, 7 Oct 2017 15:50:22 +0000 (+0200) Subject: Reformat all code using astyle. X-Git-Tag: release-1.1pre16~63 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=f6e87ab476a0faf8b124ecaaa27f967d825e6457;p=oweals%2Ftinc.git Reformat all code using astyle. --- diff --git a/src/autoconnect.c b/src/autoconnect.c index e97a33c..8adb74f 100644 --- a/src/autoconnect.c +++ b/src/autoconnect.c @@ -27,23 +27,29 @@ static void make_new_connection() { /* Select a random node we haven't connected to yet. */ int count = 0; + for splay_each(node_t, n, node_tree) { - if(n == myself || n->connection || !(n->status.has_address || n->status.reachable)) + if(n == myself || n->connection || !(n->status.has_address || n->status.reachable)) { continue; + } + count++; } - if(!count) + if(!count) { return; + } int r = rand() % count; for splay_each(node_t, n, node_tree) { - if(n == myself || n->connection || !(n->status.has_address || n->status.reachable)) + if(n == myself || n->connection || !(n->status.has_address || n->status.reachable)) { continue; + } - if(r--) + if(r--) { continue; + } bool found = false; @@ -77,17 +83,20 @@ static void connect_to_unreachable() { int r = rand() % node_tree->count; for splay_each(node_t, n, node_tree) { - if(r--) + if(r--) { continue; + } /* Is it unreachable and do we know an address for it? If not, return. */ - if(n == myself || n->connection || n->status.reachable || !n->status.has_address) + if(n == myself || n->connection || n->status.reachable || !n->status.has_address) { return; + } /* Are we already trying to make an outgoing connection to it? If not, return. */ for list_each(outgoing_t, outgoing, outgoing_list) - if(!strcmp(outgoing->name, n->name)) + if(!strcmp(outgoing->name, n->name)) { return; + } logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name); outgoing_t *outgoing = xzalloc(sizeof(*outgoing)); @@ -102,23 +111,29 @@ static void connect_to_unreachable() { static void drop_superfluous_outgoing_connection() { /* Choose a random outgoing connection to a node that has at least one other connection. */ int count = 0; + for list_each(connection_t, c, connection_list) { - if(!c->edge || !c->outgoing || !c->node || c->node->edge_tree->count < 2) + if(!c->edge || !c->outgoing || !c->node || c->node->edge_tree->count < 2) { continue; + } + count++; } - if(!count) + if(!count) { return; + } int r = rand() % count; for list_each(connection_t, c, connection_list) { - if(!c->edge || !c->outgoing || !c->node || c->node->edge_tree->count < 2) + if(!c->edge || !c->outgoing || !c->node || c->node->edge_tree->count < 2) { continue; - - if(r--) + } + + if(r--) { continue; + } logger(DEBUG_CONNECTIONS, LOG_INFO, "Autodisconnecting from %s", c->name); list_delete(outgoing_list, c->outgoing); @@ -132,6 +147,7 @@ static void drop_superfluous_pending_connections() { for list_each(outgoing_t, o, outgoing_list) { /* Only look for connections that are waiting to be retried later. */ bool found = false; + for list_each(connection_t, c, connection_list) { if(c->outgoing == o) { found = true; @@ -139,8 +155,9 @@ static void drop_superfluous_pending_connections() { } } - if(found) + if(found) { continue; + } logger(DEBUG_CONNECTIONS, LOG_INFO, "Cancelled outgoing connection to %s", o->name); list_delete_node(outgoing_list, node); @@ -150,9 +167,11 @@ static void drop_superfluous_pending_connections() { void do_autoconnect() { /* Count number of active connections. */ int nc = 0; + for list_each(connection_t, c, connection_list) { - if(c->edge) + if(c->edge) { nc++; + } } /* Less than 3 connections? Eagerly try to make a new one. */ @@ -160,10 +179,11 @@ void do_autoconnect() { make_new_connection(); return; } - + /* More than 3 connections? See if we can get rid of a superfluous one. */ - if(nc > 3) + if(nc > 3) { drop_superfluous_outgoing_connection(); + } /* Check if there are unreachable nodes that we should try to connect to. */ diff --git a/src/bsd/device.c b/src/bsd/device.c index ec088a4..6d68bc7 100644 --- a/src/bsd/device.c +++ b/src/bsd/device.c @@ -68,12 +68,14 @@ static device_type_t device_type = DEVICE_TYPE_TUN; #ifdef HAVE_NET_IF_UTUN_H static bool setup_utun(void) { device_fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL); + if(device_fd == -1) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not open PF_SYSTEM socket: %s\n", strerror(errno)); return false; } struct ctl_info info = {}; + strlcpy(info.ctl_name, UTUN_CONTROL_NAME, sizeof(info.ctl_name)); if(ioctl(device_fd, CTLIOCGINFO, &info) == -1) { @@ -83,10 +85,13 @@ static bool setup_utun(void) { int unit = -1; char *p = strstr(device, "utun"), *e = NULL; + if(p) { unit = strtol(p + 4, &e, 10); - if(!e) + + if(!e) { unit = -1; + } } struct sockaddr_ctl sc = { @@ -104,6 +109,7 @@ static bool setup_utun(void) { char name[64] = ""; socklen_t len = sizeof(name); + if(getsockopt(device_fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, name, &len)) { iface = xstrdup(device); } else { @@ -124,35 +130,43 @@ static bool setup_device(void) { // Find out if it's supposed to be a tun or a tap device char *type; + if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) { if(!strcasecmp(type, "tun")) /* use default */; + #ifdef ENABLE_TUNEMU - else if(!strcasecmp(type, "tunemu")) + else if(!strcasecmp(type, "tunemu")) { device_type = DEVICE_TYPE_TUNEMU; + } + #endif #ifdef HAVE_NET_IF_UTUN_H - else if(!strcasecmp(type, "utun")) + else if(!strcasecmp(type, "utun")) { device_type = DEVICE_TYPE_UTUN; + } + #endif - else if(!strcasecmp(type, "tunnohead")) + else if(!strcasecmp(type, "tunnohead")) { device_type = DEVICE_TYPE_TUN; - else if(!strcasecmp(type, "tunifhead")) + } else if(!strcasecmp(type, "tunifhead")) { device_type = DEVICE_TYPE_TUNIFHEAD; - else if(!strcasecmp(type, "tap")) + } else if(!strcasecmp(type, "tap")) { device_type = DEVICE_TYPE_TAP; - else { + } else { logger(DEBUG_ALWAYS, LOG_ERR, "Unknown device type %s!", type); return false; } } else { #ifdef HAVE_NET_IF_UTUN_H - if(device && (strncmp(device, "utun", 4) == 0 || strncmp(device, "/dev/utun", 9) == 0)) + + if(device && (strncmp(device, "utun", 4) == 0 || strncmp(device, "/dev/utun", 9) == 0)) { device_type = DEVICE_TYPE_UTUN; - else + } else #endif - if((device && strstr(device, "tap")) || routing_mode != RMODE_ROUTER) - device_type = DEVICE_TYPE_TAP; + if((device && strstr(device, "tap")) || routing_mode != RMODE_ROUTER) { + device_type = DEVICE_TYPE_TAP; + } } if(routing_mode == RMODE_SWITCH && device_type != DEVICE_TYPE_TAP) { @@ -163,28 +177,32 @@ static bool setup_device(void) { // Find out which device file to open if(!device) { - if(device_type == DEVICE_TYPE_TAP) + if(device_type == DEVICE_TYPE_TAP) { device = xstrdup(DEFAULT_TAP_DEVICE); - else + } else { device = xstrdup(DEFAULT_TUN_DEVICE); + } } // Open the device switch(device_type) { #ifdef ENABLE_TUNEMU - case DEVICE_TYPE_TUNEMU: { - char dynamic_name[256] = ""; - device_fd = tunemu_open(dynamic_name); - } - break; + + case DEVICE_TYPE_TUNEMU: { + char dynamic_name[256] = ""; + device_fd = tunemu_open(dynamic_name); + } + break; #endif #ifdef HAVE_NET_IF_UTUN_H - case DEVICE_TYPE_UTUN: - return setup_utun(); + + case DEVICE_TYPE_UTUN: + return setup_utun(); #endif - default: - device_fd = open(device, O_RDWR | O_NONBLOCK); + + default: + device_fd = open(device, O_RDWR | O_NONBLOCK); } if(device_fd < 0) { @@ -204,32 +222,40 @@ static bool setup_device(void) { realname = fdevname(device_fd); #elif defined(HAVE_DEVNAME) struct stat buf; - if(!fstat(device_fd, &buf)) + + if(!fstat(device_fd, &buf)) { realname = devname(buf.st_rdev, S_IFCHR); + } + #endif - if(!realname) + if(!realname) { realname = device; + } - if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) + if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) { iface = xstrdup(strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname); - else if(strcmp(iface, strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname)) + } else if(strcmp(iface, strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname)) { logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: Interface does not match Device. $INTERFACE might be set incorrectly."); + } // Configure the device as best as we can switch(device_type) { - default: - device_type = DEVICE_TYPE_TUN; - case DEVICE_TYPE_TUN: + default: + device_type = DEVICE_TYPE_TUN; + + case DEVICE_TYPE_TUN: #ifdef TUNSIFHEAD { const int zero = 0; + if(ioctl(device_fd, TUNSIFHEAD, &zero, sizeof(zero)) == -1) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno)); return false; } } + #endif #if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST) { @@ -238,53 +264,66 @@ static bool setup_device(void) { } #endif - device_info = "Generic BSD tun device"; - break; - case DEVICE_TYPE_TUNIFHEAD: + device_info = "Generic BSD tun device"; + break; + + case DEVICE_TYPE_TUNIFHEAD: #ifdef TUNSIFHEAD { const int one = 1; + if(ioctl(device_fd, TUNSIFHEAD, &one, sizeof(one)) == -1) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno)); return false; } } + #endif #if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST) { - const int mode = IFF_BROADCAST | IFF_MULTICAST; - ioctl(device_fd, TUNSIFMODE, &mode, sizeof(mode)); + const int mode = IFF_BROADCAST | IFF_MULTICAST; + ioctl(device_fd, TUNSIFMODE, &mode, sizeof(mode)); } #endif - device_info = "Generic BSD tun device"; - break; - case DEVICE_TYPE_TAP: - if(routing_mode == RMODE_ROUTER) - overwrite_mac = true; - device_info = "Generic BSD tap device"; + device_info = "Generic BSD tun device"; + break; + + case DEVICE_TYPE_TAP: + if(routing_mode == RMODE_ROUTER) { + overwrite_mac = true; + } + + device_info = "Generic BSD tap device"; #ifdef TAPGIFNAME - { - struct ifreq ifr; - if(ioctl(device_fd, TAPGIFNAME, (void*)&ifr) == 0) { - if(iface) - free(iface); - iface = xstrdup(ifr.ifr_name); + { + struct ifreq ifr; + + if(ioctl(device_fd, TAPGIFNAME, (void *)&ifr) == 0) { + if(iface) { + free(iface); } + + iface = xstrdup(ifr.ifr_name); } + } #endif - break; + break; #ifdef ENABLE_TUNEMU - case DEVICE_TYPE_TUNEMU: - device_info = "BSD tunemu device"; - break; + + case DEVICE_TYPE_TUNEMU: + device_info = "BSD tunemu device"; + break; #endif } #ifdef SIOCGIFADDR - if(overwrite_mac) + + if(overwrite_mac) { ioctl(device_fd, SIOCGIFADDR, mymac.x); + } + #endif logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); @@ -295,17 +334,22 @@ static bool setup_device(void) { static void close_device(void) { switch(device_type) { #ifdef ENABLE_TUNEMU - case DEVICE_TYPE_TUNEMU: - tunemu_close(device_fd); - break; + + case DEVICE_TYPE_TUNEMU: + tunemu_close(device_fd); + break; #endif - default: - close(device_fd); + + default: + close(device_fd); } + device_fd = -1; - free(device); device = NULL; - free(iface); iface = NULL; + free(device); + device = NULL; + free(iface); + iface = NULL; device_info = NULL; } @@ -313,154 +357,163 @@ static bool read_packet(vpn_packet_t *packet) { int inlen; switch(device_type) { - case DEVICE_TYPE_TUN: + case DEVICE_TYPE_TUN: #ifdef ENABLE_TUNEMU - case DEVICE_TYPE_TUNEMU: - if(device_type == DEVICE_TYPE_TUNEMU) - inlen = tunemu_read(device_fd, DATA(packet) + 14, MTU - 14); - else + case DEVICE_TYPE_TUNEMU: + if(device_type == DEVICE_TYPE_TUNEMU) { + inlen = tunemu_read(device_fd, DATA(packet) + 14, MTU - 14); + } else #endif - inlen = read(device_fd, DATA(packet) + 14, MTU - 14); + inlen = read(device_fd, DATA(packet) + 14, MTU - 14); - if(inlen <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - return false; - } + if(inlen <= 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, + device, strerror(errno)); + return false; + } - switch(DATA(packet)[14] >> 4) { - case 4: - DATA(packet)[12] = 0x08; - DATA(packet)[13] = 0x00; - break; - case 6: - DATA(packet)[12] = 0x86; - DATA(packet)[13] = 0xDD; - break; - default: - logger(DEBUG_TRAFFIC, LOG_ERR, - "Unknown IP version %d while reading packet from %s %s", - DATA(packet)[14] >> 4, device_info, device); - return false; - } + switch(DATA(packet)[14] >> 4) { + case 4: + DATA(packet)[12] = 0x08; + DATA(packet)[13] = 0x00; + break; - memset(DATA(packet), 0, 12); - packet->len = inlen + 14; + case 6: + DATA(packet)[12] = 0x86; + DATA(packet)[13] = 0xDD; break; - case DEVICE_TYPE_UTUN: - case DEVICE_TYPE_TUNIFHEAD: { - if((inlen = read(device_fd, DATA(packet) + 10, MTU - 10)) <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - return false; - } + default: + logger(DEBUG_TRAFFIC, LOG_ERR, + "Unknown IP version %d while reading packet from %s %s", + DATA(packet)[14] >> 4, device_info, device); + return false; + } - switch (DATA(packet)[14] >> 4) { - case 4: - DATA(packet)[12] = 0x08; - DATA(packet)[13] = 0x00; - break; - - case 6: - DATA(packet)[12] = 0x86; - DATA(packet)[13] = 0xDD; - break; - - default: - logger(DEBUG_TRAFFIC, LOG_ERR, - "Unknown IP version %d while reading packet from %s %s", - DATA(packet)[14] >> 4, device_info, device); - return false; - } + memset(DATA(packet), 0, 12); + packet->len = inlen + 14; + break; - memset(DATA(packet), 0, 12); - packet->len = inlen + 10; - break; + case DEVICE_TYPE_UTUN: + case DEVICE_TYPE_TUNIFHEAD: { + if((inlen = read(device_fd, DATA(packet) + 10, MTU - 10)) <= 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, + device, strerror(errno)); + return false; } - case DEVICE_TYPE_TAP: - if((inlen = read(device_fd, DATA(packet), MTU)) <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - return false; - } + switch(DATA(packet)[14] >> 4) { + case 4: + DATA(packet)[12] = 0x08; + DATA(packet)[13] = 0x00; + break; - packet->len = inlen; + case 6: + DATA(packet)[12] = 0x86; + DATA(packet)[13] = 0xDD; break; default: + logger(DEBUG_TRAFFIC, LOG_ERR, + "Unknown IP version %d while reading packet from %s %s", + DATA(packet)[14] >> 4, device_info, device); return false; + } + + memset(DATA(packet), 0, 12); + packet->len = inlen + 10; + break; + } + + case DEVICE_TYPE_TAP: + if((inlen = read(device_fd, DATA(packet), MTU)) <= 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, + device, strerror(errno)); + return false; + } + + packet->len = inlen; + break; + + default: + return false; } logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", - packet->len, device_info); + packet->len, device_info); return true; } static bool write_packet(vpn_packet_t *packet) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + packet->len, device_info); switch(device_type) { - case DEVICE_TYPE_TUN: - if(write(device_fd, DATA(packet) + 14, packet->len - 14) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, - device, strerror(errno)); - return false; - } - break; + case DEVICE_TYPE_TUN: + if(write(device_fd, DATA(packet) + 14, packet->len - 14) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, + device, strerror(errno)); + return false; + } - case DEVICE_TYPE_UTUN: - case DEVICE_TYPE_TUNIFHEAD: { - int af = (DATA(packet)[12] << 8) + DATA(packet)[13]; - uint32_t type; - - switch (af) { - case 0x0800: - type = htonl(AF_INET); - break; - case 0x86DD: - type = htonl(AF_INET6); - break; - default: - logger(DEBUG_TRAFFIC, LOG_ERR, - "Unknown address family %x while writing packet to %s %s", - af, device_info, device); - return false; - } + break; - memcpy(DATA(packet) + 10, &type, sizeof(type)); + case DEVICE_TYPE_UTUN: + case DEVICE_TYPE_TUNIFHEAD: { + int af = (DATA(packet)[12] << 8) + DATA(packet)[13]; + uint32_t type; - if(write(device_fd, DATA(packet) + 10, packet->len - 10) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, - strerror(errno)); - return false; - } + switch(af) { + case 0x0800: + type = htonl(AF_INET); break; - } - case DEVICE_TYPE_TAP: - if(write(device_fd, DATA(packet), packet->len) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, - device, strerror(errno)); - return false; - } + case 0x86DD: + type = htonl(AF_INET6); break; + default: + logger(DEBUG_TRAFFIC, LOG_ERR, + "Unknown address family %x while writing packet to %s %s", + af, device_info, device); + return false; + } + + memcpy(DATA(packet) + 10, &type, sizeof(type)); + + if(write(device_fd, DATA(packet) + 10, packet->len - 10) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, + strerror(errno)); + return false; + } + + break; + } + + case DEVICE_TYPE_TAP: + if(write(device_fd, DATA(packet), packet->len) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, + device, strerror(errno)); + return false; + } + + break; + #ifdef ENABLE_TUNEMU - case DEVICE_TYPE_TUNEMU: - if(tunemu_write(device_fd, DATA(packet) + 14, packet->len - 14) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, - device, strerror(errno)); - return false; - } - break; -#endif - default: + case DEVICE_TYPE_TUNEMU: + if(tunemu_write(device_fd, DATA(packet) + 14, packet->len - 14) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, + device, strerror(errno)); return false; + } + + break; +#endif + + default: + return false; } return true; diff --git a/src/bsd/tunemu.c b/src/bsd/tunemu.c index 6d5dd1a..2248264 100644 --- a/src/bsd/tunemu.c +++ b/src/bsd/tunemu.c @@ -49,24 +49,21 @@ #define PPPIOCCONNECT _IOW('t', 58, int) #define PPPIOCGUNIT _IOR('t', 86, int) -struct sockaddr_ppp -{ +struct sockaddr_ppp { u_int8_t ppp_len; u_int8_t ppp_family; u_int16_t ppp_proto; u_int32_t ppp_cookie; }; -enum NPmode -{ +enum NPmode { NPMODE_PASS, - NPMODE_DROP, - NPMODE_ERROR, - NPMODE_QUEUE + NPMODE_DROP, + NPMODE_ERROR, + NPMODE_QUEUE }; -struct npioctl -{ +struct npioctl { int protocol; enum NPmode mode; }; @@ -83,58 +80,55 @@ static pcap_t *pcap = NULL; static int data_buffer_length = 0; static char *data_buffer = NULL; -static void tun_error(char *format, ...) -{ +static void tun_error(char *format, ...) { va_list vl; va_start(vl, format); vsnprintf(tunemu_error, sizeof(tunemu_error), format, vl); va_end(vl); } -static void tun_noerror() -{ +static void tun_noerror() { *tunemu_error = 0; } -static void closeall() -{ - int fd = getdtablesize(); - while (fd--) +static void closeall() { + int fd = getdtablesize(); + + while(fd--) { close(fd); + } - open("/dev/null", O_RDWR, 0); - dup(0); - dup(0); + open("/dev/null", O_RDWR, 0); + dup(0); + dup(0); } -static int ppp_load_kext() -{ +static int ppp_load_kext() { int pid = fork(); - if (pid < 0) - { + + if(pid < 0) { tun_error("fork for ppp kext: %s", strerror(errno)); return -1; } - if (pid == 0) - { + if(pid == 0) { closeall(); execle("/sbin/kextload", "kextload", PPP_KEXT_PATH, NULL, NULL); exit(1); } int status; - while (waitpid(pid, &status, 0) < 0) - { - if (errno == EINTR) + + while(waitpid(pid, &status, 0) < 0) { + if(errno == EINTR) { continue; + } tun_error("waitpid for ppp kext: %s", strerror(errno)); return -1; } - if (WEXITSTATUS(status) != 0) - { + if(WEXITSTATUS(status) != 0) { tun_error("could not load ppp kext \"%s\"", PPP_KEXT_PATH); return -1; } @@ -143,74 +137,73 @@ static int ppp_load_kext() return 0; } -static int ppp_new_instance() -{ +static int ppp_new_instance() { // create ppp socket - int ppp_sockfd = socket(PF_PPP, SOCK_RAW, PPPPROTO_CTL); - if (ppp_sockfd < 0) - { - if (ppp_load_kext() < 0) + int ppp_sockfd = socket(PF_PPP, SOCK_RAW, PPPPROTO_CTL); + + if(ppp_sockfd < 0) { + if(ppp_load_kext() < 0) { return -1; + } ppp_sockfd = socket(PF_PPP, SOCK_RAW, PPPPROTO_CTL); - if (ppp_sockfd < 0) - { + + if(ppp_sockfd < 0) { tun_error("creating ppp socket: %s", strerror(errno)); return -1; } } // connect to ppp procotol - struct sockaddr_ppp pppaddr; - pppaddr.ppp_len = sizeof(struct sockaddr_ppp); - pppaddr.ppp_family = AF_PPP; - pppaddr.ppp_proto = PPPPROTO_CTL; - pppaddr.ppp_cookie = 0; - if (connect(ppp_sockfd, (struct sockaddr *)&pppaddr, sizeof(struct sockaddr_ppp)) < 0) - { + struct sockaddr_ppp pppaddr; + pppaddr.ppp_len = sizeof(struct sockaddr_ppp); + pppaddr.ppp_family = AF_PPP; + pppaddr.ppp_proto = PPPPROTO_CTL; + pppaddr.ppp_cookie = 0; + + if(connect(ppp_sockfd, (struct sockaddr *)&pppaddr, sizeof(struct sockaddr_ppp)) < 0) { tun_error("connecting ppp socket: %s", strerror(errno)); close(ppp_sockfd); return -1; - } + } tun_noerror(); return ppp_sockfd; } -static int ppp_new_unit(int *unit_number) -{ +static int ppp_new_unit(int *unit_number) { int fd = ppp_new_instance(); - if (fd < 0) + + if(fd < 0) { return -1; + } // create ppp unit - if (ioctl(fd, PPPIOCNEWUNIT, unit_number) < 0) - { + if(ioctl(fd, PPPIOCNEWUNIT, unit_number) < 0) { tun_error("creating ppp unit: %s", strerror(errno)); close(fd); return -1; - } + } tun_noerror(); return fd; } -static int ppp_setup_unit(int unit_fd) -{ +static int ppp_setup_unit(int unit_fd) { // send traffic to program int flags = SC_LOOP_TRAFFIC; - if (ioctl(unit_fd, PPPIOCSFLAGS, &flags) < 0) - { + + if(ioctl(unit_fd, PPPIOCSFLAGS, &flags) < 0) { tun_error("setting ppp loopback mode: %s", strerror(errno)); return -1; - } + } // allow packets struct npioctl npi; npi.protocol = PPP_IP; npi.mode = NPMODE_PASS; - if (ioctl(unit_fd, PPPIOCSNPMODE, &npi) < 0) - { + + if(ioctl(unit_fd, PPPIOCSNPMODE, &npi) < 0) { tun_error("starting ppp unit: %s", strerror(errno)); return -1; } @@ -219,10 +212,8 @@ static int ppp_setup_unit(int unit_fd) return 0; } -static int open_pcap() -{ - if (pcap != NULL) - { +static int open_pcap() { + if(pcap != NULL) { pcap_use_count++; return 0; } @@ -231,8 +222,7 @@ static int open_pcap() pcap = pcap_open_live("lo0", BUFSIZ, 0, 1, errbuf); pcap_use_count = 1; - if (pcap == NULL) - { + if(pcap == NULL) { tun_error("opening pcap: %s", errbuf); return -1; } @@ -241,59 +231,57 @@ static int open_pcap() return 0; } -static void close_pcap() -{ - if (pcap == NULL) +static void close_pcap() { + if(pcap == NULL) { return; + } pcap_use_count--; - if (pcap_use_count == 0) - { + + if(pcap_use_count == 0) { pcap_close(pcap); pcap = NULL; } } -static void allocate_data_buffer(int size) -{ - if (data_buffer_length < size) - { +static void allocate_data_buffer(int size) { + if(data_buffer_length < size) { free(data_buffer); data_buffer_length = size; data_buffer = malloc(data_buffer_length); } } -static void make_device_name(tunemu_device device, int unit_number) -{ +static void make_device_name(tunemu_device device, int unit_number) { snprintf(device, sizeof(tunemu_device), "ppp%d", unit_number); } -static int check_device_name(tunemu_device device) -{ - if (strlen(device) < 4) +static int check_device_name(tunemu_device device) { + if(strlen(device) < 4) { return -1; + } int unit_number = atoi(device + 3); - if (unit_number < 0 || unit_number > 999) + + if(unit_number < 0 || unit_number > 999) { return -1; + } tunemu_device compare; make_device_name(compare, unit_number); - if (strcmp(device, compare) != 0) + if(strcmp(device, compare) != 0) { return -1; + } return 0; } -int tunemu_open(tunemu_device device) -{ +int tunemu_open(tunemu_device device) { int ppp_unit_number = -1; - if (device[0] != 0) - { - if (check_device_name(device) < 0) - { + + if(device[0] != 0) { + if(check_device_name(device) < 0) { tun_error("invalid device name \"%s\"", device); return -1; } @@ -302,17 +290,17 @@ int tunemu_open(tunemu_device device) } int ppp_unit_fd = ppp_new_unit(&ppp_unit_number); - if (ppp_unit_fd < 0) + + if(ppp_unit_fd < 0) { return -1; + } - if (ppp_setup_unit(ppp_unit_fd) < 0) - { + if(ppp_setup_unit(ppp_unit_fd) < 0) { close(ppp_unit_fd); return -1; } - if (open_pcap() < 0) - { + if(open_pcap() < 0) { close(ppp_unit_fd); return -1; } @@ -322,39 +310,40 @@ int tunemu_open(tunemu_device device) return ppp_unit_fd; } -int tunemu_close(int ppp_sockfd) -{ +int tunemu_close(int ppp_sockfd) { int ret = close(ppp_sockfd); - if (ret == 0) + if(ret == 0) { close_pcap(); + } return ret; } -int tunemu_read(int ppp_sockfd, char *buffer, int length) -{ +int tunemu_read(int ppp_sockfd, char *buffer, int length) { allocate_data_buffer(length + 2); length = read(ppp_sockfd, data_buffer, length + 2); - if (length < 0) - { + + if(length < 0) { tun_error("reading packet: %s", strerror(errno)); return length; } + tun_noerror(); length -= 2; - if (length < 0) + + if(length < 0) { return 0; + } memcpy(buffer, data_buffer + 2, length); return length; } -int tunemu_write(int ppp_sockfd, char *buffer, int length) -{ +int tunemu_write(int ppp_sockfd, char *buffer, int length) { allocate_data_buffer(length + 4); data_buffer[0] = 0x02; @@ -364,23 +353,25 @@ int tunemu_write(int ppp_sockfd, char *buffer, int length) memcpy(data_buffer + 4, buffer, length); - if (pcap == NULL) - { + if(pcap == NULL) { tun_error("pcap not open"); return -1; } length = pcap_inject(pcap, data_buffer, length + 4); - if (length < 0) - { + + if(length < 0) { tun_error("injecting packet: %s", pcap_geterr(pcap)); return length; } + tun_noerror(); length -= 4; - if (length < 0) + + if(length < 0) { return 0; + } return length; } diff --git a/src/buffer.c b/src/buffer.c index ac57d1c..a9e79aa 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -82,8 +82,9 @@ static char *buffer_consume(buffer_t *buffer, int size) { char *buffer_readline(buffer_t *buffer) { char *newline = memchr(buffer->data + buffer->offset, '\n', buffer->len - buffer->offset); - if(!newline) + if(!newline) { return NULL; + } int len = newline + 1 - (buffer->data + buffer->offset); *newline = 0; @@ -93,8 +94,9 @@ char *buffer_readline(buffer_t *buffer) { // Check if we have enough bytes in the buffer, and if so, return a pointer to the start of them. char *buffer_read(buffer_t *buffer, int size) { - if(buffer->len - buffer->offset < size) + if(buffer->len - buffer->offset < size) { return NULL; + } return buffer_consume(buffer, size); } diff --git a/src/chacha-poly1305/chacha-poly1305.c b/src/chacha-poly1305/chacha-poly1305.c index d4f3723..b5dab4e 100644 --- a/src/chacha-poly1305/chacha-poly1305.c +++ b/src/chacha-poly1305/chacha-poly1305.c @@ -11,41 +11,37 @@ struct chacha_poly1305_ctx { struct chacha_ctx main_ctx, header_ctx; }; -chacha_poly1305_ctx_t *chacha_poly1305_init(void) -{ +chacha_poly1305_ctx_t *chacha_poly1305_init(void) { chacha_poly1305_ctx_t *ctx = xzalloc(sizeof(*ctx)); return ctx; } -void chacha_poly1305_exit(chacha_poly1305_ctx_t *ctx) -{ +void chacha_poly1305_exit(chacha_poly1305_ctx_t *ctx) { free(ctx); } -bool chacha_poly1305_set_key(chacha_poly1305_ctx_t *ctx, const void *key) -{ +bool chacha_poly1305_set_key(chacha_poly1305_ctx_t *ctx, const void *key) { chacha_keysetup(&ctx->main_ctx, key, 256); chacha_keysetup(&ctx->header_ctx, key + 32, 256); return true; } -static void put_u64(void *vp, uint64_t v) -{ +static void put_u64(void *vp, uint64_t v) { uint8_t *p = (uint8_t *) vp; - p[0] = (uint8_t) (v >> 56) & 0xff; - p[1] = (uint8_t) (v >> 48) & 0xff; - p[2] = (uint8_t) (v >> 40) & 0xff; - p[3] = (uint8_t) (v >> 32) & 0xff; - p[4] = (uint8_t) (v >> 24) & 0xff; - p[5] = (uint8_t) (v >> 16) & 0xff; - p[6] = (uint8_t) (v >> 8) & 0xff; + p[0] = (uint8_t)(v >> 56) & 0xff; + p[1] = (uint8_t)(v >> 48) & 0xff; + p[2] = (uint8_t)(v >> 40) & 0xff; + p[3] = (uint8_t)(v >> 32) & 0xff; + p[4] = (uint8_t)(v >> 24) & 0xff; + p[5] = (uint8_t)(v >> 16) & 0xff; + p[6] = (uint8_t)(v >> 8) & 0xff; p[7] = (uint8_t) v & 0xff; } bool chacha_poly1305_encrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const void *indata, size_t inlen, void *outdata, size_t *outlen) { uint8_t seqbuf[8]; - const uint8_t one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */ + const uint8_t one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */ uint8_t poly_key[POLY1305_KEYLEN]; /* @@ -63,15 +59,16 @@ bool chacha_poly1305_encrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const v chacha_encrypt_bytes(&ctx->main_ctx, indata, outdata, inlen); poly1305_auth(outdata + inlen, outdata, inlen, poly_key); - if (outlen) + if(outlen) { *outlen = inlen + POLY1305_TAGLEN; + } return true; } bool chacha_poly1305_decrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const void *indata, size_t inlen, void *outdata, size_t *outlen) { uint8_t seqbuf[8]; - const uint8_t one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */ + const uint8_t one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */ uint8_t expected_tag[POLY1305_TAGLEN], poly_key[POLY1305_KEYLEN]; /* @@ -91,13 +88,16 @@ bool chacha_poly1305_decrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const v const uint8_t *tag = indata + inlen; poly1305_auth(expected_tag, indata, inlen, poly_key); - if (memcmp(expected_tag, tag, POLY1305_TAGLEN)) + + if(memcmp(expected_tag, tag, POLY1305_TAGLEN)) { return false; + } chacha_encrypt_bytes(&ctx->main_ctx, indata, outdata, inlen); - if (outlen) + if(outlen) { *outlen = inlen; + } return true; } diff --git a/src/chacha-poly1305/chacha.c b/src/chacha-poly1305/chacha.c index 2d0b918..696f44a 100644 --- a/src/chacha-poly1305/chacha.c +++ b/src/chacha-poly1305/chacha.c @@ -47,20 +47,21 @@ typedef struct chacha_ctx chacha_ctx; static const char sigma[16] = "expand 32-byte k"; static const char tau[16] = "expand 16-byte k"; -void chacha_keysetup(chacha_ctx *x, const uint8_t *k, uint32_t kbits) -{ +void chacha_keysetup(chacha_ctx *x, const uint8_t *k, uint32_t kbits) { const char *constants; x->input[4] = U8TO32_LITTLE(k + 0); x->input[5] = U8TO32_LITTLE(k + 4); x->input[6] = U8TO32_LITTLE(k + 8); x->input[7] = U8TO32_LITTLE(k + 12); - if (kbits == 256) { /* recommended */ + + if(kbits == 256) { /* recommended */ k += 16; constants = sigma; - } else { /* kbits == 128 */ + } else { /* kbits == 128 */ constants = tau; } + x->input[8] = U8TO32_LITTLE(k + 0); x->input[9] = U8TO32_LITTLE(k + 4); x->input[10] = U8TO32_LITTLE(k + 8); @@ -71,8 +72,7 @@ void chacha_keysetup(chacha_ctx *x, const uint8_t *k, uint32_t kbits) x->input[3] = U8TO32_LITTLE(constants + 12); } -void chacha_ivsetup(chacha_ctx *x, const uint8_t *iv, const uint8_t *counter) -{ +void chacha_ivsetup(chacha_ctx *x, const uint8_t *iv, const uint8_t *counter) { x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0); x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4); x->input[14] = U8TO32_LITTLE(iv + 0); @@ -80,16 +80,16 @@ void chacha_ivsetup(chacha_ctx *x, const uint8_t *iv, const uint8_t *counter) } void -chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes) -{ +chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes) { uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; uint8_t *ctarget = NULL; uint8_t tmp[64]; uint32_t i; - if (!bytes) + if(!bytes) { return; + } j0 = x->input[0]; j1 = x->input[1]; @@ -108,14 +108,17 @@ chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes j14 = x->input[14]; j15 = x->input[15]; - for (;;) { - if (bytes < 64) { - for (i = 0; i < bytes; ++i) + for(;;) { + if(bytes < 64) { + for(i = 0; i < bytes; ++i) { tmp[i] = m[i]; + } + m = tmp; ctarget = c; c = tmp; } + x0 = j0; x1 = j1; x2 = j2; @@ -132,7 +135,8 @@ chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes x13 = j13; x14 = j14; x15 = j15; - for (i = 20; i > 0; i -= 2) { + + for(i = 20; i > 0; i -= 2) { QUARTERROUND(x0, x4, x8, x12) QUARTERROUND(x1, x5, x9, x13) QUARTERROUND(x2, x6, x10, x14) @@ -142,6 +146,7 @@ chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes QUARTERROUND(x2, x7, x8, x13) QUARTERROUND(x3, x4, x9, x14) } + x0 = PLUS(x0, j0); x1 = PLUS(x1, j1); x2 = PLUS(x2, j2); @@ -177,7 +182,8 @@ chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes x15 = XOR(x15, U8TO32_LITTLE(m + 60)); j12 = PLUSONE(j12); - if (!j12) { + + if(!j12) { j13 = PLUSONE(j13); /* stopping at 2^70 bytes per nonce is user's responsibility */ } @@ -199,15 +205,18 @@ chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes U32TO8_LITTLE(c + 56, x14); U32TO8_LITTLE(c + 60, x15); - if (bytes <= 64) { - if (bytes < 64) { - for (i = 0; i < bytes; ++i) + if(bytes <= 64) { + if(bytes < 64) { + for(i = 0; i < bytes; ++i) { ctarget[i] = c[i]; + } } + x->input[12] = j12; x->input[13] = j13; return; } + bytes -= 64; c += 64; m += 64; diff --git a/src/chacha-poly1305/chacha.h b/src/chacha-poly1305/chacha.h index af1b9a4..103c3d8 100644 --- a/src/chacha-poly1305/chacha.h +++ b/src/chacha-poly1305/chacha.h @@ -11,14 +11,14 @@ struct chacha_ctx { uint32_t input[16]; }; -#define CHACHA_MINKEYLEN 16 -#define CHACHA_NONCELEN 8 -#define CHACHA_CTRLEN 8 -#define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN) -#define CHACHA_BLOCKLEN 64 +#define CHACHA_MINKEYLEN 16 +#define CHACHA_NONCELEN 8 +#define CHACHA_CTRLEN 8 +#define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN) +#define CHACHA_BLOCKLEN 64 void chacha_keysetup(struct chacha_ctx *x, const uint8_t *k, uint32_t kbits); void chacha_ivsetup(struct chacha_ctx *x, const uint8_t *iv, const uint8_t *ctr); -void chacha_encrypt_bytes(struct chacha_ctx *x, const uint8_t *m, uint8_t * c, uint32_t bytes); +void chacha_encrypt_bytes(struct chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes); #endif /* CHACHA_H */ diff --git a/src/chacha-poly1305/poly1305.c b/src/chacha-poly1305/poly1305.c index f1ddf2d..4d99b8c 100644 --- a/src/chacha-poly1305/poly1305.c +++ b/src/chacha-poly1305/poly1305.c @@ -1,4 +1,4 @@ -/* +/* * Public Domain poly1305 from Andrew Moon * poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna */ @@ -24,8 +24,7 @@ } while (0) void -poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t inlen, const unsigned char key[POLY1305_KEYLEN]) -{ +poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t inlen, const unsigned char key[POLY1305_KEYLEN]) { uint32_t t0, t1, t2, t3; uint32_t h0, h1, h2, h3, h4; uint32_t r0, r1, r2, r3, r4; @@ -71,10 +70,11 @@ poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t h4 = 0; /* full blocks */ - if (inlen < 16) + if(inlen < 16) { goto poly1305_donna_atmost15bytes; + } - poly1305_donna_16bytes: +poly1305_donna_16bytes: m += 16; inlen -= 16; @@ -89,7 +89,7 @@ poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t h3 += ((((uint64_t) t3 << 32) | t2) >> 14) & 0x3ffffff; h4 += (t3 >> 8) | (1 << 24); - poly1305_donna_mul: +poly1305_donna_mul: t[0] = mul32x32_64(h0, r0) + mul32x32_64(h1, s4) + mul32x32_64(h2, s3) + mul32x32_64(h3, s2) + mul32x32_64(h4, s1); t[1] = mul32x32_64(h0, r1) + mul32x32_64(h1, r0) + mul32x32_64(h2, s4) + mul32x32_64(h3, s3) + mul32x32_64(h4, s2); t[2] = mul32x32_64(h0, r2) + mul32x32_64(h1, r1) + mul32x32_64(h2, r0) + mul32x32_64(h3, s4) + mul32x32_64(h4, s3); @@ -100,31 +100,39 @@ poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t c = (t[0] >> 26); t[1] += c; h1 = (uint32_t) t[1] & 0x3ffffff; - b = (uint32_t) (t[1] >> 26); + b = (uint32_t)(t[1] >> 26); t[2] += b; h2 = (uint32_t) t[2] & 0x3ffffff; - b = (uint32_t) (t[2] >> 26); + b = (uint32_t)(t[2] >> 26); t[3] += b; h3 = (uint32_t) t[3] & 0x3ffffff; - b = (uint32_t) (t[3] >> 26); + b = (uint32_t)(t[3] >> 26); t[4] += b; h4 = (uint32_t) t[4] & 0x3ffffff; - b = (uint32_t) (t[4] >> 26); + b = (uint32_t)(t[4] >> 26); h0 += b * 5; - if (inlen >= 16) + if(inlen >= 16) { goto poly1305_donna_16bytes; + } /* final bytes */ - poly1305_donna_atmost15bytes: - if (!inlen) +poly1305_donna_atmost15bytes: + + if(!inlen) { goto poly1305_donna_finish; + } - for (j = 0; j < inlen; j++) + for(j = 0; j < inlen; j++) { mp[j] = m[j]; + } + mp[j++] = 1; - for (; j < 16; j++) + + for(; j < 16; j++) { mp[j] = 0; + } + inlen = 0; t0 = U8TO32_LE(mp + 0); @@ -140,7 +148,7 @@ poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t goto poly1305_donna_mul; - poly1305_donna_finish: +poly1305_donna_finish: b = h0 >> 26; h0 = h0 & 0x3ffffff; h1 += b; diff --git a/src/chacha-poly1305/poly1305.h b/src/chacha-poly1305/poly1305.h index 9a64015..4ece415 100644 --- a/src/chacha-poly1305/poly1305.h +++ b/src/chacha-poly1305/poly1305.h @@ -1,6 +1,6 @@ /* $OpenBSD: poly1305.h,v 1.2 2013/12/19 22:57:13 djm Exp $ */ -/* +/* * Public Domain poly1305 from Andrew Moon * poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna */ @@ -8,9 +8,9 @@ #ifndef POLY1305_H #define POLY1305_H -#define POLY1305_KEYLEN 32 -#define POLY1305_TAGLEN 16 +#define POLY1305_KEYLEN 32 +#define POLY1305_TAGLEN 16 void poly1305_auth(uint8_t out[POLY1305_TAGLEN], const uint8_t *m, size_t inlen, const uint8_t key[POLY1305_KEYLEN]); -#endif /* POLY1305_H */ +#endif /* POLY1305_H */ diff --git a/src/cipher.h b/src/cipher.h index 0501223..8d794bb 100644 --- a/src/cipher.h +++ b/src/cipher.h @@ -28,17 +28,17 @@ typedef struct cipher cipher_t; -extern cipher_t *cipher_open_by_name(const char *) __attribute__ ((__malloc__)); -extern cipher_t *cipher_open_by_nid(int) __attribute__ ((__malloc__)); +extern cipher_t *cipher_open_by_name(const char *) __attribute__((__malloc__)); +extern cipher_t *cipher_open_by_nid(int) __attribute__((__malloc__)); extern void cipher_close(cipher_t *); extern size_t cipher_keylength(const cipher_t *); extern size_t cipher_blocksize(const cipher_t *); extern uint64_t cipher_budget(const cipher_t *); extern void cipher_get_key(const cipher_t *, void *); -extern bool cipher_set_key(cipher_t *, void *, bool) __attribute__ ((__warn_unused_result__)); -extern bool cipher_set_key_from_rsa(cipher_t *, void *, size_t, bool) __attribute__ ((__warn_unused_result__)); -extern bool cipher_encrypt(cipher_t *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) __attribute__ ((__warn_unused_result__)); -extern bool cipher_decrypt(cipher_t *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) __attribute__ ((__warn_unused_result__)); +extern bool cipher_set_key(cipher_t *, void *, bool) __attribute__((__warn_unused_result__)); +extern bool cipher_set_key_from_rsa(cipher_t *, void *, size_t, bool) __attribute__((__warn_unused_result__)); +extern bool cipher_encrypt(cipher_t *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) __attribute__((__warn_unused_result__)); +extern bool cipher_decrypt(cipher_t *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) __attribute__((__warn_unused_result__)); extern int cipher_get_nid(const cipher_t *); extern bool cipher_active(const cipher_t *); diff --git a/src/conf.c b/src/conf.c index 8a7e525..e789f72 100644 --- a/src/conf.c +++ b/src/conf.c @@ -46,27 +46,31 @@ static int config_compare(const config_t *a, const config_t *b) { result = strcasecmp(a->variable, b->variable); - if(result) + if(result) { return result; + } /* give priority to command line options */ result = !b->file - !a->file; - if (result) + + if(result) { return result; + } result = a->line - b->line; - if(result) + if(result) { return result; - else + } else { return a->file ? strcmp(a->file, b->file) : 0; + } } -void init_configuration(splay_tree_t ** config_tree) { +void init_configuration(splay_tree_t **config_tree) { *config_tree = splay_alloc_tree((splay_compare_t) config_compare, (splay_action_t) free_config); } -void exit_configuration(splay_tree_t ** config_tree) { +void exit_configuration(splay_tree_t **config_tree) { splay_delete_tree(*config_tree); *config_tree = NULL; } @@ -76,14 +80,17 @@ config_t *new_config(void) { } void free_config(config_t *cfg) { - if(cfg->variable) + if(cfg->variable) { free(cfg->variable); + } - if(cfg->value) + if(cfg->value) { free(cfg->value); + } - if(cfg->file) + if(cfg->file) { free(cfg->file); + } free(cfg); } @@ -101,11 +108,13 @@ config_t *lookup_config(splay_tree_t *config_tree, char *variable) { found = splay_search_closest_greater(config_tree, &cfg); - if(!found) + if(!found) { return NULL; + } - if(strcasecmp(found->variable, variable)) + if(strcasecmp(found->variable, variable)) { return NULL; + } return found; } @@ -120,8 +129,9 @@ config_t *lookup_config_next(splay_tree_t *config_tree, const config_t *cfg) { if(node->next) { found = node->next->data; - if(!strcasecmp(found->variable, cfg->variable)) + if(!strcasecmp(found->variable, cfg->variable)) { return found; + } } } @@ -129,8 +139,9 @@ config_t *lookup_config_next(splay_tree_t *config_tree, const config_t *cfg) { } bool get_config_bool(const config_t *cfg, bool *result) { - if(!cfg) + if(!cfg) { return false; + } if(!strcasecmp(cfg->value, "yes")) { *result = true; @@ -141,27 +152,30 @@ bool get_config_bool(const config_t *cfg, bool *result) { } logger(DEBUG_ALWAYS, LOG_ERR, "\"yes\" or \"no\" expected for configuration variable %s in %s line %d", - cfg->variable, cfg->file, cfg->line); + cfg->variable, cfg->file, cfg->line); return false; } bool get_config_int(const config_t *cfg, int *result) { - if(!cfg) + if(!cfg) { return false; + } - if(sscanf(cfg->value, "%d", result) == 1) + if(sscanf(cfg->value, "%d", result) == 1) { return true; + } logger(DEBUG_ALWAYS, LOG_ERR, "Integer expected for configuration variable %s in %s line %d", - cfg->variable, cfg->file, cfg->line); + cfg->variable, cfg->file, cfg->line); return false; } bool get_config_string(const config_t *cfg, char **result) { - if(!cfg) + if(!cfg) { return false; + } *result = xstrdup(cfg->value); @@ -171,8 +185,9 @@ bool get_config_string(const config_t *cfg, char **result) { bool get_config_address(const config_t *cfg, struct addrinfo **result) { struct addrinfo *ai; - if(!cfg) + if(!cfg) { return false; + } ai = str2addrinfo(cfg->value, NULL, 0); @@ -182,31 +197,32 @@ bool get_config_address(const config_t *cfg, struct addrinfo **result) { } logger(DEBUG_ALWAYS, LOG_ERR, "Hostname or IP address expected for configuration variable %s in %s line %d", - cfg->variable, cfg->file, cfg->line); + cfg->variable, cfg->file, cfg->line); return false; } -bool get_config_subnet(const config_t *cfg, subnet_t ** result) { +bool get_config_subnet(const config_t *cfg, subnet_t **result) { subnet_t subnet = {NULL}; - if(!cfg) + if(!cfg) { return false; + } if(!str2net(&subnet, cfg->value)) { logger(DEBUG_ALWAYS, LOG_ERR, "Subnet expected for configuration variable %s in %s line %d", - cfg->variable, cfg->file, cfg->line); + cfg->variable, cfg->file, cfg->line); return false; } /* Teach newbies what subnets are... */ if(((subnet.type == SUBNET_IPV4) - && !maskcheck(&subnet.net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof(subnet.net.ipv4.address))) - || ((subnet.type == SUBNET_IPV6) - && !maskcheck(&subnet.net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof(subnet.net.ipv6.address)))) { + && !maskcheck(&subnet.net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof(subnet.net.ipv4.address))) + || ((subnet.type == SUBNET_IPV6) + && !maskcheck(&subnet.net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof(subnet.net.ipv6.address)))) { logger(DEBUG_ALWAYS, LOG_ERR, "Network address and prefix length do not match for configuration variable %s in %s line %d", - cfg->variable, cfg->file, cfg->line); + cfg->variable, cfg->file, cfg->line); return false; } @@ -218,27 +234,32 @@ bool get_config_subnet(const config_t *cfg, subnet_t ** result) { /* Read exactly one line and strip the trailing newline if any. */ -static char *readline(FILE * fp, char *buf, size_t buflen) { +static char *readline(FILE *fp, char *buf, size_t buflen) { char *newline = NULL; char *p; - if(feof(fp)) + if(feof(fp)) { return NULL; + } p = fgets(buf, buflen, fp); - if(!p) + if(!p) { return NULL; + } newline = strchr(p, '\n'); - if(!newline) + if(!newline) { return buf; + } /* kill newline and carriage return if necessary */ *newline = '\0'; - if(newline > p && newline[-1] == '\r') + + if(newline > p && newline[-1] == '\r') { newline[-1] = '\0'; + } return buf; } @@ -250,26 +271,32 @@ config_t *parse_config_line(char *line, const char *fname, int lineno) { variable = value = line; eol = line + strlen(line); - while(strchr("\t ", *--eol)) + + while(strchr("\t ", *--eol)) { *eol = '\0'; + } len = strcspn(value, "\t ="); value += len; value += strspn(value, "\t "); + if(*value == '=') { value++; value += strspn(value, "\t "); } + variable[len] = '\0'; if(!*value) { const char err[] = "No value for variable"; - if (fname) + + if(fname) logger(DEBUG_ALWAYS, LOG_ERR, "%s `%s' on line %d while reading config file %s", - err, variable, lineno, fname); + err, variable, lineno, fname); else logger(DEBUG_ALWAYS, LOG_ERR, "%s `%s' in command line option %d", - err, variable, lineno); + err, variable, lineno); + return NULL; } @@ -306,19 +333,24 @@ bool read_config_file(splay_tree_t *config_tree, const char *fname) { line = readline(fp, buffer, sizeof(buffer)); if(!line) { - if(feof(fp)) + if(feof(fp)) { result = true; + } + break; } lineno++; - if(!*line || *line == '#') + if(!*line || *line == '#') { continue; + } if(ignore) { - if(!strncmp(line, "-----END", 8)) + if(!strncmp(line, "-----END", 8)) { ignore = false; + } + continue; } @@ -328,8 +360,11 @@ bool read_config_file(splay_tree_t *config_tree, const char *fname) { } cfg = parse_config_line(line, fname, lineno); - if (!cfg) + + if(!cfg) { break; + } + config_add(config_tree, cfg); } @@ -346,19 +381,24 @@ void read_config_options(splay_tree_t *config_tree, const char *prefix) { config_t *new; if(!prefix) { - if(strchr(cfg->variable, '.')) + if(strchr(cfg->variable, '.')) { continue; + } } else { if(strncmp(prefix, cfg->variable, prefix_len) || - cfg->variable[prefix_len] != '.') + cfg->variable[prefix_len] != '.') { continue; + } } new = new_config(); - if(prefix) + + if(prefix) { new->variable = xstrdup(cfg->variable + prefix_len + 1); - else + } else { new->variable = xstrdup(cfg->variable); + } + new->value = xstrdup(cfg->value); new->file = NULL; new->line = cfg->line; @@ -378,28 +418,33 @@ bool read_server_config(void) { x = read_config_file(config_tree, fname); // We will try to read the conf files in the "conf.d" dir - if (x) { + if(x) { char dname[PATH_MAX]; snprintf(dname, sizeof(dname), "%s" SLASH "conf.d", confbase); - DIR *dir = opendir (dname); + DIR *dir = opendir(dname); + // If we can find this dir - if (dir) { + if(dir) { struct dirent *ep; + // We list all the files in it - while (x && (ep = readdir (dir))) { + while(x && (ep = readdir(dir))) { size_t l = strlen(ep->d_name); + // And we try to read the ones that end with ".conf" - if (l > 5 && !strcmp(".conf", & ep->d_name[ l - 5 ])) { + if(l > 5 && !strcmp(".conf", & ep->d_name[ l - 5 ])) { snprintf(fname, sizeof(fname), "%s" SLASH "%s", dname, ep->d_name); x = read_config_file(config_tree, fname); } } - closedir (dir); + + closedir(dir); } } - if(!x && errno) + if(!x && errno) { logger(DEBUG_ALWAYS, LOG_ERR, "Failed to read `%s': %s", fname, strerror(errno)); + } return x; } diff --git a/src/conf.h b/src/conf.h index 9fcc301..817c2cb 100644 --- a/src/conf.h +++ b/src/conf.h @@ -43,7 +43,7 @@ extern list_t *cmdline_conf; extern void init_configuration(splay_tree_t **); extern void exit_configuration(splay_tree_t **); -extern config_t *new_config(void) __attribute__ ((__malloc__)); +extern config_t *new_config(void) __attribute__((__malloc__)); extern void free_config(config_t *); extern void config_add(splay_tree_t *, config_t *); extern config_t *lookup_config(splay_tree_t *, char *); diff --git a/src/connection.c b/src/connection.c index 5fcecbd..92a9f48 100644 --- a/src/connection.c +++ b/src/connection.c @@ -52,8 +52,9 @@ connection_t *new_connection(void) { } void free_connection(connection_t *c) { - if(!c) + if(!c) { return; + } #ifndef DISABLE_LEGACY cipher_close(c->incipher); @@ -73,14 +74,16 @@ void free_connection(connection_t *c) { io_del(&c->io); - if(c->socket > 0) + if(c->socket > 0) { closesocket(c->socket); + } free(c->name); free(c->hostname); - if(c->config_tree) + if(c->config_tree) { exit_configuration(&c->config_tree); + } free(c); } @@ -96,9 +99,9 @@ void connection_del(connection_t *c) { bool dump_connections(connection_t *cdump) { for list_each(connection_t, c, connection_list) { send_request(cdump, "%d %d %s %s %x %d %x", - CONTROL, REQ_DUMP_CONNECTIONS, - c->name, c->hostname, c->options, c->socket, - bitfield_to_int(&c->status, sizeof(c->status))); + CONTROL, REQ_DUMP_CONNECTIONS, + c->name, c->hostname, c->options, c->socket, + bitfield_to_int(&c->status, sizeof(c->status))); } return send_request(cdump, "%d %d", CONTROL, REQ_DUMP_CONNECTIONS); diff --git a/src/connection.h b/src/connection.h index b6f8105..78c7a5b 100644 --- a/src/connection.h +++ b/src/connection.h @@ -35,21 +35,21 @@ #define OPTION_VERSION(x) ((x) >> 24) /* Top 8 bits are for protocol minor version */ typedef struct connection_status_t { - unsigned int pinged:1; /* sent ping */ - unsigned int unused_active:1; - unsigned int connecting:1; /* 1 if we are waiting for a non-blocking connect() to finish */ - unsigned int unused_termreq:1; /* the termination of this connection was requested */ - unsigned int remove_unused:1; /* Set to 1 if you want this connection removed */ - unsigned int timeout_unused:1; /* 1 if gotten timeout */ - unsigned int encryptout:1; /* 1 if we can encrypt outgoing traffic */ - unsigned int decryptin:1; /* 1 if we have to decrypt incoming traffic */ - unsigned int mst:1; /* 1 if this connection is part of a minimum spanning tree */ - unsigned int control:1; /* 1 if this is a control connection */ - unsigned int pcap:1; /* 1 if this is a control connection requesting packet capture */ - unsigned int log:1; /* 1 if this is a control connection requesting log dump */ - unsigned int invitation:1; /* 1 if this is an invitation */ - unsigned int invitation_used:1; /* 1 if the invitation has been consumed */ - unsigned int unused:18; + unsigned int pinged: 1; /* sent ping */ + unsigned int unused_active: 1; + unsigned int connecting: 1; /* 1 if we are waiting for a non-blocking connect() to finish */ + unsigned int unused_termreq: 1; /* the termination of this connection was requested */ + unsigned int remove_unused: 1; /* Set to 1 if you want this connection removed */ + unsigned int timeout_unused: 1; /* 1 if gotten timeout */ + unsigned int encryptout: 1; /* 1 if we can encrypt outgoing traffic */ + unsigned int decryptin: 1; /* 1 if we have to decrypt incoming traffic */ + unsigned int mst: 1; /* 1 if this connection is part of a minimum spanning tree */ + unsigned int control: 1; /* 1 if this is a control connection */ + unsigned int pcap: 1; /* 1 if this is a control connection requesting packet capture */ + unsigned int log: 1; /* 1 if this is a control connection requesting log dump */ + unsigned int invitation: 1; /* 1 if this is an invitation */ + unsigned int invitation_used: 1; /* 1 if the invitation has been consumed */ + unsigned int unused: 18; } connection_status_t; #include "ecdsa.h" @@ -99,7 +99,7 @@ typedef struct connection_t { struct buffer_t outbuf; io_t io; /* input/output event on this metadata connection */ int tcplen; /* length of incoming TCPpacket */ - int sptpslen; /* length of incoming SPTPS packet */ + int sptpslen; /* length of incoming SPTPS packet */ int allow_request; /* defined if there's only one request possible */ time_t last_ping_time; /* last time we saw some activity from the other end or pinged them */ @@ -112,7 +112,7 @@ extern connection_t *everyone; extern void init_connections(void); extern void exit_connections(void); -extern connection_t *new_connection(void) __attribute__ ((__malloc__)); +extern connection_t *new_connection(void) __attribute__((__malloc__)); extern void free_connection(connection_t *); extern void connection_add(connection_t *); extern void connection_del(connection_t *); diff --git a/src/control.c b/src/control.c index bf8a12b..76f262e 100644 --- a/src/control.c +++ b/src/control.c @@ -56,80 +56,89 @@ bool control_h(connection_t *c, const char *request) { return false; } - switch (type) { - case REQ_STOP: - event_exit(); - return control_ok(c, REQ_STOP); - - case REQ_DUMP_NODES: - return dump_nodes(c); - - case REQ_DUMP_EDGES: - return dump_edges(c); - - case REQ_DUMP_SUBNETS: - return dump_subnets(c); - - case REQ_DUMP_CONNECTIONS: - return dump_connections(c); - - case REQ_PURGE: - purge(); - return control_ok(c, REQ_PURGE); - - case REQ_SET_DEBUG: { - int new_level; - if(sscanf(request, "%*d %*d %d", &new_level) != 1) - return false; - send_request(c, "%d %d %d", CONTROL, REQ_SET_DEBUG, debug_level); - if(new_level >= 0) - debug_level = new_level; - return true; + switch(type) { + case REQ_STOP: + event_exit(); + return control_ok(c, REQ_STOP); + + case REQ_DUMP_NODES: + return dump_nodes(c); + + case REQ_DUMP_EDGES: + return dump_edges(c); + + case REQ_DUMP_SUBNETS: + return dump_subnets(c); + + case REQ_DUMP_CONNECTIONS: + return dump_connections(c); + + case REQ_PURGE: + purge(); + return control_ok(c, REQ_PURGE); + + case REQ_SET_DEBUG: { + int new_level; + + if(sscanf(request, "%*d %*d %d", &new_level) != 1) { + return false; } - case REQ_RETRY: - retry(); - return control_ok(c, REQ_RETRY); + send_request(c, "%d %d %d", CONTROL, REQ_SET_DEBUG, debug_level); + + if(new_level >= 0) { + debug_level = new_level; + } + + return true; + } - case REQ_RELOAD: - logger(DEBUG_ALWAYS, LOG_NOTICE, "Got '%s' command", "reload"); - int result = reload_configuration(); - return control_return(c, REQ_RELOAD, result); + case REQ_RETRY: + retry(); + return control_ok(c, REQ_RETRY); - case REQ_DISCONNECT: { - char name[MAX_STRING_SIZE]; - bool found = false; + case REQ_RELOAD: + logger(DEBUG_ALWAYS, LOG_NOTICE, "Got '%s' command", "reload"); + int result = reload_configuration(); + return control_return(c, REQ_RELOAD, result); - if(sscanf(request, "%*d %*d " MAX_STRING, name) != 1) - return control_return(c, REQ_DISCONNECT, -1); + case REQ_DISCONNECT: { + char name[MAX_STRING_SIZE]; + bool found = false; - for list_each(connection_t, other, connection_list) { - if(strcmp(other->name, name)) - continue; - terminate_connection(other, other->edge); - found = true; + if(sscanf(request, "%*d %*d " MAX_STRING, name) != 1) { + return control_return(c, REQ_DISCONNECT, -1); + } + + for list_each(connection_t, other, connection_list) { + if(strcmp(other->name, name)) { + continue; } - return control_return(c, REQ_DISCONNECT, found ? 0 : -2); + terminate_connection(other, other->edge); + found = true; } - case REQ_DUMP_TRAFFIC: - return dump_traffic(c); + return control_return(c, REQ_DISCONNECT, found ? 0 : -2); + } - case REQ_PCAP: - sscanf(request, "%*d %*d %d", &c->outmaclength); - c->status.pcap = true; - pcap = true; - return true; + case REQ_DUMP_TRAFFIC: + return dump_traffic(c); - case REQ_LOG: - sscanf(request, "%*d %*d %d", &c->outcompression); - c->status.log = true; - logcontrol = true; - return true; + case REQ_PCAP: + sscanf(request, "%*d %*d %d", &c->outmaclength); + c->status.pcap = true; + pcap = true; + return true; - default: - return send_request(c, "%d %d", CONTROL, REQ_INVALID); + case REQ_LOG: + sscanf(request, "%*d %*d %d", &c->outcompression); + c->status.log = true; + logcontrol = true; + return true; + + default: + return send_request(c, "%d %d", CONTROL, REQ_INVALID); } } @@ -159,12 +168,15 @@ bool init_control(void) { xasprintf(&localhost, "127.0.0.1 port %s", myport); } else { if(sa.sa.sa_family == AF_INET) { - if(sa.in.sin_addr.s_addr == 0) + if(sa.in.sin_addr.s_addr == 0) { sa.in.sin_addr.s_addr = htonl(0x7f000001); + } } else if(sa.sa.sa_family == AF_INET6) { static const uint8_t zero[16] = {0}; - if(!memcmp(sa.in6.sin6_addr.s6_addr, zero, sizeof(zero))) + + if(!memcmp(sa.in6.sin6_addr.s6_addr, zero, sizeof(zero))) { sa.in6.sin6_addr.s6_addr[15] = 1; + } } localhost = sockaddr2hostname(&sa); @@ -177,13 +189,16 @@ bool init_control(void) { #ifndef HAVE_MINGW int unix_fd = socket(AF_UNIX, SOCK_STREAM, 0); + if(unix_fd < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not create UNIX socket: %s", sockstrerror(sockerrno)); return false; } struct sockaddr_un sa_un; + sa_un.sun_family = AF_UNIX; + strncpy(sa_un.sun_path, unixsocketname, sizeof(sa_un.sun_path)); if(connect(unix_fd, (struct sockaddr *)&sa_un, sizeof(sa_un)) >= 0) { diff --git a/src/cygwin/device.c b/src/cygwin/device.c index 64fcc7c..8229c3d 100644 --- a/src/cygwin/device.c +++ b/src/cygwin/device.c @@ -59,8 +59,9 @@ static bool setup_device(void) { get_config_string(lookup_config(config_tree, "Device"), &device); get_config_string(lookup_config(config_tree, "Interface"), &iface); - if(device && iface) + if(device && iface) { logger(LOG_WARNING, "Warning: both Device and Interface specified, results may not be as expected"); + } /* Open registry and look for network adapters */ @@ -69,44 +70,51 @@ static bool setup_device(void) { return false; } - for (i = 0; ; i++) { + for(i = 0; ; i++) { len = sizeof(adapterid); - if(RegEnumKeyEx(key, i, adapterid, &len, 0, 0, 0, NULL)) + + if(RegEnumKeyEx(key, i, adapterid, &len, 0, 0, 0, NULL)) { break; + } /* Find out more about this adapter */ snprintf(regpath, sizeof(regpath), "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapterid); - if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2)) + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2)) { continue; + } len = sizeof(adaptername); err = RegQueryValueEx(key2, "Name", 0, 0, adaptername, &len); RegCloseKey(key2); - if(err) + if(err) { continue; + } if(device) { if(!strcmp(device, adapterid)) { found = true; break; - } else + } else { continue; + } } if(iface) { if(!strcmp(iface, adaptername)) { found = true; break; - } else + } else { continue; + } } snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid); device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0); + if(device_handle != INVALID_HANDLE_VALUE) { CloseHandle(device_handle); found = true; @@ -121,11 +129,13 @@ static bool setup_device(void) { return false; } - if(!device) + if(!device) { device = xstrdup(adapterid); + } - if(!iface) + if(!iface) { iface = xstrdup(adaptername); + } snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, device); @@ -140,7 +150,7 @@ static bool setup_device(void) { /* The parent opens the tap device for writing. */ - device_handle = CreateFile(tapname, GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM , 0); + device_handle = CreateFile(tapname, GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0); if(device_handle == INVALID_HANDLE_VALUE) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not open Windows tap device %s (%s) for writing: %s", device, iface, winerror(GetLastError())); @@ -203,6 +213,7 @@ static bool setup_device(void) { } read(device_fd, &gelukt, 1); + if(gelukt != 1) { logger(DEBUG_ALWAYS, LOG_DEBUG, "Tap reader failed!"); return false; @@ -218,12 +229,15 @@ static bool setup_device(void) { static void close_device(void) { close(sp[0]); close(sp[1]); - CloseHandle(device_handle); device_handle = INVALID_HANDLE_VALUE; + CloseHandle(device_handle); + device_handle = INVALID_HANDLE_VALUE; kill(reader_pid, SIGKILL); - free(device); device = NULL; - free(iface); iface = NULL; + free(device); + device = NULL; + free(iface); + iface = NULL; device_info = NULL; } @@ -232,14 +246,14 @@ static bool read_packet(vpn_packet_t *packet) { if((inlen = read(sp[0], DATA(packet), MTU)) <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); + device, strerror(errno)); return false; } packet->len = inlen; logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, - device_info); + device_info); return true; } @@ -248,9 +262,9 @@ static bool write_packet(vpn_packet_t *packet) { long outlen; logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + packet->len, device_info); - if(!WriteFile (device_handle, DATA(packet), packet->len, &outlen, NULL)) { + if(!WriteFile(device_handle, DATA(packet), packet->len, &outlen, NULL)) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, device, winerror(GetLastError())); return false; } diff --git a/src/digest.h b/src/digest.h index 3341531..e74ed3f 100644 --- a/src/digest.h +++ b/src/digest.h @@ -26,12 +26,12 @@ typedef struct digest digest_t; -extern digest_t *digest_open_by_name(const char *name, int maclength) __attribute__ ((__malloc__)); -extern digest_t *digest_open_by_nid(int nid, int maclength) __attribute__ ((__malloc__)); +extern digest_t *digest_open_by_name(const char *name, int maclength) __attribute__((__malloc__)); +extern digest_t *digest_open_by_nid(int nid, int maclength) __attribute__((__malloc__)); extern void digest_close(digest_t *); -extern bool digest_create(digest_t *, const void *indata, size_t inlen, void *outdata) __attribute__ ((__warn_unused_result__)); -extern bool digest_verify(digest_t *, const void *indata, size_t inlen, const void *digestdata) __attribute__ ((__warn_unused_result__)); -extern bool digest_set_key(digest_t *, const void *key, size_t len) __attribute__ ((__warn_unused_result__)); +extern bool digest_create(digest_t *, const void *indata, size_t inlen, void *outdata) __attribute__((__warn_unused_result__)); +extern bool digest_verify(digest_t *, const void *indata, size_t inlen, const void *digestdata) __attribute__((__warn_unused_result__)); +extern bool digest_set_key(digest_t *, const void *key, size_t len) __attribute__((__warn_unused_result__)); extern int digest_get_nid(const digest_t *); extern size_t digest_keylength(const digest_t *); extern size_t digest_length(const digest_t *); diff --git a/src/dropin.c b/src/dropin.c index a4f7a65..74e5676 100644 --- a/src/dropin.c +++ b/src/dropin.c @@ -50,8 +50,9 @@ int daemon(int nochdir, int noclose) { } /* If we are the parent, terminate */ - if(pid) + if(pid) { exit(0); + } /* Detach by becoming the new process group leader */ if(setsid() < 0) { @@ -108,8 +109,9 @@ int vasprintf(char **buf, const char *fmt, va_list ap) { status = vsnprintf(*buf, len, fmt, aq); va_end(aq); - if(status >= 0) + if(status >= 0) { *buf = xrealloc(*buf, status + 1); + } if(status > len - 1) { len = status + 1; diff --git a/src/dropin.h b/src/dropin.h index 81d1d03..5033f90 100644 --- a/src/dropin.h +++ b/src/dropin.h @@ -40,20 +40,20 @@ extern int nanosleep(const struct timespec *req, struct timespec *rem); #ifndef timeradd #define timeradd(a, b, r) do {\ - (r)->tv_sec = (a)->tv_sec + (b)->tv_sec;\ - (r)->tv_usec = (a)->tv_usec + (b)->tv_usec;\ - if((r)->tv_usec >= 1000000)\ - (r)->tv_sec++, (r)->tv_usec -= 1000000;\ -} while (0) + (r)->tv_sec = (a)->tv_sec + (b)->tv_sec;\ + (r)->tv_usec = (a)->tv_usec + (b)->tv_usec;\ + if((r)->tv_usec >= 1000000)\ + (r)->tv_sec++, (r)->tv_usec -= 1000000;\ + } while (0) #endif #ifndef timersub #define timersub(a, b, r) do {\ - (r)->tv_sec = (a)->tv_sec - (b)->tv_sec;\ - (r)->tv_usec = (a)->tv_usec - (b)->tv_usec;\ - if((r)->tv_usec < 0)\ - (r)->tv_sec--, (r)->tv_usec += 1000000;\ -} while (0) + (r)->tv_sec = (a)->tv_sec - (b)->tv_sec;\ + (r)->tv_usec = (a)->tv_usec - (b)->tv_usec;\ + if((r)->tv_usec < 0)\ + (r)->tv_sec--, (r)->tv_usec += 1000000;\ + } while (0) #endif #ifdef HAVE_MINGW diff --git a/src/ecdh.h b/src/ecdh.h index 5a88244..0bfc271 100644 --- a/src/ecdh.h +++ b/src/ecdh.h @@ -27,8 +27,8 @@ typedef struct ecdh ecdh_t; #endif -extern ecdh_t *ecdh_generate_public(void *pubkey) __attribute__ ((__malloc__)); -extern bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) __attribute__ ((__warn_unused_result__)); +extern ecdh_t *ecdh_generate_public(void *pubkey) __attribute__((__malloc__)); +extern bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) __attribute__((__warn_unused_result__)); extern void ecdh_free(ecdh_t *ecdh); #endif diff --git a/src/ecdsa.h b/src/ecdsa.h index be138f9..6cb5434 100644 --- a/src/ecdsa.h +++ b/src/ecdsa.h @@ -24,13 +24,13 @@ typedef struct ecdsa ecdsa_t; #endif -extern ecdsa_t *ecdsa_set_base64_public_key(const char *p) __attribute__ ((__malloc__)); +extern ecdsa_t *ecdsa_set_base64_public_key(const char *p) __attribute__((__malloc__)); extern char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa); -extern ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) __attribute__ ((__malloc__)); -extern ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) __attribute__ ((__malloc__)); +extern ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) __attribute__((__malloc__)); +extern ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) __attribute__((__malloc__)); extern size_t ecdsa_size(ecdsa_t *ecdsa); -extern bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t inlen, void *out) __attribute__ ((__warn_unused_result__)); -extern bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t inlen, const void *out) __attribute__ ((__warn_unused_result__)); +extern bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t inlen, void *out) __attribute__((__warn_unused_result__)); +extern bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t inlen, const void *out) __attribute__((__warn_unused_result__)); extern bool ecdsa_active(ecdsa_t *ecdsa); extern void ecdsa_free(ecdsa_t *ecdsa); diff --git a/src/ecdsagen.h b/src/ecdsagen.h index 95ec741..48cd25b 100644 --- a/src/ecdsagen.h +++ b/src/ecdsagen.h @@ -22,8 +22,8 @@ #include "ecdsa.h" -extern ecdsa_t *ecdsa_generate(void) __attribute__ ((__malloc__)); -extern bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp) __attribute__ ((__warn_unused_result__)); -extern bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp) __attribute__ ((__warn_unused_result__)); +extern ecdsa_t *ecdsa_generate(void) __attribute__((__malloc__)); +extern bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp) __attribute__((__warn_unused_result__)); +extern bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp) __attribute__((__warn_unused_result__)); #endif diff --git a/src/ed25519/ecdsa.c b/src/ed25519/ecdsa.c index 78e24fe..79532c8 100644 --- a/src/ed25519/ecdsa.c +++ b/src/ed25519/ecdsa.c @@ -44,6 +44,7 @@ ecdsa_t *ecdsa_set_base64_public_key(const char *p) { ecdsa_t *ecdsa = xzalloc(sizeof(*ecdsa)); len = b64decode(p, ecdsa->public, len); + if(len != 32) { logger(DEBUG_ALWAYS, LOG_ERR, "Invalid format of public key! len = %d", len); free(ecdsa); @@ -69,19 +70,25 @@ static bool read_pem(FILE *fp, const char *type, void *buf, size_t size) { while(fgets(line, sizeof(line), fp)) { if(!data) { - if(strncmp(line, "-----BEGIN ", 11)) + if(strncmp(line, "-----BEGIN ", 11)) { continue; - if(strncmp(line + 11, type, typelen)) + } + + if(strncmp(line + 11, type, typelen)) { continue; + } + data = true; continue; } - if(!strncmp(line, "-----END ", 9)) + if(!strncmp(line, "-----END ", 9)) { break; + } size_t linelen = strcspn(line, "\r\n"); size_t len = b64decode(line, line, linelen); + if(!len) { logger(DEBUG_ALWAYS, LOG_ERR, "Invalid base64 data in PEM file\n"); errno = EINVAL; @@ -106,6 +113,7 @@ static bool read_pem(FILE *fp, const char *type, void *buf, size_t size) { } else { errno = ENOENT; } + return false; } @@ -114,16 +122,22 @@ static bool read_pem(FILE *fp, const char *type, void *buf, size_t size) { ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) { ecdsa_t *ecdsa = xzalloc(sizeof(*ecdsa)); - if(read_pem(fp, "ED25519 PUBLIC KEY", ecdsa->public, sizeof(ecdsa->public))) + + if(read_pem(fp, "ED25519 PUBLIC KEY", ecdsa->public, sizeof(ecdsa->public))) { return ecdsa; + } + free(ecdsa); return 0; } ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) { ecdsa_t *ecdsa = xmalloc(sizeof(*ecdsa)); - if(read_pem(fp, "ED25519 PRIVATE KEY", ecdsa->private, sizeof(*ecdsa))) + + if(read_pem(fp, "ED25519 PRIVATE KEY", ecdsa->private, sizeof(*ecdsa))) { return ecdsa; + } + free(ecdsa); return 0; } diff --git a/src/ed25519/ecdsagen.c b/src/ed25519/ecdsagen.c index 5120f28..9a1de1e 100644 --- a/src/ed25519/ecdsagen.c +++ b/src/ed25519/ecdsagen.c @@ -50,6 +50,7 @@ static bool write_pem(FILE *fp, const char *type, void *buf, size_t size) { fprintf(fp, "-----BEGIN %s-----\n", type); char base64[65]; + while(size) { size_t todo = size > 48 ? 48 : size; b64encode(buf, base64, todo); diff --git a/src/ed25519/ed25519.h b/src/ed25519/ed25519.h index 5cb82d5..65b191e 100644 --- a/src/ed25519/ed25519.h +++ b/src/ed25519/ed25519.h @@ -4,15 +4,15 @@ #include #if defined(_WIN32) - #if defined(ED25519_BUILD_DLL) - #define ED25519_DECLSPEC __declspec(dllexport) - #elif defined(ED25519_DLL) - #define ED25519_DECLSPEC __declspec(dllimport) - #else - #define ED25519_DECLSPEC - #endif +#if defined(ED25519_BUILD_DLL) +#define ED25519_DECLSPEC __declspec(dllexport) +#elif defined(ED25519_DLL) +#define ED25519_DECLSPEC __declspec(dllimport) #else - #define ED25519_DECLSPEC +#define ED25519_DECLSPEC +#endif +#else +#define ED25519_DECLSPEC #endif diff --git a/src/ed25519/fe.c b/src/ed25519/fe.c index 1c459f4..df907a7 100644 --- a/src/ed25519/fe.c +++ b/src/ed25519/fe.c @@ -6,24 +6,24 @@ helper functions */ static uint64_t load_3(const unsigned char *in) { - uint64_t result; + uint64_t result; - result = in[0]; - result |= shlu64(in[1], 8); - result |= shlu64(in[2], 16); + result = in[0]; + result |= shlu64(in[1], 8); + result |= shlu64(in[2], 16); - return result; + return result; } static uint64_t load_4(const unsigned char *in) { - uint64_t result; - - result = in[0]; - result |= shlu64(in[1], 8); - result |= shlu64(in[2], 16); - result |= shlu64(in[3], 24); - - return result; + uint64_t result; + + result = in[0]; + result |= shlu64(in[1], 8); + result |= shlu64(in[2], 16); + result |= shlu64(in[3], 24); + + return result; } @@ -33,16 +33,16 @@ static uint64_t load_4(const unsigned char *in) { */ void fe_0(fe h) { - h[0] = 0; - h[1] = 0; - h[2] = 0; - h[3] = 0; - h[4] = 0; - h[5] = 0; - h[6] = 0; - h[7] = 0; - h[8] = 0; - h[9] = 0; + h[0] = 0; + h[1] = 0; + h[2] = 0; + h[3] = 0; + h[4] = 0; + h[5] = 0; + h[6] = 0; + h[7] = 0; + h[8] = 0; + h[9] = 0; } @@ -52,16 +52,16 @@ void fe_0(fe h) { */ void fe_1(fe h) { - h[0] = 1; - h[1] = 0; - h[2] = 0; - h[3] = 0; - h[4] = 0; - h[5] = 0; - h[6] = 0; - h[7] = 0; - h[8] = 0; - h[9] = 0; + h[0] = 1; + h[1] = 0; + h[2] = 0; + h[3] = 0; + h[4] = 0; + h[5] = 0; + h[6] = 0; + h[7] = 0; + h[8] = 0; + h[9] = 0; } @@ -79,47 +79,47 @@ void fe_1(fe h) { */ void fe_add(fe h, const fe f, const fe g) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t g0 = g[0]; - int32_t g1 = g[1]; - int32_t g2 = g[2]; - int32_t g3 = g[3]; - int32_t g4 = g[4]; - int32_t g5 = g[5]; - int32_t g6 = g[6]; - int32_t g7 = g[7]; - int32_t g8 = g[8]; - int32_t g9 = g[9]; - int32_t h0 = f0 + g0; - int32_t h1 = f1 + g1; - int32_t h2 = f2 + g2; - int32_t h3 = f3 + g3; - int32_t h4 = f4 + g4; - int32_t h5 = f5 + g5; - int32_t h6 = f6 + g6; - int32_t h7 = f7 + g7; - int32_t h8 = f8 + g8; - int32_t h9 = f9 + g9; - - h[0] = h0; - h[1] = h1; - h[2] = h2; - h[3] = h3; - h[4] = h4; - h[5] = h5; - h[6] = h6; - h[7] = h7; - h[8] = h8; - h[9] = h9; + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t g0 = g[0]; + int32_t g1 = g[1]; + int32_t g2 = g[2]; + int32_t g3 = g[3]; + int32_t g4 = g[4]; + int32_t g5 = g[5]; + int32_t g6 = g[6]; + int32_t g7 = g[7]; + int32_t g8 = g[8]; + int32_t g9 = g[9]; + int32_t h0 = f0 + g0; + int32_t h1 = f1 + g1; + int32_t h2 = f2 + g2; + int32_t h3 = f3 + g3; + int32_t h4 = f4 + g4; + int32_t h5 = f5 + g5; + int32_t h6 = f6 + g6; + int32_t h7 = f7 + g7; + int32_t h8 = f8 + g8; + int32_t h9 = f9 + g9; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; } @@ -132,59 +132,59 @@ void fe_add(fe h, const fe f, const fe g) { */ void fe_cmov(fe f, const fe g, unsigned int b) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t g0 = g[0]; - int32_t g1 = g[1]; - int32_t g2 = g[2]; - int32_t g3 = g[3]; - int32_t g4 = g[4]; - int32_t g5 = g[5]; - int32_t g6 = g[6]; - int32_t g7 = g[7]; - int32_t g8 = g[8]; - int32_t g9 = g[9]; - int32_t x0 = f0 ^ g0; - int32_t x1 = f1 ^ g1; - int32_t x2 = f2 ^ g2; - int32_t x3 = f3 ^ g3; - int32_t x4 = f4 ^ g4; - int32_t x5 = f5 ^ g5; - int32_t x6 = f6 ^ g6; - int32_t x7 = f7 ^ g7; - int32_t x8 = f8 ^ g8; - int32_t x9 = f9 ^ g9; - - b = (unsigned int) (- (int) b); /* silence warning */ - x0 &= b; - x1 &= b; - x2 &= b; - x3 &= b; - x4 &= b; - x5 &= b; - x6 &= b; - x7 &= b; - x8 &= b; - x9 &= b; - - f[0] = f0 ^ x0; - f[1] = f1 ^ x1; - f[2] = f2 ^ x2; - f[3] = f3 ^ x3; - f[4] = f4 ^ x4; - f[5] = f5 ^ x5; - f[6] = f6 ^ x6; - f[7] = f7 ^ x7; - f[8] = f8 ^ x8; - f[9] = f9 ^ x9; + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t g0 = g[0]; + int32_t g1 = g[1]; + int32_t g2 = g[2]; + int32_t g3 = g[3]; + int32_t g4 = g[4]; + int32_t g5 = g[5]; + int32_t g6 = g[6]; + int32_t g7 = g[7]; + int32_t g8 = g[8]; + int32_t g9 = g[9]; + int32_t x0 = f0 ^ g0; + int32_t x1 = f1 ^ g1; + int32_t x2 = f2 ^ g2; + int32_t x3 = f3 ^ g3; + int32_t x4 = f4 ^ g4; + int32_t x5 = f5 ^ g5; + int32_t x6 = f6 ^ g6; + int32_t x7 = f7 ^ g7; + int32_t x8 = f8 ^ g8; + int32_t x9 = f9 ^ g9; + + b = (unsigned int)(- (int) b); /* silence warning */ + x0 &= b; + x1 &= b; + x2 &= b; + x3 &= b; + x4 &= b; + x5 &= b; + x6 &= b; + x7 &= b; + x8 &= b; + x9 &= b; + + f[0] = f0 ^ x0; + f[1] = f1 ^ x1; + f[2] = f2 ^ x2; + f[3] = f3 ^ x3; + f[4] = f4 ^ x4; + f[5] = f5 ^ x5; + f[6] = f6 ^ x6; + f[7] = f7 ^ x7; + f[8] = f8 ^ x8; + f[9] = f9 ^ x9; } /* @@ -194,68 +194,68 @@ void fe_cmov(fe f, const fe g, unsigned int b) { Preconditions: b in {0,1}. */ -void fe_cswap(fe f,fe g,unsigned int b) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t g0 = g[0]; - int32_t g1 = g[1]; - int32_t g2 = g[2]; - int32_t g3 = g[3]; - int32_t g4 = g[4]; - int32_t g5 = g[5]; - int32_t g6 = g[6]; - int32_t g7 = g[7]; - int32_t g8 = g[8]; - int32_t g9 = g[9]; - int32_t x0 = f0 ^ g0; - int32_t x1 = f1 ^ g1; - int32_t x2 = f2 ^ g2; - int32_t x3 = f3 ^ g3; - int32_t x4 = f4 ^ g4; - int32_t x5 = f5 ^ g5; - int32_t x6 = f6 ^ g6; - int32_t x7 = f7 ^ g7; - int32_t x8 = f8 ^ g8; - int32_t x9 = f9 ^ g9; - b = -b; - x0 &= b; - x1 &= b; - x2 &= b; - x3 &= b; - x4 &= b; - x5 &= b; - x6 &= b; - x7 &= b; - x8 &= b; - x9 &= b; - f[0] = f0 ^ x0; - f[1] = f1 ^ x1; - f[2] = f2 ^ x2; - f[3] = f3 ^ x3; - f[4] = f4 ^ x4; - f[5] = f5 ^ x5; - f[6] = f6 ^ x6; - f[7] = f7 ^ x7; - f[8] = f8 ^ x8; - f[9] = f9 ^ x9; - g[0] = g0 ^ x0; - g[1] = g1 ^ x1; - g[2] = g2 ^ x2; - g[3] = g3 ^ x3; - g[4] = g4 ^ x4; - g[5] = g5 ^ x5; - g[6] = g6 ^ x6; - g[7] = g7 ^ x7; - g[8] = g8 ^ x8; - g[9] = g9 ^ x9; +void fe_cswap(fe f, fe g, unsigned int b) { + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t g0 = g[0]; + int32_t g1 = g[1]; + int32_t g2 = g[2]; + int32_t g3 = g[3]; + int32_t g4 = g[4]; + int32_t g5 = g[5]; + int32_t g6 = g[6]; + int32_t g7 = g[7]; + int32_t g8 = g[8]; + int32_t g9 = g[9]; + int32_t x0 = f0 ^ g0; + int32_t x1 = f1 ^ g1; + int32_t x2 = f2 ^ g2; + int32_t x3 = f3 ^ g3; + int32_t x4 = f4 ^ g4; + int32_t x5 = f5 ^ g5; + int32_t x6 = f6 ^ g6; + int32_t x7 = f7 ^ g7; + int32_t x8 = f8 ^ g8; + int32_t x9 = f9 ^ g9; + b = -b; + x0 &= b; + x1 &= b; + x2 &= b; + x3 &= b; + x4 &= b; + x5 &= b; + x6 &= b; + x7 &= b; + x8 &= b; + x9 &= b; + f[0] = f0 ^ x0; + f[1] = f1 ^ x1; + f[2] = f2 ^ x2; + f[3] = f3 ^ x3; + f[4] = f4 ^ x4; + f[5] = f5 ^ x5; + f[6] = f6 ^ x6; + f[7] = f7 ^ x7; + f[8] = f8 ^ x8; + f[9] = f9 ^ x9; + g[0] = g0 ^ x0; + g[1] = g1 ^ x1; + g[2] = g2 ^ x2; + g[3] = g3 ^ x3; + g[4] = g4 ^ x4; + g[5] = g5 ^ x5; + g[6] = g6 ^ x6; + g[7] = g7 ^ x7; + g[8] = g8 ^ x8; + g[9] = g9 ^ x9; } @@ -265,27 +265,27 @@ void fe_cswap(fe f,fe g,unsigned int b) { */ void fe_copy(fe h, const fe f) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - - h[0] = f0; - h[1] = f1; - h[2] = f2; - h[3] = f3; - h[4] = f4; - h[5] = f5; - h[6] = f6; - h[7] = f7; - h[8] = f8; - h[9] = f9; + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + + h[0] = f0; + h[1] = f1; + h[2] = f2; + h[3] = f3; + h[4] = f4; + h[5] = f5; + h[6] = f6; + h[7] = f7; + h[8] = f8; + h[9] = f9; } @@ -295,156 +295,156 @@ void fe_copy(fe h, const fe f) { */ void fe_frombytes(fe h, const unsigned char *s) { - int64_t h0 = load_4(s); - int64_t h1 = load_3(s + 4) << 6; - int64_t h2 = load_3(s + 7) << 5; - int64_t h3 = load_3(s + 10) << 3; - int64_t h4 = load_3(s + 13) << 2; - int64_t h5 = load_4(s + 16); - int64_t h6 = load_3(s + 20) << 7; - int64_t h7 = load_3(s + 23) << 5; - int64_t h8 = load_3(s + 26) << 4; - int64_t h9 = (load_3(s + 29) & 8388607) << 2; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - - carry9 = (h9 + (1L << 24)) >> 25; - h0 += carry9 * 19; - h9 -= shl64(carry9, 25); - carry1 = (h1 + (1L << 24)) >> 25; - h2 += carry1; - h1 -= shl64(carry1, 25); - carry3 = (h3 + (1L << 24)) >> 25; - h4 += carry3; - h3 -= shl64(carry3, 25); - carry5 = (h5 + (1L << 24)) >> 25; - h6 += carry5; - h5 -= shl64(carry5, 25); - carry7 = (h7 + (1L << 24)) >> 25; - h8 += carry7; - h7 -= shl64(carry7, 25); - carry0 = (h0 + (1L << 25)) >> 26; - h1 += carry0; - h0 -= shl64(carry0, 26); - carry2 = (h2 + (1L << 25)) >> 26; - h3 += carry2; - h2 -= shl64(carry2, 26); - carry4 = (h4 + (1L << 25)) >> 26; - h5 += carry4; - h4 -= shl64(carry4, 26); - carry6 = (h6 + (1L << 25)) >> 26; - h7 += carry6; - h6 -= shl64(carry6, 26); - carry8 = (h8 + (1L << 25)) >> 26; - h9 += carry8; - h8 -= shl64(carry8, 26); - - h[0] = h0; - h[1] = h1; - h[2] = h2; - h[3] = h3; - h[4] = h4; - h[5] = h5; - h[6] = h6; - h[7] = h7; - h[8] = h8; - h[9] = h9; + int64_t h0 = load_4(s); + int64_t h1 = load_3(s + 4) << 6; + int64_t h2 = load_3(s + 7) << 5; + int64_t h3 = load_3(s + 10) << 3; + int64_t h4 = load_3(s + 13) << 2; + int64_t h5 = load_4(s + 16); + int64_t h6 = load_3(s + 20) << 7; + int64_t h7 = load_3(s + 23) << 5; + int64_t h8 = load_3(s + 26) << 4; + int64_t h9 = (load_3(s + 29) & 8388607) << 2; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + carry9 = (h9 + (1L << 24)) >> 25; + h0 += carry9 * 19; + h9 -= shl64(carry9, 25); + carry1 = (h1 + (1L << 24)) >> 25; + h2 += carry1; + h1 -= shl64(carry1, 25); + carry3 = (h3 + (1L << 24)) >> 25; + h4 += carry3; + h3 -= shl64(carry3, 25); + carry5 = (h5 + (1L << 24)) >> 25; + h6 += carry5; + h5 -= shl64(carry5, 25); + carry7 = (h7 + (1L << 24)) >> 25; + h8 += carry7; + h7 -= shl64(carry7, 25); + carry0 = (h0 + (1L << 25)) >> 26; + h1 += carry0; + h0 -= shl64(carry0, 26); + carry2 = (h2 + (1L << 25)) >> 26; + h3 += carry2; + h2 -= shl64(carry2, 26); + carry4 = (h4 + (1L << 25)) >> 26; + h5 += carry4; + h4 -= shl64(carry4, 26); + carry6 = (h6 + (1L << 25)) >> 26; + h7 += carry6; + h6 -= shl64(carry6, 26); + carry8 = (h8 + (1L << 25)) >> 26; + h9 += carry8; + h8 -= shl64(carry8, 26); + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; } void fe_invert(fe out, const fe z) { - fe t0; - fe t1; - fe t2; - fe t3; - int i; + fe t0; + fe t1; + fe t2; + fe t3; + int i; - fe_sq(t0, z); + fe_sq(t0, z); - for (i = 1; i < 1; ++i) { - fe_sq(t0, t0); - } + for(i = 1; i < 1; ++i) { + fe_sq(t0, t0); + } - fe_sq(t1, t0); + fe_sq(t1, t0); - for (i = 1; i < 2; ++i) { - fe_sq(t1, t1); - } + for(i = 1; i < 2; ++i) { + fe_sq(t1, t1); + } - fe_mul(t1, z, t1); - fe_mul(t0, t0, t1); - fe_sq(t2, t0); + fe_mul(t1, z, t1); + fe_mul(t0, t0, t1); + fe_sq(t2, t0); - for (i = 1; i < 1; ++i) { - fe_sq(t2, t2); - } + for(i = 1; i < 1; ++i) { + fe_sq(t2, t2); + } - fe_mul(t1, t1, t2); - fe_sq(t2, t1); + fe_mul(t1, t1, t2); + fe_sq(t2, t1); - for (i = 1; i < 5; ++i) { - fe_sq(t2, t2); - } + for(i = 1; i < 5; ++i) { + fe_sq(t2, t2); + } - fe_mul(t1, t2, t1); - fe_sq(t2, t1); + fe_mul(t1, t2, t1); + fe_sq(t2, t1); - for (i = 1; i < 10; ++i) { - fe_sq(t2, t2); - } + for(i = 1; i < 10; ++i) { + fe_sq(t2, t2); + } - fe_mul(t2, t2, t1); - fe_sq(t3, t2); + fe_mul(t2, t2, t1); + fe_sq(t3, t2); - for (i = 1; i < 20; ++i) { - fe_sq(t3, t3); - } + for(i = 1; i < 20; ++i) { + fe_sq(t3, t3); + } - fe_mul(t2, t3, t2); - fe_sq(t2, t2); + fe_mul(t2, t3, t2); + fe_sq(t2, t2); - for (i = 1; i < 10; ++i) { - fe_sq(t2, t2); - } + for(i = 1; i < 10; ++i) { + fe_sq(t2, t2); + } - fe_mul(t1, t2, t1); - fe_sq(t2, t1); + fe_mul(t1, t2, t1); + fe_sq(t2, t1); - for (i = 1; i < 50; ++i) { - fe_sq(t2, t2); - } + for(i = 1; i < 50; ++i) { + fe_sq(t2, t2); + } - fe_mul(t2, t2, t1); - fe_sq(t3, t2); + fe_mul(t2, t2, t1); + fe_sq(t3, t2); - for (i = 1; i < 100; ++i) { - fe_sq(t3, t3); - } + for(i = 1; i < 100; ++i) { + fe_sq(t3, t3); + } - fe_mul(t2, t3, t2); - fe_sq(t2, t2); + fe_mul(t2, t3, t2); + fe_sq(t2, t2); - for (i = 1; i < 50; ++i) { - fe_sq(t2, t2); - } + for(i = 1; i < 50; ++i) { + fe_sq(t2, t2); + } - fe_mul(t1, t2, t1); - fe_sq(t1, t1); + fe_mul(t1, t2, t1); + fe_sq(t1, t1); - for (i = 1; i < 5; ++i) { - fe_sq(t1, t1); - } + for(i = 1; i < 5; ++i) { + fe_sq(t1, t1); + } - fe_mul(out, t1, t0); + fe_mul(out, t1, t0); } @@ -458,11 +458,11 @@ void fe_invert(fe out, const fe z) { */ int fe_isnegative(const fe f) { - unsigned char s[32]; + unsigned char s[32]; + + fe_tobytes(s, f); - fe_tobytes(s, f); - - return s[0] & 1; + return s[0] & 1; } @@ -476,47 +476,47 @@ int fe_isnegative(const fe f) { */ int fe_isnonzero(const fe f) { - unsigned char s[32]; - unsigned char r; - - fe_tobytes(s, f); - - r = s[0]; - #define F(i) r |= s[i] - F(1); - F(2); - F(3); - F(4); - F(5); - F(6); - F(7); - F(8); - F(9); - F(10); - F(11); - F(12); - F(13); - F(14); - F(15); - F(16); - F(17); - F(18); - F(19); - F(20); - F(21); - F(22); - F(23); - F(24); - F(25); - F(26); - F(27); - F(28); - F(29); - F(30); - F(31); - #undef F - - return r != 0; + unsigned char s[32]; + unsigned char r; + + fe_tobytes(s, f); + + r = s[0]; +#define F(i) r |= s[i] + F(1); + F(2); + F(3); + F(4); + F(5); + F(6); + F(7); + F(8); + F(9); + F(10); + F(11); + F(12); + F(13); + F(14); + F(15); + F(16); + F(17); + F(18); + F(19); + F(20); + F(21); + F(22); + F(23); + F(24); + F(25); + F(26); + F(27); + F(28); + F(29); + F(30); + F(31); +#undef F + + return r != 0; } @@ -533,235 +533,235 @@ int fe_isnonzero(const fe f) { |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. */ - /* - Notes on implementation strategy: +/* +Notes on implementation strategy: - Using schoolbook multiplication. - Karatsuba would save a little in some cost models. +Using schoolbook multiplication. +Karatsuba would save a little in some cost models. - Most multiplications by 2 and 19 are 32-bit precomputations; - cheaper than 64-bit postcomputations. +Most multiplications by 2 and 19 are 32-bit precomputations; +cheaper than 64-bit postcomputations. - There is one remaining multiplication by 19 in the carry chain; - one *19 precomputation can be merged into this, - but the resulting data flow is considerably less clean. +There is one remaining multiplication by 19 in the carry chain; +one *19 precomputation can be merged into this, +but the resulting data flow is considerably less clean. - There are 12 carries below. - 10 of them are 2-way parallelizable and vectorizable. - Can get away with 11 carries, but then data flow is much deeper. +There are 12 carries below. +10 of them are 2-way parallelizable and vectorizable. +Can get away with 11 carries, but then data flow is much deeper. - With tighter constraints on inputs can squeeze carries into int32. +With tighter constraints on inputs can squeeze carries into int32. */ void fe_mul(fe h, const fe f, const fe g) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t g0 = g[0]; - int32_t g1 = g[1]; - int32_t g2 = g[2]; - int32_t g3 = g[3]; - int32_t g4 = g[4]; - int32_t g5 = g[5]; - int32_t g6 = g[6]; - int32_t g7 = g[7]; - int32_t g8 = g[8]; - int32_t g9 = g[9]; - int32_t g1_19 = 19 * g1; /* 1.959375*2^29 */ - int32_t g2_19 = 19 * g2; /* 1.959375*2^30; still ok */ - int32_t g3_19 = 19 * g3; - int32_t g4_19 = 19 * g4; - int32_t g5_19 = 19 * g5; - int32_t g6_19 = 19 * g6; - int32_t g7_19 = 19 * g7; - int32_t g8_19 = 19 * g8; - int32_t g9_19 = 19 * g9; - int32_t f1_2 = 2 * f1; - int32_t f3_2 = 2 * f3; - int32_t f5_2 = 2 * f5; - int32_t f7_2 = 2 * f7; - int32_t f9_2 = 2 * f9; - int64_t f0g0 = f0 * (int64_t) g0; - int64_t f0g1 = f0 * (int64_t) g1; - int64_t f0g2 = f0 * (int64_t) g2; - int64_t f0g3 = f0 * (int64_t) g3; - int64_t f0g4 = f0 * (int64_t) g4; - int64_t f0g5 = f0 * (int64_t) g5; - int64_t f0g6 = f0 * (int64_t) g6; - int64_t f0g7 = f0 * (int64_t) g7; - int64_t f0g8 = f0 * (int64_t) g8; - int64_t f0g9 = f0 * (int64_t) g9; - int64_t f1g0 = f1 * (int64_t) g0; - int64_t f1g1_2 = f1_2 * (int64_t) g1; - int64_t f1g2 = f1 * (int64_t) g2; - int64_t f1g3_2 = f1_2 * (int64_t) g3; - int64_t f1g4 = f1 * (int64_t) g4; - int64_t f1g5_2 = f1_2 * (int64_t) g5; - int64_t f1g6 = f1 * (int64_t) g6; - int64_t f1g7_2 = f1_2 * (int64_t) g7; - int64_t f1g8 = f1 * (int64_t) g8; - int64_t f1g9_38 = f1_2 * (int64_t) g9_19; - int64_t f2g0 = f2 * (int64_t) g0; - int64_t f2g1 = f2 * (int64_t) g1; - int64_t f2g2 = f2 * (int64_t) g2; - int64_t f2g3 = f2 * (int64_t) g3; - int64_t f2g4 = f2 * (int64_t) g4; - int64_t f2g5 = f2 * (int64_t) g5; - int64_t f2g6 = f2 * (int64_t) g6; - int64_t f2g7 = f2 * (int64_t) g7; - int64_t f2g8_19 = f2 * (int64_t) g8_19; - int64_t f2g9_19 = f2 * (int64_t) g9_19; - int64_t f3g0 = f3 * (int64_t) g0; - int64_t f3g1_2 = f3_2 * (int64_t) g1; - int64_t f3g2 = f3 * (int64_t) g2; - int64_t f3g3_2 = f3_2 * (int64_t) g3; - int64_t f3g4 = f3 * (int64_t) g4; - int64_t f3g5_2 = f3_2 * (int64_t) g5; - int64_t f3g6 = f3 * (int64_t) g6; - int64_t f3g7_38 = f3_2 * (int64_t) g7_19; - int64_t f3g8_19 = f3 * (int64_t) g8_19; - int64_t f3g9_38 = f3_2 * (int64_t) g9_19; - int64_t f4g0 = f4 * (int64_t) g0; - int64_t f4g1 = f4 * (int64_t) g1; - int64_t f4g2 = f4 * (int64_t) g2; - int64_t f4g3 = f4 * (int64_t) g3; - int64_t f4g4 = f4 * (int64_t) g4; - int64_t f4g5 = f4 * (int64_t) g5; - int64_t f4g6_19 = f4 * (int64_t) g6_19; - int64_t f4g7_19 = f4 * (int64_t) g7_19; - int64_t f4g8_19 = f4 * (int64_t) g8_19; - int64_t f4g9_19 = f4 * (int64_t) g9_19; - int64_t f5g0 = f5 * (int64_t) g0; - int64_t f5g1_2 = f5_2 * (int64_t) g1; - int64_t f5g2 = f5 * (int64_t) g2; - int64_t f5g3_2 = f5_2 * (int64_t) g3; - int64_t f5g4 = f5 * (int64_t) g4; - int64_t f5g5_38 = f5_2 * (int64_t) g5_19; - int64_t f5g6_19 = f5 * (int64_t) g6_19; - int64_t f5g7_38 = f5_2 * (int64_t) g7_19; - int64_t f5g8_19 = f5 * (int64_t) g8_19; - int64_t f5g9_38 = f5_2 * (int64_t) g9_19; - int64_t f6g0 = f6 * (int64_t) g0; - int64_t f6g1 = f6 * (int64_t) g1; - int64_t f6g2 = f6 * (int64_t) g2; - int64_t f6g3 = f6 * (int64_t) g3; - int64_t f6g4_19 = f6 * (int64_t) g4_19; - int64_t f6g5_19 = f6 * (int64_t) g5_19; - int64_t f6g6_19 = f6 * (int64_t) g6_19; - int64_t f6g7_19 = f6 * (int64_t) g7_19; - int64_t f6g8_19 = f6 * (int64_t) g8_19; - int64_t f6g9_19 = f6 * (int64_t) g9_19; - int64_t f7g0 = f7 * (int64_t) g0; - int64_t f7g1_2 = f7_2 * (int64_t) g1; - int64_t f7g2 = f7 * (int64_t) g2; - int64_t f7g3_38 = f7_2 * (int64_t) g3_19; - int64_t f7g4_19 = f7 * (int64_t) g4_19; - int64_t f7g5_38 = f7_2 * (int64_t) g5_19; - int64_t f7g6_19 = f7 * (int64_t) g6_19; - int64_t f7g7_38 = f7_2 * (int64_t) g7_19; - int64_t f7g8_19 = f7 * (int64_t) g8_19; - int64_t f7g9_38 = f7_2 * (int64_t) g9_19; - int64_t f8g0 = f8 * (int64_t) g0; - int64_t f8g1 = f8 * (int64_t) g1; - int64_t f8g2_19 = f8 * (int64_t) g2_19; - int64_t f8g3_19 = f8 * (int64_t) g3_19; - int64_t f8g4_19 = f8 * (int64_t) g4_19; - int64_t f8g5_19 = f8 * (int64_t) g5_19; - int64_t f8g6_19 = f8 * (int64_t) g6_19; - int64_t f8g7_19 = f8 * (int64_t) g7_19; - int64_t f8g8_19 = f8 * (int64_t) g8_19; - int64_t f8g9_19 = f8 * (int64_t) g9_19; - int64_t f9g0 = f9 * (int64_t) g0; - int64_t f9g1_38 = f9_2 * (int64_t) g1_19; - int64_t f9g2_19 = f9 * (int64_t) g2_19; - int64_t f9g3_38 = f9_2 * (int64_t) g3_19; - int64_t f9g4_19 = f9 * (int64_t) g4_19; - int64_t f9g5_38 = f9_2 * (int64_t) g5_19; - int64_t f9g6_19 = f9 * (int64_t) g6_19; - int64_t f9g7_38 = f9_2 * (int64_t) g7_19; - int64_t f9g8_19 = f9 * (int64_t) g8_19; - int64_t f9g9_38 = f9_2 * (int64_t) g9_19; - int64_t h0 = f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38; - int64_t h1 = f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19; - int64_t h2 = f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38; - int64_t h3 = f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19; - int64_t h4 = f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38; - int64_t h5 = f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19; - int64_t h6 = f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38; - int64_t h7 = f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19; - int64_t h8 = f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38; - int64_t h9 = f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0 ; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - - carry0 = (h0 + (1L << 25)) >> 26; - h1 += carry0; - h0 -= shl64(carry0, 26); - carry4 = (h4 + (1L << 25)) >> 26; - h5 += carry4; - h4 -= shl64(carry4, 26); - - carry1 = (h1 + (1L << 24)) >> 25; - h2 += carry1; - h1 -= shl64(carry1, 25); - carry5 = (h5 + (1L << 24)) >> 25; - h6 += carry5; - h5 -= shl64(carry5, 25); - - carry2 = (h2 + (1L << 25)) >> 26; - h3 += carry2; - h2 -= shl64(carry2, 26); - carry6 = (h6 + (1L << 25)) >> 26; - h7 += carry6; - h6 -= shl64(carry6, 26); - - carry3 = (h3 + (1L << 24)) >> 25; - h4 += carry3; - h3 -= shl64(carry3, 25); - carry7 = (h7 + (1L << 24)) >> 25; - h8 += carry7; - h7 -= shl64(carry7, 25); - - carry4 = (h4 + (1L << 25)) >> 26; - h5 += carry4; - h4 -= shl64(carry4, 26); - carry8 = (h8 + (1L << 25)) >> 26; - h9 += carry8; - h8 -= shl64(carry8, 26); - - carry9 = (h9 + (1L << 24)) >> 25; - h0 += carry9 * 19; - h9 -= shl64(carry9, 25); - - carry0 = (h0 + (1L << 25)) >> 26; - h1 += carry0; - h0 -= shl64(carry0, 26); - - h[0] = (int32_t) h0; - h[1] = (int32_t) h1; - h[2] = (int32_t) h2; - h[3] = (int32_t) h3; - h[4] = (int32_t) h4; - h[5] = (int32_t) h5; - h[6] = (int32_t) h6; - h[7] = (int32_t) h7; - h[8] = (int32_t) h8; - h[9] = (int32_t) h9; + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t g0 = g[0]; + int32_t g1 = g[1]; + int32_t g2 = g[2]; + int32_t g3 = g[3]; + int32_t g4 = g[4]; + int32_t g5 = g[5]; + int32_t g6 = g[6]; + int32_t g7 = g[7]; + int32_t g8 = g[8]; + int32_t g9 = g[9]; + int32_t g1_19 = 19 * g1; /* 1.959375*2^29 */ + int32_t g2_19 = 19 * g2; /* 1.959375*2^30; still ok */ + int32_t g3_19 = 19 * g3; + int32_t g4_19 = 19 * g4; + int32_t g5_19 = 19 * g5; + int32_t g6_19 = 19 * g6; + int32_t g7_19 = 19 * g7; + int32_t g8_19 = 19 * g8; + int32_t g9_19 = 19 * g9; + int32_t f1_2 = 2 * f1; + int32_t f3_2 = 2 * f3; + int32_t f5_2 = 2 * f5; + int32_t f7_2 = 2 * f7; + int32_t f9_2 = 2 * f9; + int64_t f0g0 = f0 * (int64_t) g0; + int64_t f0g1 = f0 * (int64_t) g1; + int64_t f0g2 = f0 * (int64_t) g2; + int64_t f0g3 = f0 * (int64_t) g3; + int64_t f0g4 = f0 * (int64_t) g4; + int64_t f0g5 = f0 * (int64_t) g5; + int64_t f0g6 = f0 * (int64_t) g6; + int64_t f0g7 = f0 * (int64_t) g7; + int64_t f0g8 = f0 * (int64_t) g8; + int64_t f0g9 = f0 * (int64_t) g9; + int64_t f1g0 = f1 * (int64_t) g0; + int64_t f1g1_2 = f1_2 * (int64_t) g1; + int64_t f1g2 = f1 * (int64_t) g2; + int64_t f1g3_2 = f1_2 * (int64_t) g3; + int64_t f1g4 = f1 * (int64_t) g4; + int64_t f1g5_2 = f1_2 * (int64_t) g5; + int64_t f1g6 = f1 * (int64_t) g6; + int64_t f1g7_2 = f1_2 * (int64_t) g7; + int64_t f1g8 = f1 * (int64_t) g8; + int64_t f1g9_38 = f1_2 * (int64_t) g9_19; + int64_t f2g0 = f2 * (int64_t) g0; + int64_t f2g1 = f2 * (int64_t) g1; + int64_t f2g2 = f2 * (int64_t) g2; + int64_t f2g3 = f2 * (int64_t) g3; + int64_t f2g4 = f2 * (int64_t) g4; + int64_t f2g5 = f2 * (int64_t) g5; + int64_t f2g6 = f2 * (int64_t) g6; + int64_t f2g7 = f2 * (int64_t) g7; + int64_t f2g8_19 = f2 * (int64_t) g8_19; + int64_t f2g9_19 = f2 * (int64_t) g9_19; + int64_t f3g0 = f3 * (int64_t) g0; + int64_t f3g1_2 = f3_2 * (int64_t) g1; + int64_t f3g2 = f3 * (int64_t) g2; + int64_t f3g3_2 = f3_2 * (int64_t) g3; + int64_t f3g4 = f3 * (int64_t) g4; + int64_t f3g5_2 = f3_2 * (int64_t) g5; + int64_t f3g6 = f3 * (int64_t) g6; + int64_t f3g7_38 = f3_2 * (int64_t) g7_19; + int64_t f3g8_19 = f3 * (int64_t) g8_19; + int64_t f3g9_38 = f3_2 * (int64_t) g9_19; + int64_t f4g0 = f4 * (int64_t) g0; + int64_t f4g1 = f4 * (int64_t) g1; + int64_t f4g2 = f4 * (int64_t) g2; + int64_t f4g3 = f4 * (int64_t) g3; + int64_t f4g4 = f4 * (int64_t) g4; + int64_t f4g5 = f4 * (int64_t) g5; + int64_t f4g6_19 = f4 * (int64_t) g6_19; + int64_t f4g7_19 = f4 * (int64_t) g7_19; + int64_t f4g8_19 = f4 * (int64_t) g8_19; + int64_t f4g9_19 = f4 * (int64_t) g9_19; + int64_t f5g0 = f5 * (int64_t) g0; + int64_t f5g1_2 = f5_2 * (int64_t) g1; + int64_t f5g2 = f5 * (int64_t) g2; + int64_t f5g3_2 = f5_2 * (int64_t) g3; + int64_t f5g4 = f5 * (int64_t) g4; + int64_t f5g5_38 = f5_2 * (int64_t) g5_19; + int64_t f5g6_19 = f5 * (int64_t) g6_19; + int64_t f5g7_38 = f5_2 * (int64_t) g7_19; + int64_t f5g8_19 = f5 * (int64_t) g8_19; + int64_t f5g9_38 = f5_2 * (int64_t) g9_19; + int64_t f6g0 = f6 * (int64_t) g0; + int64_t f6g1 = f6 * (int64_t) g1; + int64_t f6g2 = f6 * (int64_t) g2; + int64_t f6g3 = f6 * (int64_t) g3; + int64_t f6g4_19 = f6 * (int64_t) g4_19; + int64_t f6g5_19 = f6 * (int64_t) g5_19; + int64_t f6g6_19 = f6 * (int64_t) g6_19; + int64_t f6g7_19 = f6 * (int64_t) g7_19; + int64_t f6g8_19 = f6 * (int64_t) g8_19; + int64_t f6g9_19 = f6 * (int64_t) g9_19; + int64_t f7g0 = f7 * (int64_t) g0; + int64_t f7g1_2 = f7_2 * (int64_t) g1; + int64_t f7g2 = f7 * (int64_t) g2; + int64_t f7g3_38 = f7_2 * (int64_t) g3_19; + int64_t f7g4_19 = f7 * (int64_t) g4_19; + int64_t f7g5_38 = f7_2 * (int64_t) g5_19; + int64_t f7g6_19 = f7 * (int64_t) g6_19; + int64_t f7g7_38 = f7_2 * (int64_t) g7_19; + int64_t f7g8_19 = f7 * (int64_t) g8_19; + int64_t f7g9_38 = f7_2 * (int64_t) g9_19; + int64_t f8g0 = f8 * (int64_t) g0; + int64_t f8g1 = f8 * (int64_t) g1; + int64_t f8g2_19 = f8 * (int64_t) g2_19; + int64_t f8g3_19 = f8 * (int64_t) g3_19; + int64_t f8g4_19 = f8 * (int64_t) g4_19; + int64_t f8g5_19 = f8 * (int64_t) g5_19; + int64_t f8g6_19 = f8 * (int64_t) g6_19; + int64_t f8g7_19 = f8 * (int64_t) g7_19; + int64_t f8g8_19 = f8 * (int64_t) g8_19; + int64_t f8g9_19 = f8 * (int64_t) g9_19; + int64_t f9g0 = f9 * (int64_t) g0; + int64_t f9g1_38 = f9_2 * (int64_t) g1_19; + int64_t f9g2_19 = f9 * (int64_t) g2_19; + int64_t f9g3_38 = f9_2 * (int64_t) g3_19; + int64_t f9g4_19 = f9 * (int64_t) g4_19; + int64_t f9g5_38 = f9_2 * (int64_t) g5_19; + int64_t f9g6_19 = f9 * (int64_t) g6_19; + int64_t f9g7_38 = f9_2 * (int64_t) g7_19; + int64_t f9g8_19 = f9 * (int64_t) g8_19; + int64_t f9g9_38 = f9_2 * (int64_t) g9_19; + int64_t h0 = f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38; + int64_t h1 = f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19; + int64_t h2 = f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38; + int64_t h3 = f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19; + int64_t h4 = f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38; + int64_t h5 = f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19; + int64_t h6 = f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38; + int64_t h7 = f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19; + int64_t h8 = f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38; + int64_t h9 = f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0 ; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + carry0 = (h0 + (1L << 25)) >> 26; + h1 += carry0; + h0 -= shl64(carry0, 26); + carry4 = (h4 + (1L << 25)) >> 26; + h5 += carry4; + h4 -= shl64(carry4, 26); + + carry1 = (h1 + (1L << 24)) >> 25; + h2 += carry1; + h1 -= shl64(carry1, 25); + carry5 = (h5 + (1L << 24)) >> 25; + h6 += carry5; + h5 -= shl64(carry5, 25); + + carry2 = (h2 + (1L << 25)) >> 26; + h3 += carry2; + h2 -= shl64(carry2, 26); + carry6 = (h6 + (1L << 25)) >> 26; + h7 += carry6; + h6 -= shl64(carry6, 26); + + carry3 = (h3 + (1L << 24)) >> 25; + h4 += carry3; + h3 -= shl64(carry3, 25); + carry7 = (h7 + (1L << 24)) >> 25; + h8 += carry7; + h7 -= shl64(carry7, 25); + + carry4 = (h4 + (1L << 25)) >> 26; + h5 += carry4; + h4 -= shl64(carry4, 26); + carry8 = (h8 + (1L << 25)) >> 26; + h9 += carry8; + h8 -= shl64(carry8, 26); + + carry9 = (h9 + (1L << 24)) >> 25; + h0 += carry9 * 19; + h9 -= shl64(carry9, 25); + + carry0 = (h0 + (1L << 25)) >> 26; + h1 += carry0; + h0 -= shl64(carry0, 26); + + h[0] = (int32_t) h0; + h[1] = (int32_t) h1; + h[2] = (int32_t) h2; + h[3] = (int32_t) h3; + h[4] = (int32_t) h4; + h[5] = (int32_t) h5; + h[6] = (int32_t) h6; + h[7] = (int32_t) h7; + h[8] = (int32_t) h8; + h[9] = (int32_t) h9; } @@ -777,59 +777,79 @@ Postconditions: */ void fe_mul121666(fe h, fe f) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int64_t h0 = f0 * (int64_t) 121666; - int64_t h1 = f1 * (int64_t) 121666; - int64_t h2 = f2 * (int64_t) 121666; - int64_t h3 = f3 * (int64_t) 121666; - int64_t h4 = f4 * (int64_t) 121666; - int64_t h5 = f5 * (int64_t) 121666; - int64_t h6 = f6 * (int64_t) 121666; - int64_t h7 = f7 * (int64_t) 121666; - int64_t h8 = f8 * (int64_t) 121666; - int64_t h9 = f9 * (int64_t) 121666; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - - carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= shl64(carry9, 25); - carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= shl64(carry1, 25); - carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= shl64(carry3, 25); - carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= shl64(carry5, 25); - carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= shl64(carry7, 25); - - carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= shl64(carry0, 26); - carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= shl64(carry2, 26); - carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= shl64(carry4, 26); - carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= shl64(carry6, 26); - carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= shl64(carry8, 26); - - h[0] = h0; - h[1] = h1; - h[2] = h2; - h[3] = h3; - h[4] = h4; - h[5] = h5; - h[6] = h6; - h[7] = h7; - h[8] = h8; - h[9] = h9; + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int64_t h0 = f0 * (int64_t) 121666; + int64_t h1 = f1 * (int64_t) 121666; + int64_t h2 = f2 * (int64_t) 121666; + int64_t h3 = f3 * (int64_t) 121666; + int64_t h4 = f4 * (int64_t) 121666; + int64_t h5 = f5 * (int64_t) 121666; + int64_t h6 = f6 * (int64_t) 121666; + int64_t h7 = f7 * (int64_t) 121666; + int64_t h8 = f8 * (int64_t) 121666; + int64_t h9 = f9 * (int64_t) 121666; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + carry9 = (h9 + (int64_t)(1 << 24)) >> 25; + h0 += carry9 * 19; + h9 -= shl64(carry9, 25); + carry1 = (h1 + (int64_t)(1 << 24)) >> 25; + h2 += carry1; + h1 -= shl64(carry1, 25); + carry3 = (h3 + (int64_t)(1 << 24)) >> 25; + h4 += carry3; + h3 -= shl64(carry3, 25); + carry5 = (h5 + (int64_t)(1 << 24)) >> 25; + h6 += carry5; + h5 -= shl64(carry5, 25); + carry7 = (h7 + (int64_t)(1 << 24)) >> 25; + h8 += carry7; + h7 -= shl64(carry7, 25); + + carry0 = (h0 + (int64_t)(1 << 25)) >> 26; + h1 += carry0; + h0 -= shl64(carry0, 26); + carry2 = (h2 + (int64_t)(1 << 25)) >> 26; + h3 += carry2; + h2 -= shl64(carry2, 26); + carry4 = (h4 + (int64_t)(1 << 25)) >> 26; + h5 += carry4; + h4 -= shl64(carry4, 26); + carry6 = (h6 + (int64_t)(1 << 25)) >> 26; + h7 += carry6; + h6 -= shl64(carry6, 26); + carry8 = (h8 + (int64_t)(1 << 25)) >> 26; + h9 += carry8; + h8 -= shl64(carry8, 26); + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; } @@ -844,123 +864,123 @@ Postconditions: */ void fe_neg(fe h, const fe f) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t h0 = -f0; - int32_t h1 = -f1; - int32_t h2 = -f2; - int32_t h3 = -f3; - int32_t h4 = -f4; - int32_t h5 = -f5; - int32_t h6 = -f6; - int32_t h7 = -f7; - int32_t h8 = -f8; - int32_t h9 = -f9; - - h[0] = h0; - h[1] = h1; - h[2] = h2; - h[3] = h3; - h[4] = h4; - h[5] = h5; - h[6] = h6; - h[7] = h7; - h[8] = h8; - h[9] = h9; + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t h0 = -f0; + int32_t h1 = -f1; + int32_t h2 = -f2; + int32_t h3 = -f3; + int32_t h4 = -f4; + int32_t h5 = -f5; + int32_t h6 = -f6; + int32_t h7 = -f7; + int32_t h8 = -f8; + int32_t h9 = -f9; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; } void fe_pow22523(fe out, const fe z) { - fe t0; - fe t1; - fe t2; - int i; - fe_sq(t0, z); + fe t0; + fe t1; + fe t2; + int i; + fe_sq(t0, z); - for (i = 1; i < 1; ++i) { - fe_sq(t0, t0); - } + for(i = 1; i < 1; ++i) { + fe_sq(t0, t0); + } - fe_sq(t1, t0); + fe_sq(t1, t0); - for (i = 1; i < 2; ++i) { - fe_sq(t1, t1); - } + for(i = 1; i < 2; ++i) { + fe_sq(t1, t1); + } - fe_mul(t1, z, t1); - fe_mul(t0, t0, t1); - fe_sq(t0, t0); + fe_mul(t1, z, t1); + fe_mul(t0, t0, t1); + fe_sq(t0, t0); - for (i = 1; i < 1; ++i) { - fe_sq(t0, t0); - } + for(i = 1; i < 1; ++i) { + fe_sq(t0, t0); + } - fe_mul(t0, t1, t0); - fe_sq(t1, t0); + fe_mul(t0, t1, t0); + fe_sq(t1, t0); - for (i = 1; i < 5; ++i) { - fe_sq(t1, t1); - } + for(i = 1; i < 5; ++i) { + fe_sq(t1, t1); + } - fe_mul(t0, t1, t0); - fe_sq(t1, t0); + fe_mul(t0, t1, t0); + fe_sq(t1, t0); - for (i = 1; i < 10; ++i) { - fe_sq(t1, t1); - } + for(i = 1; i < 10; ++i) { + fe_sq(t1, t1); + } - fe_mul(t1, t1, t0); - fe_sq(t2, t1); + fe_mul(t1, t1, t0); + fe_sq(t2, t1); - for (i = 1; i < 20; ++i) { - fe_sq(t2, t2); - } + for(i = 1; i < 20; ++i) { + fe_sq(t2, t2); + } - fe_mul(t1, t2, t1); - fe_sq(t1, t1); + fe_mul(t1, t2, t1); + fe_sq(t1, t1); - for (i = 1; i < 10; ++i) { - fe_sq(t1, t1); - } + for(i = 1; i < 10; ++i) { + fe_sq(t1, t1); + } - fe_mul(t0, t1, t0); - fe_sq(t1, t0); + fe_mul(t0, t1, t0); + fe_sq(t1, t0); - for (i = 1; i < 50; ++i) { - fe_sq(t1, t1); - } + for(i = 1; i < 50; ++i) { + fe_sq(t1, t1); + } - fe_mul(t1, t1, t0); - fe_sq(t2, t1); + fe_mul(t1, t1, t0); + fe_sq(t2, t1); - for (i = 1; i < 100; ++i) { - fe_sq(t2, t2); - } + for(i = 1; i < 100; ++i) { + fe_sq(t2, t2); + } - fe_mul(t1, t2, t1); - fe_sq(t1, t1); + fe_mul(t1, t2, t1); + fe_sq(t1, t1); - for (i = 1; i < 50; ++i) { - fe_sq(t1, t1); - } + for(i = 1; i < 50; ++i) { + fe_sq(t1, t1); + } - fe_mul(t0, t1, t0); - fe_sq(t0, t0); + fe_mul(t0, t1, t0); + fe_sq(t0, t0); - for (i = 1; i < 2; ++i) { - fe_sq(t0, t0); - } + for(i = 1; i < 2; ++i) { + fe_sq(t0, t0); + } - fe_mul(out, t0, z); - return; + fe_mul(out, t0, z); + return; } @@ -980,150 +1000,150 @@ See fe_mul.c for discussion of implementation strategy. */ void fe_sq(fe h, const fe f) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t f0_2 = 2 * f0; - int32_t f1_2 = 2 * f1; - int32_t f2_2 = 2 * f2; - int32_t f3_2 = 2 * f3; - int32_t f4_2 = 2 * f4; - int32_t f5_2 = 2 * f5; - int32_t f6_2 = 2 * f6; - int32_t f7_2 = 2 * f7; - int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */ - int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */ - int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */ - int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */ - int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */ - int64_t f0f0 = f0 * (int64_t) f0; - int64_t f0f1_2 = f0_2 * (int64_t) f1; - int64_t f0f2_2 = f0_2 * (int64_t) f2; - int64_t f0f3_2 = f0_2 * (int64_t) f3; - int64_t f0f4_2 = f0_2 * (int64_t) f4; - int64_t f0f5_2 = f0_2 * (int64_t) f5; - int64_t f0f6_2 = f0_2 * (int64_t) f6; - int64_t f0f7_2 = f0_2 * (int64_t) f7; - int64_t f0f8_2 = f0_2 * (int64_t) f8; - int64_t f0f9_2 = f0_2 * (int64_t) f9; - int64_t f1f1_2 = f1_2 * (int64_t) f1; - int64_t f1f2_2 = f1_2 * (int64_t) f2; - int64_t f1f3_4 = f1_2 * (int64_t) f3_2; - int64_t f1f4_2 = f1_2 * (int64_t) f4; - int64_t f1f5_4 = f1_2 * (int64_t) f5_2; - int64_t f1f6_2 = f1_2 * (int64_t) f6; - int64_t f1f7_4 = f1_2 * (int64_t) f7_2; - int64_t f1f8_2 = f1_2 * (int64_t) f8; - int64_t f1f9_76 = f1_2 * (int64_t) f9_38; - int64_t f2f2 = f2 * (int64_t) f2; - int64_t f2f3_2 = f2_2 * (int64_t) f3; - int64_t f2f4_2 = f2_2 * (int64_t) f4; - int64_t f2f5_2 = f2_2 * (int64_t) f5; - int64_t f2f6_2 = f2_2 * (int64_t) f6; - int64_t f2f7_2 = f2_2 * (int64_t) f7; - int64_t f2f8_38 = f2_2 * (int64_t) f8_19; - int64_t f2f9_38 = f2 * (int64_t) f9_38; - int64_t f3f3_2 = f3_2 * (int64_t) f3; - int64_t f3f4_2 = f3_2 * (int64_t) f4; - int64_t f3f5_4 = f3_2 * (int64_t) f5_2; - int64_t f3f6_2 = f3_2 * (int64_t) f6; - int64_t f3f7_76 = f3_2 * (int64_t) f7_38; - int64_t f3f8_38 = f3_2 * (int64_t) f8_19; - int64_t f3f9_76 = f3_2 * (int64_t) f9_38; - int64_t f4f4 = f4 * (int64_t) f4; - int64_t f4f5_2 = f4_2 * (int64_t) f5; - int64_t f4f6_38 = f4_2 * (int64_t) f6_19; - int64_t f4f7_38 = f4 * (int64_t) f7_38; - int64_t f4f8_38 = f4_2 * (int64_t) f8_19; - int64_t f4f9_38 = f4 * (int64_t) f9_38; - int64_t f5f5_38 = f5 * (int64_t) f5_38; - int64_t f5f6_38 = f5_2 * (int64_t) f6_19; - int64_t f5f7_76 = f5_2 * (int64_t) f7_38; - int64_t f5f8_38 = f5_2 * (int64_t) f8_19; - int64_t f5f9_76 = f5_2 * (int64_t) f9_38; - int64_t f6f6_19 = f6 * (int64_t) f6_19; - int64_t f6f7_38 = f6 * (int64_t) f7_38; - int64_t f6f8_38 = f6_2 * (int64_t) f8_19; - int64_t f6f9_38 = f6 * (int64_t) f9_38; - int64_t f7f7_38 = f7 * (int64_t) f7_38; - int64_t f7f8_38 = f7_2 * (int64_t) f8_19; - int64_t f7f9_76 = f7_2 * (int64_t) f9_38; - int64_t f8f8_19 = f8 * (int64_t) f8_19; - int64_t f8f9_38 = f8 * (int64_t) f9_38; - int64_t f9f9_38 = f9 * (int64_t) f9_38; - int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38; - int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38; - int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19; - int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38; - int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38; - int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38; - int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19; - int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38; - int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38; - int64_t h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - carry0 = (h0 + (1L << 25)) >> 26; - h1 += carry0; - h0 -= shl64(carry0, 26); - carry4 = (h4 + (1L << 25)) >> 26; - h5 += carry4; - h4 -= shl64(carry4, 26); - carry1 = (h1 + (1L << 24)) >> 25; - h2 += carry1; - h1 -= shl64(carry1, 25); - carry5 = (h5 + (1L << 24)) >> 25; - h6 += carry5; - h5 -= shl64(carry5, 25); - carry2 = (h2 + (1L << 25)) >> 26; - h3 += carry2; - h2 -= shl64(carry2, 26); - carry6 = (h6 + (1L << 25)) >> 26; - h7 += carry6; - h6 -= shl64(carry6, 26); - carry3 = (h3 + (1L << 24)) >> 25; - h4 += carry3; - h3 -= shl64(carry3, 25); - carry7 = (h7 + (1L << 24)) >> 25; - h8 += carry7; - h7 -= shl64(carry7, 25); - carry4 = (h4 + (1L << 25)) >> 26; - h5 += carry4; - h4 -= shl64(carry4, 26); - carry8 = (h8 + (1L << 25)) >> 26; - h9 += carry8; - h8 -= shl64(carry8, 26); - carry9 = (h9 + (1L << 24)) >> 25; - h0 += carry9 * 19; - h9 -= shl64(carry9, 25); - carry0 = (h0 + (1L << 25)) >> 26; - h1 += carry0; - h0 -= shl64(carry0, 26); - h[0] = (int32_t) h0; - h[1] = (int32_t) h1; - h[2] = (int32_t) h2; - h[3] = (int32_t) h3; - h[4] = (int32_t) h4; - h[5] = (int32_t) h5; - h[6] = (int32_t) h6; - h[7] = (int32_t) h7; - h[8] = (int32_t) h8; - h[9] = (int32_t) h9; + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t f0_2 = 2 * f0; + int32_t f1_2 = 2 * f1; + int32_t f2_2 = 2 * f2; + int32_t f3_2 = 2 * f3; + int32_t f4_2 = 2 * f4; + int32_t f5_2 = 2 * f5; + int32_t f6_2 = 2 * f6; + int32_t f7_2 = 2 * f7; + int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */ + int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */ + int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */ + int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */ + int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */ + int64_t f0f0 = f0 * (int64_t) f0; + int64_t f0f1_2 = f0_2 * (int64_t) f1; + int64_t f0f2_2 = f0_2 * (int64_t) f2; + int64_t f0f3_2 = f0_2 * (int64_t) f3; + int64_t f0f4_2 = f0_2 * (int64_t) f4; + int64_t f0f5_2 = f0_2 * (int64_t) f5; + int64_t f0f6_2 = f0_2 * (int64_t) f6; + int64_t f0f7_2 = f0_2 * (int64_t) f7; + int64_t f0f8_2 = f0_2 * (int64_t) f8; + int64_t f0f9_2 = f0_2 * (int64_t) f9; + int64_t f1f1_2 = f1_2 * (int64_t) f1; + int64_t f1f2_2 = f1_2 * (int64_t) f2; + int64_t f1f3_4 = f1_2 * (int64_t) f3_2; + int64_t f1f4_2 = f1_2 * (int64_t) f4; + int64_t f1f5_4 = f1_2 * (int64_t) f5_2; + int64_t f1f6_2 = f1_2 * (int64_t) f6; + int64_t f1f7_4 = f1_2 * (int64_t) f7_2; + int64_t f1f8_2 = f1_2 * (int64_t) f8; + int64_t f1f9_76 = f1_2 * (int64_t) f9_38; + int64_t f2f2 = f2 * (int64_t) f2; + int64_t f2f3_2 = f2_2 * (int64_t) f3; + int64_t f2f4_2 = f2_2 * (int64_t) f4; + int64_t f2f5_2 = f2_2 * (int64_t) f5; + int64_t f2f6_2 = f2_2 * (int64_t) f6; + int64_t f2f7_2 = f2_2 * (int64_t) f7; + int64_t f2f8_38 = f2_2 * (int64_t) f8_19; + int64_t f2f9_38 = f2 * (int64_t) f9_38; + int64_t f3f3_2 = f3_2 * (int64_t) f3; + int64_t f3f4_2 = f3_2 * (int64_t) f4; + int64_t f3f5_4 = f3_2 * (int64_t) f5_2; + int64_t f3f6_2 = f3_2 * (int64_t) f6; + int64_t f3f7_76 = f3_2 * (int64_t) f7_38; + int64_t f3f8_38 = f3_2 * (int64_t) f8_19; + int64_t f3f9_76 = f3_2 * (int64_t) f9_38; + int64_t f4f4 = f4 * (int64_t) f4; + int64_t f4f5_2 = f4_2 * (int64_t) f5; + int64_t f4f6_38 = f4_2 * (int64_t) f6_19; + int64_t f4f7_38 = f4 * (int64_t) f7_38; + int64_t f4f8_38 = f4_2 * (int64_t) f8_19; + int64_t f4f9_38 = f4 * (int64_t) f9_38; + int64_t f5f5_38 = f5 * (int64_t) f5_38; + int64_t f5f6_38 = f5_2 * (int64_t) f6_19; + int64_t f5f7_76 = f5_2 * (int64_t) f7_38; + int64_t f5f8_38 = f5_2 * (int64_t) f8_19; + int64_t f5f9_76 = f5_2 * (int64_t) f9_38; + int64_t f6f6_19 = f6 * (int64_t) f6_19; + int64_t f6f7_38 = f6 * (int64_t) f7_38; + int64_t f6f8_38 = f6_2 * (int64_t) f8_19; + int64_t f6f9_38 = f6 * (int64_t) f9_38; + int64_t f7f7_38 = f7 * (int64_t) f7_38; + int64_t f7f8_38 = f7_2 * (int64_t) f8_19; + int64_t f7f9_76 = f7_2 * (int64_t) f9_38; + int64_t f8f8_19 = f8 * (int64_t) f8_19; + int64_t f8f9_38 = f8 * (int64_t) f9_38; + int64_t f9f9_38 = f9 * (int64_t) f9_38; + int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38; + int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38; + int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19; + int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38; + int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38; + int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38; + int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19; + int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38; + int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38; + int64_t h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + carry0 = (h0 + (1L << 25)) >> 26; + h1 += carry0; + h0 -= shl64(carry0, 26); + carry4 = (h4 + (1L << 25)) >> 26; + h5 += carry4; + h4 -= shl64(carry4, 26); + carry1 = (h1 + (1L << 24)) >> 25; + h2 += carry1; + h1 -= shl64(carry1, 25); + carry5 = (h5 + (1L << 24)) >> 25; + h6 += carry5; + h5 -= shl64(carry5, 25); + carry2 = (h2 + (1L << 25)) >> 26; + h3 += carry2; + h2 -= shl64(carry2, 26); + carry6 = (h6 + (1L << 25)) >> 26; + h7 += carry6; + h6 -= shl64(carry6, 26); + carry3 = (h3 + (1L << 24)) >> 25; + h4 += carry3; + h3 -= shl64(carry3, 25); + carry7 = (h7 + (1L << 24)) >> 25; + h8 += carry7; + h7 -= shl64(carry7, 25); + carry4 = (h4 + (1L << 25)) >> 26; + h5 += carry4; + h4 -= shl64(carry4, 26); + carry8 = (h8 + (1L << 25)) >> 26; + h9 += carry8; + h8 -= shl64(carry8, 26); + carry9 = (h9 + (1L << 24)) >> 25; + h0 += carry9 * 19; + h9 -= shl64(carry9, 25); + carry0 = (h0 + (1L << 25)) >> 26; + h1 += carry0; + h0 -= shl64(carry0, 26); + h[0] = (int32_t) h0; + h[1] = (int32_t) h1; + h[2] = (int32_t) h2; + h[3] = (int32_t) h3; + h[4] = (int32_t) h4; + h[5] = (int32_t) h5; + h[6] = (int32_t) h6; + h[7] = (int32_t) h7; + h[8] = (int32_t) h8; + h[9] = (int32_t) h9; } @@ -1143,160 +1163,160 @@ See fe_mul.c for discussion of implementation strategy. */ void fe_sq2(fe h, const fe f) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t f0_2 = 2 * f0; - int32_t f1_2 = 2 * f1; - int32_t f2_2 = 2 * f2; - int32_t f3_2 = 2 * f3; - int32_t f4_2 = 2 * f4; - int32_t f5_2 = 2 * f5; - int32_t f6_2 = 2 * f6; - int32_t f7_2 = 2 * f7; - int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */ - int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */ - int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */ - int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */ - int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */ - int64_t f0f0 = f0 * (int64_t) f0; - int64_t f0f1_2 = f0_2 * (int64_t) f1; - int64_t f0f2_2 = f0_2 * (int64_t) f2; - int64_t f0f3_2 = f0_2 * (int64_t) f3; - int64_t f0f4_2 = f0_2 * (int64_t) f4; - int64_t f0f5_2 = f0_2 * (int64_t) f5; - int64_t f0f6_2 = f0_2 * (int64_t) f6; - int64_t f0f7_2 = f0_2 * (int64_t) f7; - int64_t f0f8_2 = f0_2 * (int64_t) f8; - int64_t f0f9_2 = f0_2 * (int64_t) f9; - int64_t f1f1_2 = f1_2 * (int64_t) f1; - int64_t f1f2_2 = f1_2 * (int64_t) f2; - int64_t f1f3_4 = f1_2 * (int64_t) f3_2; - int64_t f1f4_2 = f1_2 * (int64_t) f4; - int64_t f1f5_4 = f1_2 * (int64_t) f5_2; - int64_t f1f6_2 = f1_2 * (int64_t) f6; - int64_t f1f7_4 = f1_2 * (int64_t) f7_2; - int64_t f1f8_2 = f1_2 * (int64_t) f8; - int64_t f1f9_76 = f1_2 * (int64_t) f9_38; - int64_t f2f2 = f2 * (int64_t) f2; - int64_t f2f3_2 = f2_2 * (int64_t) f3; - int64_t f2f4_2 = f2_2 * (int64_t) f4; - int64_t f2f5_2 = f2_2 * (int64_t) f5; - int64_t f2f6_2 = f2_2 * (int64_t) f6; - int64_t f2f7_2 = f2_2 * (int64_t) f7; - int64_t f2f8_38 = f2_2 * (int64_t) f8_19; - int64_t f2f9_38 = f2 * (int64_t) f9_38; - int64_t f3f3_2 = f3_2 * (int64_t) f3; - int64_t f3f4_2 = f3_2 * (int64_t) f4; - int64_t f3f5_4 = f3_2 * (int64_t) f5_2; - int64_t f3f6_2 = f3_2 * (int64_t) f6; - int64_t f3f7_76 = f3_2 * (int64_t) f7_38; - int64_t f3f8_38 = f3_2 * (int64_t) f8_19; - int64_t f3f9_76 = f3_2 * (int64_t) f9_38; - int64_t f4f4 = f4 * (int64_t) f4; - int64_t f4f5_2 = f4_2 * (int64_t) f5; - int64_t f4f6_38 = f4_2 * (int64_t) f6_19; - int64_t f4f7_38 = f4 * (int64_t) f7_38; - int64_t f4f8_38 = f4_2 * (int64_t) f8_19; - int64_t f4f9_38 = f4 * (int64_t) f9_38; - int64_t f5f5_38 = f5 * (int64_t) f5_38; - int64_t f5f6_38 = f5_2 * (int64_t) f6_19; - int64_t f5f7_76 = f5_2 * (int64_t) f7_38; - int64_t f5f8_38 = f5_2 * (int64_t) f8_19; - int64_t f5f9_76 = f5_2 * (int64_t) f9_38; - int64_t f6f6_19 = f6 * (int64_t) f6_19; - int64_t f6f7_38 = f6 * (int64_t) f7_38; - int64_t f6f8_38 = f6_2 * (int64_t) f8_19; - int64_t f6f9_38 = f6 * (int64_t) f9_38; - int64_t f7f7_38 = f7 * (int64_t) f7_38; - int64_t f7f8_38 = f7_2 * (int64_t) f8_19; - int64_t f7f9_76 = f7_2 * (int64_t) f9_38; - int64_t f8f8_19 = f8 * (int64_t) f8_19; - int64_t f8f9_38 = f8 * (int64_t) f9_38; - int64_t f9f9_38 = f9 * (int64_t) f9_38; - int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38; - int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38; - int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19; - int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38; - int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38; - int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38; - int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19; - int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38; - int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38; - int64_t h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - h0 += h0; - h1 += h1; - h2 += h2; - h3 += h3; - h4 += h4; - h5 += h5; - h6 += h6; - h7 += h7; - h8 += h8; - h9 += h9; - carry0 = (h0 + (1L << 25)) >> 26; - h1 += carry0; - h0 -= shl64(carry0, 26); - carry4 = (h4 + (1L << 25)) >> 26; - h5 += carry4; - h4 -= shl64(carry4, 26); - carry1 = (h1 + (1L << 24)) >> 25; - h2 += carry1; - h1 -= shl64(carry1, 25); - carry5 = (h5 + (1L << 24)) >> 25; - h6 += carry5; - h5 -= shl64(carry5, 25); - carry2 = (h2 + (1L << 25)) >> 26; - h3 += carry2; - h2 -= shl64(carry2, 26); - carry6 = (h6 + (1L << 25)) >> 26; - h7 += carry6; - h6 -= shl64(carry6, 26); - carry3 = (h3 + (1L << 24)) >> 25; - h4 += carry3; - h3 -= shl64(carry3, 25); - carry7 = (h7 + (1L << 24)) >> 25; - h8 += carry7; - h7 -= shl64(carry7, 25); - carry4 = (h4 + (1L << 25)) >> 26; - h5 += carry4; - h4 -= shl64(carry4, 26); - carry8 = (h8 + (1L << 25)) >> 26; - h9 += carry8; - h8 -= shl64(carry8, 26); - carry9 = (h9 + (1L << 24)) >> 25; - h0 += carry9 * 19; - h9 -= shl64(carry9, 25); - carry0 = (h0 + (1L << 25)) >> 26; - h1 += carry0; - h0 -= shl64(carry0, 26); - h[0] = (int32_t) h0; - h[1] = (int32_t) h1; - h[2] = (int32_t) h2; - h[3] = (int32_t) h3; - h[4] = (int32_t) h4; - h[5] = (int32_t) h5; - h[6] = (int32_t) h6; - h[7] = (int32_t) h7; - h[8] = (int32_t) h8; - h[9] = (int32_t) h9; + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t f0_2 = 2 * f0; + int32_t f1_2 = 2 * f1; + int32_t f2_2 = 2 * f2; + int32_t f3_2 = 2 * f3; + int32_t f4_2 = 2 * f4; + int32_t f5_2 = 2 * f5; + int32_t f6_2 = 2 * f6; + int32_t f7_2 = 2 * f7; + int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */ + int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */ + int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */ + int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */ + int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */ + int64_t f0f0 = f0 * (int64_t) f0; + int64_t f0f1_2 = f0_2 * (int64_t) f1; + int64_t f0f2_2 = f0_2 * (int64_t) f2; + int64_t f0f3_2 = f0_2 * (int64_t) f3; + int64_t f0f4_2 = f0_2 * (int64_t) f4; + int64_t f0f5_2 = f0_2 * (int64_t) f5; + int64_t f0f6_2 = f0_2 * (int64_t) f6; + int64_t f0f7_2 = f0_2 * (int64_t) f7; + int64_t f0f8_2 = f0_2 * (int64_t) f8; + int64_t f0f9_2 = f0_2 * (int64_t) f9; + int64_t f1f1_2 = f1_2 * (int64_t) f1; + int64_t f1f2_2 = f1_2 * (int64_t) f2; + int64_t f1f3_4 = f1_2 * (int64_t) f3_2; + int64_t f1f4_2 = f1_2 * (int64_t) f4; + int64_t f1f5_4 = f1_2 * (int64_t) f5_2; + int64_t f1f6_2 = f1_2 * (int64_t) f6; + int64_t f1f7_4 = f1_2 * (int64_t) f7_2; + int64_t f1f8_2 = f1_2 * (int64_t) f8; + int64_t f1f9_76 = f1_2 * (int64_t) f9_38; + int64_t f2f2 = f2 * (int64_t) f2; + int64_t f2f3_2 = f2_2 * (int64_t) f3; + int64_t f2f4_2 = f2_2 * (int64_t) f4; + int64_t f2f5_2 = f2_2 * (int64_t) f5; + int64_t f2f6_2 = f2_2 * (int64_t) f6; + int64_t f2f7_2 = f2_2 * (int64_t) f7; + int64_t f2f8_38 = f2_2 * (int64_t) f8_19; + int64_t f2f9_38 = f2 * (int64_t) f9_38; + int64_t f3f3_2 = f3_2 * (int64_t) f3; + int64_t f3f4_2 = f3_2 * (int64_t) f4; + int64_t f3f5_4 = f3_2 * (int64_t) f5_2; + int64_t f3f6_2 = f3_2 * (int64_t) f6; + int64_t f3f7_76 = f3_2 * (int64_t) f7_38; + int64_t f3f8_38 = f3_2 * (int64_t) f8_19; + int64_t f3f9_76 = f3_2 * (int64_t) f9_38; + int64_t f4f4 = f4 * (int64_t) f4; + int64_t f4f5_2 = f4_2 * (int64_t) f5; + int64_t f4f6_38 = f4_2 * (int64_t) f6_19; + int64_t f4f7_38 = f4 * (int64_t) f7_38; + int64_t f4f8_38 = f4_2 * (int64_t) f8_19; + int64_t f4f9_38 = f4 * (int64_t) f9_38; + int64_t f5f5_38 = f5 * (int64_t) f5_38; + int64_t f5f6_38 = f5_2 * (int64_t) f6_19; + int64_t f5f7_76 = f5_2 * (int64_t) f7_38; + int64_t f5f8_38 = f5_2 * (int64_t) f8_19; + int64_t f5f9_76 = f5_2 * (int64_t) f9_38; + int64_t f6f6_19 = f6 * (int64_t) f6_19; + int64_t f6f7_38 = f6 * (int64_t) f7_38; + int64_t f6f8_38 = f6_2 * (int64_t) f8_19; + int64_t f6f9_38 = f6 * (int64_t) f9_38; + int64_t f7f7_38 = f7 * (int64_t) f7_38; + int64_t f7f8_38 = f7_2 * (int64_t) f8_19; + int64_t f7f9_76 = f7_2 * (int64_t) f9_38; + int64_t f8f8_19 = f8 * (int64_t) f8_19; + int64_t f8f9_38 = f8 * (int64_t) f9_38; + int64_t f9f9_38 = f9 * (int64_t) f9_38; + int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38; + int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38; + int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19; + int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38; + int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38; + int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38; + int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19; + int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38; + int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38; + int64_t h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + h0 += h0; + h1 += h1; + h2 += h2; + h3 += h3; + h4 += h4; + h5 += h5; + h6 += h6; + h7 += h7; + h8 += h8; + h9 += h9; + carry0 = (h0 + (1L << 25)) >> 26; + h1 += carry0; + h0 -= shl64(carry0, 26); + carry4 = (h4 + (1L << 25)) >> 26; + h5 += carry4; + h4 -= shl64(carry4, 26); + carry1 = (h1 + (1L << 24)) >> 25; + h2 += carry1; + h1 -= shl64(carry1, 25); + carry5 = (h5 + (1L << 24)) >> 25; + h6 += carry5; + h5 -= shl64(carry5, 25); + carry2 = (h2 + (1L << 25)) >> 26; + h3 += carry2; + h2 -= shl64(carry2, 26); + carry6 = (h6 + (1L << 25)) >> 26; + h7 += carry6; + h6 -= shl64(carry6, 26); + carry3 = (h3 + (1L << 24)) >> 25; + h4 += carry3; + h3 -= shl64(carry3, 25); + carry7 = (h7 + (1L << 24)) >> 25; + h8 += carry7; + h7 -= shl64(carry7, 25); + carry4 = (h4 + (1L << 25)) >> 26; + h5 += carry4; + h4 -= shl64(carry4, 26); + carry8 = (h8 + (1L << 25)) >> 26; + h9 += carry8; + h8 -= shl64(carry8, 26); + carry9 = (h9 + (1L << 24)) >> 25; + h0 += carry9 * 19; + h9 -= shl64(carry9, 25); + carry0 = (h0 + (1L << 25)) >> 26; + h1 += carry0; + h0 -= shl64(carry0, 26); + h[0] = (int32_t) h0; + h[1] = (int32_t) h1; + h[2] = (int32_t) h2; + h[3] = (int32_t) h3; + h[4] = (int32_t) h4; + h[5] = (int32_t) h5; + h[6] = (int32_t) h6; + h[7] = (int32_t) h7; + h[8] = (int32_t) h8; + h[9] = (int32_t) h9; } @@ -1313,47 +1333,47 @@ Postconditions: */ void fe_sub(fe h, const fe f, const fe g) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t g0 = g[0]; - int32_t g1 = g[1]; - int32_t g2 = g[2]; - int32_t g3 = g[3]; - int32_t g4 = g[4]; - int32_t g5 = g[5]; - int32_t g6 = g[6]; - int32_t g7 = g[7]; - int32_t g8 = g[8]; - int32_t g9 = g[9]; - int32_t h0 = f0 - g0; - int32_t h1 = f1 - g1; - int32_t h2 = f2 - g2; - int32_t h3 = f3 - g3; - int32_t h4 = f4 - g4; - int32_t h5 = f5 - g5; - int32_t h6 = f6 - g6; - int32_t h7 = f7 - g7; - int32_t h8 = f8 - g8; - int32_t h9 = f9 - g9; - - h[0] = h0; - h[1] = h1; - h[2] = h2; - h[3] = h3; - h[4] = h4; - h[5] = h5; - h[6] = h6; - h[7] = h7; - h[8] = h8; - h[9] = h9; + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t g0 = g[0]; + int32_t g1 = g[1]; + int32_t g2 = g[2]; + int32_t g3 = g[3]; + int32_t g4 = g[4]; + int32_t g5 = g[5]; + int32_t g6 = g[6]; + int32_t g7 = g[7]; + int32_t g8 = g[8]; + int32_t g9 = g[9]; + int32_t h0 = f0 - g0; + int32_t h1 = f1 - g1; + int32_t h2 = f2 - g2; + int32_t h3 = f3 - g3; + int32_t h4 = f4 - g4; + int32_t h5 = f5 - g5; + int32_t h6 = f6 - g6; + int32_t h7 = f7 - g7; + int32_t h8 = f8 - g8; + int32_t h9 = f9 - g9; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; } @@ -1384,108 +1404,108 @@ Proof: */ void fe_tobytes(unsigned char *s, const fe h) { - int32_t h0 = h[0]; - int32_t h1 = h[1]; - int32_t h2 = h[2]; - int32_t h3 = h[3]; - int32_t h4 = h[4]; - int32_t h5 = h[5]; - int32_t h6 = h[6]; - int32_t h7 = h[7]; - int32_t h8 = h[8]; - int32_t h9 = h[9]; - int32_t q; - int32_t carry0; - int32_t carry1; - int32_t carry2; - int32_t carry3; - int32_t carry4; - int32_t carry5; - int32_t carry6; - int32_t carry7; - int32_t carry8; - int32_t carry9; - q = (19 * h9 + (((int32_t) 1) << 24)) >> 25; - q = (h0 + q) >> 26; - q = (h1 + q) >> 25; - q = (h2 + q) >> 26; - q = (h3 + q) >> 25; - q = (h4 + q) >> 26; - q = (h5 + q) >> 25; - q = (h6 + q) >> 26; - q = (h7 + q) >> 25; - q = (h8 + q) >> 26; - q = (h9 + q) >> 25; - /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */ - h0 += 19 * q; - /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */ - carry0 = h0 >> 26; - h1 += carry0; - h0 -= shl32(carry0, 26); - carry1 = h1 >> 25; - h2 += carry1; - h1 -= shl32(carry1, 25); - carry2 = h2 >> 26; - h3 += carry2; - h2 -= shl32(carry2, 26); - carry3 = h3 >> 25; - h4 += carry3; - h3 -= shl32(carry3, 25); - carry4 = h4 >> 26; - h5 += carry4; - h4 -= shl32(carry4, 26); - carry5 = h5 >> 25; - h6 += carry5; - h5 -= shl32(carry5, 25); - carry6 = h6 >> 26; - h7 += carry6; - h6 -= shl32(carry6, 26); - carry7 = h7 >> 25; - h8 += carry7; - h7 -= shl32(carry7, 25); - carry8 = h8 >> 26; - h9 += carry8; - h8 -= shl32(carry8, 26); - carry9 = h9 >> 25; - h9 -= shl32(carry9, 25); - - /* h10 = carry9 */ - /* - Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. - Have h0+...+2^230 h9 between 0 and 2^255-1; - evidently 2^255 h10-2^255 q = 0. - Goal: Output h0+...+2^230 h9. - */ - s[0] = (unsigned char) (h0 >> 0); - s[1] = (unsigned char) (h0 >> 8); - s[2] = (unsigned char) (h0 >> 16); - s[3] = (unsigned char) ((h0 >> 24) | shl32(h1, 2)); - s[4] = (unsigned char) (h1 >> 6); - s[5] = (unsigned char) (h1 >> 14); - s[6] = (unsigned char) ((h1 >> 22) | shl32(h2, 3)); - s[7] = (unsigned char) (h2 >> 5); - s[8] = (unsigned char) (h2 >> 13); - s[9] = (unsigned char) ((h2 >> 21) | shl32(h3, 5)); - s[10] = (unsigned char) (h3 >> 3); - s[11] = (unsigned char) (h3 >> 11); - s[12] = (unsigned char) ((h3 >> 19) | shl32(h4, 6)); - s[13] = (unsigned char) (h4 >> 2); - s[14] = (unsigned char) (h4 >> 10); - s[15] = (unsigned char) (h4 >> 18); - s[16] = (unsigned char) (h5 >> 0); - s[17] = (unsigned char) (h5 >> 8); - s[18] = (unsigned char) (h5 >> 16); - s[19] = (unsigned char) ((h5 >> 24) | shl32(h6, 1)); - s[20] = (unsigned char) (h6 >> 7); - s[21] = (unsigned char) (h6 >> 15); - s[22] = (unsigned char) ((h6 >> 23) | shl32(h7, 3)); - s[23] = (unsigned char) (h7 >> 5); - s[24] = (unsigned char) (h7 >> 13); - s[25] = (unsigned char) ((h7 >> 21) | shl32(h8, 4)); - s[26] = (unsigned char) (h8 >> 4); - s[27] = (unsigned char) (h8 >> 12); - s[28] = (unsigned char) ((h8 >> 20) | shl32(h9, 6)); - s[29] = (unsigned char) (h9 >> 2); - s[30] = (unsigned char) (h9 >> 10); - s[31] = (unsigned char) (h9 >> 18); + int32_t h0 = h[0]; + int32_t h1 = h[1]; + int32_t h2 = h[2]; + int32_t h3 = h[3]; + int32_t h4 = h[4]; + int32_t h5 = h[5]; + int32_t h6 = h[6]; + int32_t h7 = h[7]; + int32_t h8 = h[8]; + int32_t h9 = h[9]; + int32_t q; + int32_t carry0; + int32_t carry1; + int32_t carry2; + int32_t carry3; + int32_t carry4; + int32_t carry5; + int32_t carry6; + int32_t carry7; + int32_t carry8; + int32_t carry9; + q = (19 * h9 + (((int32_t) 1) << 24)) >> 25; + q = (h0 + q) >> 26; + q = (h1 + q) >> 25; + q = (h2 + q) >> 26; + q = (h3 + q) >> 25; + q = (h4 + q) >> 26; + q = (h5 + q) >> 25; + q = (h6 + q) >> 26; + q = (h7 + q) >> 25; + q = (h8 + q) >> 26; + q = (h9 + q) >> 25; + /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */ + h0 += 19 * q; + /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */ + carry0 = h0 >> 26; + h1 += carry0; + h0 -= shl32(carry0, 26); + carry1 = h1 >> 25; + h2 += carry1; + h1 -= shl32(carry1, 25); + carry2 = h2 >> 26; + h3 += carry2; + h2 -= shl32(carry2, 26); + carry3 = h3 >> 25; + h4 += carry3; + h3 -= shl32(carry3, 25); + carry4 = h4 >> 26; + h5 += carry4; + h4 -= shl32(carry4, 26); + carry5 = h5 >> 25; + h6 += carry5; + h5 -= shl32(carry5, 25); + carry6 = h6 >> 26; + h7 += carry6; + h6 -= shl32(carry6, 26); + carry7 = h7 >> 25; + h8 += carry7; + h7 -= shl32(carry7, 25); + carry8 = h8 >> 26; + h9 += carry8; + h8 -= shl32(carry8, 26); + carry9 = h9 >> 25; + h9 -= shl32(carry9, 25); + + /* h10 = carry9 */ + /* + Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. + Have h0+...+2^230 h9 between 0 and 2^255-1; + evidently 2^255 h10-2^255 q = 0. + Goal: Output h0+...+2^230 h9. + */ + s[0] = (unsigned char)(h0 >> 0); + s[1] = (unsigned char)(h0 >> 8); + s[2] = (unsigned char)(h0 >> 16); + s[3] = (unsigned char)((h0 >> 24) | shl32(h1, 2)); + s[4] = (unsigned char)(h1 >> 6); + s[5] = (unsigned char)(h1 >> 14); + s[6] = (unsigned char)((h1 >> 22) | shl32(h2, 3)); + s[7] = (unsigned char)(h2 >> 5); + s[8] = (unsigned char)(h2 >> 13); + s[9] = (unsigned char)((h2 >> 21) | shl32(h3, 5)); + s[10] = (unsigned char)(h3 >> 3); + s[11] = (unsigned char)(h3 >> 11); + s[12] = (unsigned char)((h3 >> 19) | shl32(h4, 6)); + s[13] = (unsigned char)(h4 >> 2); + s[14] = (unsigned char)(h4 >> 10); + s[15] = (unsigned char)(h4 >> 18); + s[16] = (unsigned char)(h5 >> 0); + s[17] = (unsigned char)(h5 >> 8); + s[18] = (unsigned char)(h5 >> 16); + s[19] = (unsigned char)((h5 >> 24) | shl32(h6, 1)); + s[20] = (unsigned char)(h6 >> 7); + s[21] = (unsigned char)(h6 >> 15); + s[22] = (unsigned char)((h6 >> 23) | shl32(h7, 3)); + s[23] = (unsigned char)(h7 >> 5); + s[24] = (unsigned char)(h7 >> 13); + s[25] = (unsigned char)((h7 >> 21) | shl32(h8, 4)); + s[26] = (unsigned char)(h8 >> 4); + s[27] = (unsigned char)(h8 >> 12); + s[28] = (unsigned char)((h8 >> 20) | shl32(h9, 6)); + s[29] = (unsigned char)(h9 >> 2); + s[30] = (unsigned char)(h9 >> 10); + s[31] = (unsigned char)(h9 >> 18); } diff --git a/src/ed25519/fixedint.h b/src/ed25519/fixedint.h index e9f973c..af031e9 100644 --- a/src/ed25519/fixedint.h +++ b/src/ed25519/fixedint.h @@ -8,68 +8,68 @@ */ #if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined(__WATCOMC__) && (defined(_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_) || defined(__UINT_FAST64_TYPE__)) )) && !defined(FIXEDINT_H_INCLUDED) - #include - #define FIXEDINT_H_INCLUDED +#include +#define FIXEDINT_H_INCLUDED - #if defined(__WATCOMC__) && __WATCOMC__ >= 1250 && !defined(UINT64_C) - #include - #define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX)) - #endif +#if defined(__WATCOMC__) && __WATCOMC__ >= 1250 && !defined(UINT64_C) +#include +#define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX)) +#endif #endif #ifndef FIXEDINT_H_INCLUDED - #define FIXEDINT_H_INCLUDED - - /* (u)int32_t */ - #ifndef uint32_t - #if (ULONG_MAX == 0xffffffffUL) - typedef unsigned long uint32_t; - #elif (UINT_MAX == 0xffffffffUL) - typedef unsigned int uint32_t; - #elif (USHRT_MAX == 0xffffffffUL) - typedef unsigned short uint32_t; - #endif - #endif - - - #ifndef int32_t - #if (LONG_MAX == 0x7fffffffL) - typedef signed long int32_t; - #elif (INT_MAX == 0x7fffffffL) - typedef signed int int32_t; - #elif (SHRT_MAX == 0x7fffffffL) - typedef signed short int32_t; - #endif - #endif - - - /* (u)int64_t */ - #if (defined(__STDC__) && defined(__STDC_VERSION__) && __STDC__ && __STDC_VERSION__ >= 199901L) - typedef long long int64_t; - typedef unsigned long long uint64_t; - - #define UINT64_C(v) v ##ULL - #define INT64_C(v) v ##LL - #elif defined(__GNUC__) - __extension__ typedef long long int64_t; - __extension__ typedef unsigned long long uint64_t; - - #define UINT64_C(v) v ##ULL - #define INT64_C(v) v ##LL - #elif defined(__MWERKS__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__APPLE_CC__) || defined(_LONG_LONG) || defined(_CRAYC) - typedef long long int64_t; - typedef unsigned long long uint64_t; - - #define UINT64_C(v) v ##ULL - #define INT64_C(v) v ##LL - #elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined(__BORLANDC__) && __BORLANDC__ > 0x460) || defined(__alpha) || defined(__DECC) - typedef __int64 int64_t; - typedef unsigned __int64 uint64_t; - - #define UINT64_C(v) v ##UI64 - #define INT64_C(v) v ##I64 - #endif +#define FIXEDINT_H_INCLUDED + +/* (u)int32_t */ +#ifndef uint32_t +#if (ULONG_MAX == 0xffffffffUL) +typedef unsigned long uint32_t; +#elif (UINT_MAX == 0xffffffffUL) +typedef unsigned int uint32_t; +#elif (USHRT_MAX == 0xffffffffUL) +typedef unsigned short uint32_t; +#endif +#endif + + +#ifndef int32_t +#if (LONG_MAX == 0x7fffffffL) +typedef signed long int32_t; +#elif (INT_MAX == 0x7fffffffL) +typedef signed int int32_t; +#elif (SHRT_MAX == 0x7fffffffL) +typedef signed short int32_t; +#endif +#endif + + +/* (u)int64_t */ +#if (defined(__STDC__) && defined(__STDC_VERSION__) && __STDC__ && __STDC_VERSION__ >= 199901L) +typedef long long int64_t; +typedef unsigned long long uint64_t; + +#define UINT64_C(v) v ##ULL +#define INT64_C(v) v ##LL +#elif defined(__GNUC__) +__extension__ typedef long long int64_t; +__extension__ typedef unsigned long long uint64_t; + +#define UINT64_C(v) v ##ULL +#define INT64_C(v) v ##LL +#elif defined(__MWERKS__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__APPLE_CC__) || defined(_LONG_LONG) || defined(_CRAYC) +typedef long long int64_t; +typedef unsigned long long uint64_t; + +#define UINT64_C(v) v ##ULL +#define INT64_C(v) v ##LL +#elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined(__BORLANDC__) && __BORLANDC__ > 0x460) || defined(__alpha) || defined(__DECC) +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; + +#define UINT64_C(v) v ##UI64 +#define INT64_C(v) v ##I64 +#endif #endif static inline unsigned char shlu8(unsigned char a, uint32_t b) { diff --git a/src/ed25519/ge.c b/src/ed25519/ge.c index 9488218..a69ed9d 100644 --- a/src/ed25519/ge.c +++ b/src/ed25519/ge.c @@ -7,54 +7,54 @@ r = p + q */ void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) { - fe t0; - fe_add(r->X, p->Y, p->X); - fe_sub(r->Y, p->Y, p->X); - fe_mul(r->Z, r->X, q->YplusX); - fe_mul(r->Y, r->Y, q->YminusX); - fe_mul(r->T, q->T2d, p->T); - fe_mul(r->X, p->Z, q->Z); - fe_add(t0, r->X, r->X); - fe_sub(r->X, r->Z, r->Y); - fe_add(r->Y, r->Z, r->Y); - fe_add(r->Z, t0, r->T); - fe_sub(r->T, t0, r->T); + fe t0; + fe_add(r->X, p->Y, p->X); + fe_sub(r->Y, p->Y, p->X); + fe_mul(r->Z, r->X, q->YplusX); + fe_mul(r->Y, r->Y, q->YminusX); + fe_mul(r->T, q->T2d, p->T); + fe_mul(r->X, p->Z, q->Z); + fe_add(t0, r->X, r->X); + fe_sub(r->X, r->Z, r->Y); + fe_add(r->Y, r->Z, r->Y); + fe_add(r->Z, t0, r->T); + fe_sub(r->T, t0, r->T); } static void slide(signed char *r, const unsigned char *a) { - int i; - int b; - int k; - - for (i = 0; i < 256; ++i) { - r[i] = 1 & (a[i >> 3] >> (i & 7)); - } - - for (i = 0; i < 256; ++i) - if (r[i]) { - for (b = 1; b <= 6 && i + b < 256; ++b) { - if (r[i + b]) { - if (r[i] + (r[i + b] << b) <= 15) { - r[i] += r[i + b] << b; - r[i + b] = 0; - } else if (r[i] - (r[i + b] << b) >= -15) { - r[i] -= r[i + b] << b; - - for (k = i + b; k < 256; ++k) { - if (!r[k]) { - r[k] = 1; - break; - } - - r[k] = 0; - } - } else { - break; - } - } - } - } + int i; + int b; + int k; + + for(i = 0; i < 256; ++i) { + r[i] = 1 & (a[i >> 3] >> (i & 7)); + } + + for(i = 0; i < 256; ++i) + if(r[i]) { + for(b = 1; b <= 6 && i + b < 256; ++b) { + if(r[i + b]) { + if(r[i] + (r[i + b] << b) <= 15) { + r[i] += r[i + b] << b; + r[i + b] = 0; + } else if(r[i] - (r[i + b] << b) >= -15) { + r[i] -= r[i + b] << b; + + for(k = i + b; k < 256; ++k) { + if(!r[k]) { + r[k] = 1; + break; + } + + r[k] = 0; + } + } else { + break; + } + } + } + } } /* @@ -65,119 +65,119 @@ B is the Ed25519 base point (x,4/5) with x positive. */ void ge_double_scalarmult_vartime(ge_p2 *r, const unsigned char *a, const ge_p3 *A, const unsigned char *b) { - signed char aslide[256]; - signed char bslide[256]; - ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */ - ge_p1p1 t; - ge_p3 u; - ge_p3 A2; - int i; - slide(aslide, a); - slide(bslide, b); - ge_p3_to_cached(&Ai[0], A); - ge_p3_dbl(&t, A); - ge_p1p1_to_p3(&A2, &t); - ge_add(&t, &A2, &Ai[0]); - ge_p1p1_to_p3(&u, &t); - ge_p3_to_cached(&Ai[1], &u); - ge_add(&t, &A2, &Ai[1]); - ge_p1p1_to_p3(&u, &t); - ge_p3_to_cached(&Ai[2], &u); - ge_add(&t, &A2, &Ai[2]); - ge_p1p1_to_p3(&u, &t); - ge_p3_to_cached(&Ai[3], &u); - ge_add(&t, &A2, &Ai[3]); - ge_p1p1_to_p3(&u, &t); - ge_p3_to_cached(&Ai[4], &u); - ge_add(&t, &A2, &Ai[4]); - ge_p1p1_to_p3(&u, &t); - ge_p3_to_cached(&Ai[5], &u); - ge_add(&t, &A2, &Ai[5]); - ge_p1p1_to_p3(&u, &t); - ge_p3_to_cached(&Ai[6], &u); - ge_add(&t, &A2, &Ai[6]); - ge_p1p1_to_p3(&u, &t); - ge_p3_to_cached(&Ai[7], &u); - ge_p2_0(r); - - for (i = 255; i >= 0; --i) { - if (aslide[i] || bslide[i]) { - break; - } - } - - for (; i >= 0; --i) { - ge_p2_dbl(&t, r); - - if (aslide[i] > 0) { - ge_p1p1_to_p3(&u, &t); - ge_add(&t, &u, &Ai[aslide[i] / 2]); - } else if (aslide[i] < 0) { - ge_p1p1_to_p3(&u, &t); - ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]); - } - - if (bslide[i] > 0) { - ge_p1p1_to_p3(&u, &t); - ge_madd(&t, &u, &Bi[bslide[i] / 2]); - } else if (bslide[i] < 0) { - ge_p1p1_to_p3(&u, &t); - ge_msub(&t, &u, &Bi[(-bslide[i]) / 2]); - } - - ge_p1p1_to_p2(r, &t); - } + signed char aslide[256]; + signed char bslide[256]; + ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */ + ge_p1p1 t; + ge_p3 u; + ge_p3 A2; + int i; + slide(aslide, a); + slide(bslide, b); + ge_p3_to_cached(&Ai[0], A); + ge_p3_dbl(&t, A); + ge_p1p1_to_p3(&A2, &t); + ge_add(&t, &A2, &Ai[0]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[1], &u); + ge_add(&t, &A2, &Ai[1]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[2], &u); + ge_add(&t, &A2, &Ai[2]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[3], &u); + ge_add(&t, &A2, &Ai[3]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[4], &u); + ge_add(&t, &A2, &Ai[4]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[5], &u); + ge_add(&t, &A2, &Ai[5]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[6], &u); + ge_add(&t, &A2, &Ai[6]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[7], &u); + ge_p2_0(r); + + for(i = 255; i >= 0; --i) { + if(aslide[i] || bslide[i]) { + break; + } + } + + for(; i >= 0; --i) { + ge_p2_dbl(&t, r); + + if(aslide[i] > 0) { + ge_p1p1_to_p3(&u, &t); + ge_add(&t, &u, &Ai[aslide[i] / 2]); + } else if(aslide[i] < 0) { + ge_p1p1_to_p3(&u, &t); + ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]); + } + + if(bslide[i] > 0) { + ge_p1p1_to_p3(&u, &t); + ge_madd(&t, &u, &Bi[bslide[i] / 2]); + } else if(bslide[i] < 0) { + ge_p1p1_to_p3(&u, &t); + ge_msub(&t, &u, &Bi[(-bslide[i]) / 2]); + } + + ge_p1p1_to_p2(r, &t); + } } static const fe d = { - -10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116 + -10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116 }; static const fe sqrtm1 = { - -32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482 + -32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482 }; int ge_frombytes_negate_vartime(ge_p3 *h, const unsigned char *s) { - fe u; - fe v; - fe v3; - fe vxx; - fe check; - fe_frombytes(h->Y, s); - fe_1(h->Z); - fe_sq(u, h->Y); - fe_mul(v, u, d); - fe_sub(u, u, h->Z); /* u = y^2-1 */ - fe_add(v, v, h->Z); /* v = dy^2+1 */ - fe_sq(v3, v); - fe_mul(v3, v3, v); /* v3 = v^3 */ - fe_sq(h->X, v3); - fe_mul(h->X, h->X, v); - fe_mul(h->X, h->X, u); /* x = uv^7 */ - fe_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */ - fe_mul(h->X, h->X, v3); - fe_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */ - fe_sq(vxx, h->X); - fe_mul(vxx, vxx, v); - fe_sub(check, vxx, u); /* vx^2-u */ - - if (fe_isnonzero(check)) { - fe_add(check, vxx, u); /* vx^2+u */ - - if (fe_isnonzero(check)) { - return -1; - } - - fe_mul(h->X, h->X, sqrtm1); - } - - if (fe_isnegative(h->X) == (s[31] >> 7)) { - fe_neg(h->X, h->X); - } - - fe_mul(h->T, h->X, h->Y); - return 0; + fe u; + fe v; + fe v3; + fe vxx; + fe check; + fe_frombytes(h->Y, s); + fe_1(h->Z); + fe_sq(u, h->Y); + fe_mul(v, u, d); + fe_sub(u, u, h->Z); /* u = y^2-1 */ + fe_add(v, v, h->Z); /* v = dy^2+1 */ + fe_sq(v3, v); + fe_mul(v3, v3, v); /* v3 = v^3 */ + fe_sq(h->X, v3); + fe_mul(h->X, h->X, v); + fe_mul(h->X, h->X, u); /* x = uv^7 */ + fe_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */ + fe_mul(h->X, h->X, v3); + fe_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */ + fe_sq(vxx, h->X); + fe_mul(vxx, vxx, v); + fe_sub(check, vxx, u); /* vx^2-u */ + + if(fe_isnonzero(check)) { + fe_add(check, vxx, u); /* vx^2+u */ + + if(fe_isnonzero(check)) { + return -1; + } + + fe_mul(h->X, h->X, sqrtm1); + } + + if(fe_isnegative(h->X) == (s[31] >> 7)) { + fe_neg(h->X, h->X); + } + + fe_mul(h->T, h->X, h->Y); + return 0; } @@ -186,17 +186,17 @@ r = p + q */ void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) { - fe t0; - fe_add(r->X, p->Y, p->X); - fe_sub(r->Y, p->Y, p->X); - fe_mul(r->Z, r->X, q->yplusx); - fe_mul(r->Y, r->Y, q->yminusx); - fe_mul(r->T, q->xy2d, p->T); - fe_add(t0, p->Z, p->Z); - fe_sub(r->X, r->Z, r->Y); - fe_add(r->Y, r->Z, r->Y); - fe_add(r->Z, t0, r->T); - fe_sub(r->T, t0, r->T); + fe t0; + fe_add(r->X, p->Y, p->X); + fe_sub(r->Y, p->Y, p->X); + fe_mul(r->Z, r->X, q->yplusx); + fe_mul(r->Y, r->Y, q->yminusx); + fe_mul(r->T, q->xy2d, p->T); + fe_add(t0, p->Z, p->Z); + fe_sub(r->X, r->Z, r->Y); + fe_add(r->Y, r->Z, r->Y); + fe_add(r->Z, t0, r->T); + fe_sub(r->T, t0, r->T); } @@ -205,18 +205,18 @@ r = p - q */ void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) { - fe t0; - - fe_add(r->X, p->Y, p->X); - fe_sub(r->Y, p->Y, p->X); - fe_mul(r->Z, r->X, q->yminusx); - fe_mul(r->Y, r->Y, q->yplusx); - fe_mul(r->T, q->xy2d, p->T); - fe_add(t0, p->Z, p->Z); - fe_sub(r->X, r->Z, r->Y); - fe_add(r->Y, r->Z, r->Y); - fe_sub(r->Z, t0, r->T); - fe_add(r->T, t0, r->T); + fe t0; + + fe_add(r->X, p->Y, p->X); + fe_sub(r->Y, p->Y, p->X); + fe_mul(r->Z, r->X, q->yminusx); + fe_mul(r->Y, r->Y, q->yplusx); + fe_mul(r->T, q->xy2d, p->T); + fe_add(t0, p->Z, p->Z); + fe_sub(r->X, r->Z, r->Y); + fe_add(r->Y, r->Z, r->Y); + fe_sub(r->Z, t0, r->T); + fe_add(r->T, t0, r->T); } @@ -225,9 +225,9 @@ r = p */ void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) { - fe_mul(r->X, p->X, p->T); - fe_mul(r->Y, p->Y, p->Z); - fe_mul(r->Z, p->Z, p->T); + fe_mul(r->X, p->X, p->T); + fe_mul(r->Y, p->Y, p->Z); + fe_mul(r->Z, p->Z, p->T); } @@ -237,17 +237,17 @@ r = p */ void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p) { - fe_mul(r->X, p->X, p->T); - fe_mul(r->Y, p->Y, p->Z); - fe_mul(r->Z, p->Z, p->T); - fe_mul(r->T, p->X, p->Y); + fe_mul(r->X, p->X, p->T); + fe_mul(r->Y, p->Y, p->Z); + fe_mul(r->Z, p->Z, p->T); + fe_mul(r->T, p->X, p->Y); } void ge_p2_0(ge_p2 *h) { - fe_0(h->X); - fe_1(h->Y); - fe_1(h->Z); + fe_0(h->X); + fe_1(h->Y); + fe_1(h->Z); } @@ -257,25 +257,25 @@ r = 2 * p */ void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) { - fe t0; - - fe_sq(r->X, p->X); - fe_sq(r->Z, p->Y); - fe_sq2(r->T, p->Z); - fe_add(r->Y, p->X, p->Y); - fe_sq(t0, r->Y); - fe_add(r->Y, r->Z, r->X); - fe_sub(r->Z, r->Z, r->X); - fe_sub(r->X, t0, r->Y); - fe_sub(r->T, r->T, r->Z); + fe t0; + + fe_sq(r->X, p->X); + fe_sq(r->Z, p->Y); + fe_sq2(r->T, p->Z); + fe_add(r->Y, p->X, p->Y); + fe_sq(t0, r->Y); + fe_add(r->Y, r->Z, r->X); + fe_sub(r->Z, r->Z, r->X); + fe_sub(r->X, t0, r->Y); + fe_sub(r->T, r->T, r->Z); } void ge_p3_0(ge_p3 *h) { - fe_0(h->X); - fe_1(h->Y); - fe_1(h->Z); - fe_0(h->T); + fe_0(h->X); + fe_1(h->Y); + fe_1(h->Z); + fe_0(h->T); } @@ -284,9 +284,9 @@ r = 2 * p */ void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p) { - ge_p2 q; - ge_p3_to_p2(&q, p); - ge_p2_dbl(r, &q); + ge_p2 q; + ge_p3_to_p2(&q, p); + ge_p2_dbl(r, &q); } @@ -296,14 +296,14 @@ r = p */ static const fe d2 = { - -21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199 + -21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199 }; void ge_p3_to_cached(ge_cached *r, const ge_p3 *p) { - fe_add(r->YplusX, p->Y, p->X); - fe_sub(r->YminusX, p->Y, p->X); - fe_copy(r->Z, p->Z); - fe_mul(r->T2d, p->T, d2); + fe_add(r->YplusX, p->Y, p->X); + fe_sub(r->YminusX, p->Y, p->X); + fe_copy(r->Z, p->Z); + fe_mul(r->T2d, p->T, d2); } @@ -312,66 +312,66 @@ r = p */ void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p) { - fe_copy(r->X, p->X); - fe_copy(r->Y, p->Y); - fe_copy(r->Z, p->Z); + fe_copy(r->X, p->X); + fe_copy(r->Y, p->Y); + fe_copy(r->Z, p->Z); } void ge_p3_tobytes(unsigned char *s, const ge_p3 *h) { - fe recip; - fe x; - fe y; - fe_invert(recip, h->Z); - fe_mul(x, h->X, recip); - fe_mul(y, h->Y, recip); - fe_tobytes(s, y); - s[31] ^= fe_isnegative(x) << 7; + fe recip; + fe x; + fe y; + fe_invert(recip, h->Z); + fe_mul(x, h->X, recip); + fe_mul(y, h->Y, recip); + fe_tobytes(s, y); + s[31] ^= fe_isnegative(x) << 7; } static unsigned char equal(signed char b, signed char c) { - unsigned char ub = b; - unsigned char uc = c; - unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */ - uint64_t y = x; /* 0: yes; 1..255: no */ - y -= 1; /* large: yes; 0..254: no */ - y >>= 63; /* 1: yes; 0: no */ - return (unsigned char) y; + unsigned char ub = b; + unsigned char uc = c; + unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */ + uint64_t y = x; /* 0: yes; 1..255: no */ + y -= 1; /* large: yes; 0..254: no */ + y >>= 63; /* 1: yes; 0: no */ + return (unsigned char) y; } static unsigned char negative(signed char b) { - uint64_t x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ - x >>= 63; /* 1: yes; 0: no */ - return (unsigned char) x; + uint64_t x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ + x >>= 63; /* 1: yes; 0: no */ + return (unsigned char) x; } static void cmov(ge_precomp *t, ge_precomp *u, unsigned char b) { - fe_cmov(t->yplusx, u->yplusx, b); - fe_cmov(t->yminusx, u->yminusx, b); - fe_cmov(t->xy2d, u->xy2d, b); + fe_cmov(t->yplusx, u->yplusx, b); + fe_cmov(t->yminusx, u->yminusx, b); + fe_cmov(t->xy2d, u->xy2d, b); } static void select(ge_precomp *t, int pos, signed char b) { - ge_precomp minust; - unsigned char bnegative = negative(b); - unsigned char babs = b - shlu8(((-bnegative) & b), 1); - fe_1(t->yplusx); - fe_1(t->yminusx); - fe_0(t->xy2d); - cmov(t, &base[pos][0], equal(babs, 1)); - cmov(t, &base[pos][1], equal(babs, 2)); - cmov(t, &base[pos][2], equal(babs, 3)); - cmov(t, &base[pos][3], equal(babs, 4)); - cmov(t, &base[pos][4], equal(babs, 5)); - cmov(t, &base[pos][5], equal(babs, 6)); - cmov(t, &base[pos][6], equal(babs, 7)); - cmov(t, &base[pos][7], equal(babs, 8)); - fe_copy(minust.yplusx, t->yminusx); - fe_copy(minust.yminusx, t->yplusx); - fe_neg(minust.xy2d, t->xy2d); - cmov(t, &minust, bnegative); + ge_precomp minust; + unsigned char bnegative = negative(b); + unsigned char babs = b - shlu8(((-bnegative) & b), 1); + fe_1(t->yplusx); + fe_1(t->yminusx); + fe_0(t->xy2d); + cmov(t, &base[pos][0], equal(babs, 1)); + cmov(t, &base[pos][1], equal(babs, 2)); + cmov(t, &base[pos][2], equal(babs, 3)); + cmov(t, &base[pos][3], equal(babs, 4)); + cmov(t, &base[pos][4], equal(babs, 5)); + cmov(t, &base[pos][5], equal(babs, 6)); + cmov(t, &base[pos][6], equal(babs, 7)); + cmov(t, &base[pos][7], equal(babs, 8)); + fe_copy(minust.yplusx, t->yminusx); + fe_copy(minust.yminusx, t->yplusx); + fe_neg(minust.xy2d, t->xy2d); + cmov(t, &minust, bnegative); } /* @@ -384,53 +384,53 @@ Preconditions: */ void ge_scalarmult_base(ge_p3 *h, const unsigned char *a) { - signed char e[64]; - signed char carry; - ge_p1p1 r; - ge_p2 s; - ge_precomp t; - int i; - - for (i = 0; i < 32; ++i) { - e[2 * i + 0] = (a[i] >> 0) & 15; - e[2 * i + 1] = (a[i] >> 4) & 15; - } - - /* each e[i] is between 0 and 15 */ - /* e[63] is between 0 and 7 */ - carry = 0; - - for (i = 0; i < 63; ++i) { - e[i] += carry; - carry = e[i] + 8; - carry >>= 4; - e[i] -= shl32(carry, 4); - } - - e[63] += carry; - /* each e[i] is between -8 and 8 */ - ge_p3_0(h); - - for (i = 1; i < 64; i += 2) { - select(&t, i / 2, e[i]); - ge_madd(&r, h, &t); - ge_p1p1_to_p3(h, &r); - } - - ge_p3_dbl(&r, h); - ge_p1p1_to_p2(&s, &r); - ge_p2_dbl(&r, &s); - ge_p1p1_to_p2(&s, &r); - ge_p2_dbl(&r, &s); - ge_p1p1_to_p2(&s, &r); - ge_p2_dbl(&r, &s); - ge_p1p1_to_p3(h, &r); - - for (i = 0; i < 64; i += 2) { - select(&t, i / 2, e[i]); - ge_madd(&r, h, &t); - ge_p1p1_to_p3(h, &r); - } + signed char e[64]; + signed char carry; + ge_p1p1 r; + ge_p2 s; + ge_precomp t; + int i; + + for(i = 0; i < 32; ++i) { + e[2 * i + 0] = (a[i] >> 0) & 15; + e[2 * i + 1] = (a[i] >> 4) & 15; + } + + /* each e[i] is between 0 and 15 */ + /* e[63] is between 0 and 7 */ + carry = 0; + + for(i = 0; i < 63; ++i) { + e[i] += carry; + carry = e[i] + 8; + carry >>= 4; + e[i] -= shl32(carry, 4); + } + + e[63] += carry; + /* each e[i] is between -8 and 8 */ + ge_p3_0(h); + + for(i = 1; i < 64; i += 2) { + select(&t, i / 2, e[i]); + ge_madd(&r, h, &t); + ge_p1p1_to_p3(h, &r); + } + + ge_p3_dbl(&r, h); + ge_p1p1_to_p2(&s, &r); + ge_p2_dbl(&r, &s); + ge_p1p1_to_p2(&s, &r); + ge_p2_dbl(&r, &s); + ge_p1p1_to_p2(&s, &r); + ge_p2_dbl(&r, &s); + ge_p1p1_to_p3(h, &r); + + for(i = 0; i < 64; i += 2) { + select(&t, i / 2, e[i]); + ge_madd(&r, h, &t); + ge_p1p1_to_p3(h, &r); + } } @@ -439,29 +439,29 @@ r = p - q */ void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) { - fe t0; - - fe_add(r->X, p->Y, p->X); - fe_sub(r->Y, p->Y, p->X); - fe_mul(r->Z, r->X, q->YminusX); - fe_mul(r->Y, r->Y, q->YplusX); - fe_mul(r->T, q->T2d, p->T); - fe_mul(r->X, p->Z, q->Z); - fe_add(t0, r->X, r->X); - fe_sub(r->X, r->Z, r->Y); - fe_add(r->Y, r->Z, r->Y); - fe_sub(r->Z, t0, r->T); - fe_add(r->T, t0, r->T); + fe t0; + + fe_add(r->X, p->Y, p->X); + fe_sub(r->Y, p->Y, p->X); + fe_mul(r->Z, r->X, q->YminusX); + fe_mul(r->Y, r->Y, q->YplusX); + fe_mul(r->T, q->T2d, p->T); + fe_mul(r->X, p->Z, q->Z); + fe_add(t0, r->X, r->X); + fe_sub(r->X, r->Z, r->Y); + fe_add(r->Y, r->Z, r->Y); + fe_sub(r->Z, t0, r->T); + fe_add(r->T, t0, r->T); } void ge_tobytes(unsigned char *s, const ge_p2 *h) { - fe recip; - fe x; - fe y; - fe_invert(recip, h->Z); - fe_mul(x, h->X, recip); - fe_mul(y, h->Y, recip); - fe_tobytes(s, y); - s[31] ^= fe_isnegative(x) << 7; + fe recip; + fe x; + fe y; + fe_invert(recip, h->Z); + fe_mul(x, h->X, recip); + fe_mul(y, h->Y, recip); + fe_tobytes(s, y); + s[31] ^= fe_isnegative(x) << 7; } diff --git a/src/ed25519/ge.h b/src/ed25519/ge.h index 17fde2d..9cc3b98 100644 --- a/src/ed25519/ge.h +++ b/src/ed25519/ge.h @@ -19,36 +19,36 @@ Representations: */ typedef struct { - fe X; - fe Y; - fe Z; + fe X; + fe Y; + fe Z; } ge_p2; typedef struct { - fe X; - fe Y; - fe Z; - fe T; + fe X; + fe Y; + fe Z; + fe T; } ge_p3; typedef struct { - fe X; - fe Y; - fe Z; - fe T; + fe X; + fe Y; + fe Z; + fe T; } ge_p1p1; typedef struct { - fe yplusx; - fe yminusx; - fe xy2d; + fe yplusx; + fe yminusx; + fe xy2d; } ge_precomp; typedef struct { - fe YplusX; - fe YminusX; - fe Z; - fe T2d; + fe YplusX; + fe YminusX; + fe Z; + fe T2d; } ge_cached; void ge_p3_tobytes(unsigned char *s, const ge_p3 *h); diff --git a/src/ed25519/key_exchange.c b/src/ed25519/key_exchange.c index abd75da..9ace86b 100644 --- a/src/ed25519/key_exchange.c +++ b/src/ed25519/key_exchange.c @@ -2,78 +2,79 @@ #include "fe.h" void ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *public_key, const unsigned char *private_key) { - unsigned char e[32]; - unsigned int i; - - fe x1; - fe x2; - fe z2; - fe x3; - fe z3; - fe tmp0; - fe tmp1; + unsigned char e[32]; + unsigned int i; - int pos; - unsigned int swap; - unsigned int b; + fe x1; + fe x2; + fe z2; + fe x3; + fe z3; + fe tmp0; + fe tmp1; - /* copy the private key and make sure it's valid */ - for (i = 0; i < 32; ++i) { - e[i] = private_key[i]; - } + int pos; + unsigned int swap; + unsigned int b; - e[0] &= 248; - e[31] &= 63; - e[31] |= 64; + /* copy the private key and make sure it's valid */ + for(i = 0; i < 32; ++i) { + e[i] = private_key[i]; + } - /* unpack the public key and convert edwards to montgomery */ - /* due to CodesInChaos: montgomeryX = (edwardsY + 1)*inverse(1 - edwardsY) mod p */ - fe_frombytes(x1, public_key); - fe_1(tmp1); - fe_add(tmp0, x1, tmp1); - fe_sub(tmp1, tmp1, x1); - fe_invert(tmp1, tmp1); - fe_mul(x1, tmp0, tmp1); + e[0] &= 248; + e[31] &= 63; + e[31] |= 64; - fe_1(x2); - fe_0(z2); - fe_copy(x3, x1); - fe_1(z3); + /* unpack the public key and convert edwards to montgomery */ + /* due to CodesInChaos: montgomeryX = (edwardsY + 1)*inverse(1 - edwardsY) mod p */ + fe_frombytes(x1, public_key); + fe_1(tmp1); + fe_add(tmp0, x1, tmp1); + fe_sub(tmp1, tmp1, x1); + fe_invert(tmp1, tmp1); + fe_mul(x1, tmp0, tmp1); - swap = 0; - for (pos = 254; pos >= 0; --pos) { - b = e[pos / 8] >> (pos & 7); - b &= 1; - swap ^= b; - fe_cswap(x2, x3, swap); - fe_cswap(z2, z3, swap); - swap = b; + fe_1(x2); + fe_0(z2); + fe_copy(x3, x1); + fe_1(z3); - /* from montgomery.h */ - fe_sub(tmp0, x3, z3); - fe_sub(tmp1, x2, z2); - fe_add(x2, x2, z2); - fe_add(z2, x3, z3); - fe_mul(z3, tmp0, x2); - fe_mul(z2, z2, tmp1); - fe_sq(tmp0, tmp1); - fe_sq(tmp1, x2); - fe_add(x3, z3, z2); - fe_sub(z2, z3, z2); - fe_mul(x2, tmp1, tmp0); - fe_sub(tmp1, tmp1, tmp0); - fe_sq(z2, z2); - fe_mul121666(z3, tmp1); - fe_sq(x3, x3); - fe_add(tmp0, tmp0, z3); - fe_mul(z3, x1, z2); - fe_mul(z2, tmp1, tmp0); - } + swap = 0; - fe_cswap(x2, x3, swap); - fe_cswap(z2, z3, swap); + for(pos = 254; pos >= 0; --pos) { + b = e[pos / 8] >> (pos & 7); + b &= 1; + swap ^= b; + fe_cswap(x2, x3, swap); + fe_cswap(z2, z3, swap); + swap = b; - fe_invert(z2, z2); - fe_mul(x2, x2, z2); - fe_tobytes(shared_secret, x2); + /* from montgomery.h */ + fe_sub(tmp0, x3, z3); + fe_sub(tmp1, x2, z2); + fe_add(x2, x2, z2); + fe_add(z2, x3, z3); + fe_mul(z3, tmp0, x2); + fe_mul(z2, z2, tmp1); + fe_sq(tmp0, tmp1); + fe_sq(tmp1, x2); + fe_add(x3, z3, z2); + fe_sub(z2, z3, z2); + fe_mul(x2, tmp1, tmp0); + fe_sub(tmp1, tmp1, tmp0); + fe_sq(z2, z2); + fe_mul121666(z3, tmp1); + fe_sq(x3, x3); + fe_add(tmp0, tmp0, z3); + fe_mul(z3, x1, z2); + fe_mul(z2, tmp1, tmp0); + } + + fe_cswap(x2, x3, swap); + fe_cswap(z2, z3, swap); + + fe_invert(z2, z2); + fe_mul(x2, x2, z2); + fe_tobytes(shared_secret, x2); } diff --git a/src/ed25519/keypair.c b/src/ed25519/keypair.c index dc1b8ec..71ec4d7 100644 --- a/src/ed25519/keypair.c +++ b/src/ed25519/keypair.c @@ -4,13 +4,13 @@ void ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed) { - ge_p3 A; + ge_p3 A; - sha512(seed, 32, private_key); - private_key[0] &= 248; - private_key[31] &= 63; - private_key[31] |= 64; + sha512(seed, 32, private_key); + private_key[0] &= 248; + private_key[31] &= 63; + private_key[31] |= 64; - ge_scalarmult_base(&A, private_key); - ge_p3_tobytes(public_key, &A); + ge_scalarmult_base(&A, private_key); + ge_p3_tobytes(public_key, &A); } diff --git a/src/ed25519/precomp_data.h b/src/ed25519/precomp_data.h index ce59788..7a29302 100644 --- a/src/ed25519/precomp_data.h +++ b/src/ed25519/precomp_data.h @@ -1,1391 +1,1391 @@ static ge_precomp Bi[8] = { - { - { 25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605 }, - { -12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378 }, - { -8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546 }, - }, - { - { 15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024 }, - { 16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574 }, - { 30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357 }, - }, - { - { 10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380 }, - { 4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306 }, - { 19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942 }, - }, - { - { 5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766 }, - { -30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701 }, - { 28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300 }, - }, - { - { -22518993, -6692182, 14201702, -8745502, -23510406, 8844726, 18474211, -1361450, -13062696, 13821877 }, - { -6455177, -7839871, 3374702, -4740862, -27098617, -10571707, 31655028, -7212327, 18853322, -14220951 }, - { 4566830, -12963868, -28974889, -12240689, -7602672, -2830569, -8514358, -10431137, 2207753, -3209784 }, - }, - { - { -25154831, -4185821, 29681144, 7868801, -6854661, -9423865, -12437364, -663000, -31111463, -16132436 }, - { 25576264, -2703214, 7349804, -11814844, 16472782, 9300885, 3844789, 15725684, 171356, 6466918 }, - { 23103977, 13316479, 9739013, -16149481, 817875, -15038942, 8965339, -14088058, -30714912, 16193877 }, - }, - { - { -33521811, 3180713, -2394130, 14003687, -16903474, -16270840, 17238398, 4729455, -18074513, 9256800 }, - { -25182317, -4174131, 32336398, 5036987, -21236817, 11360617, 22616405, 9761698, -19827198, 630305 }, - { -13720693, 2639453, -24237460, -7406481, 9494427, -5774029, -6554551, -15960994, -2449256, -14291300 }, - }, - { - { -3151181, -5046075, 9282714, 6866145, -31907062, -863023, -18940575, 15033784, 25105118, -7894876 }, - { -24326370, 15950226, -31801215, -14592823, -11662737, -5090925, 1573892, -2625887, 2198790, -15804619 }, - { -3099351, 10324967, -2241613, 7453183, -5446979, -2735503, -13812022, -16236442, -32461234, -12290683 }, - }, + { + { 25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605 }, + { -12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378 }, + { -8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546 }, + }, + { + { 15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024 }, + { 16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574 }, + { 30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357 }, + }, + { + { 10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380 }, + { 4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306 }, + { 19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942 }, + }, + { + { 5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766 }, + { -30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701 }, + { 28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300 }, + }, + { + { -22518993, -6692182, 14201702, -8745502, -23510406, 8844726, 18474211, -1361450, -13062696, 13821877 }, + { -6455177, -7839871, 3374702, -4740862, -27098617, -10571707, 31655028, -7212327, 18853322, -14220951 }, + { 4566830, -12963868, -28974889, -12240689, -7602672, -2830569, -8514358, -10431137, 2207753, -3209784 }, + }, + { + { -25154831, -4185821, 29681144, 7868801, -6854661, -9423865, -12437364, -663000, -31111463, -16132436 }, + { 25576264, -2703214, 7349804, -11814844, 16472782, 9300885, 3844789, 15725684, 171356, 6466918 }, + { 23103977, 13316479, 9739013, -16149481, 817875, -15038942, 8965339, -14088058, -30714912, 16193877 }, + }, + { + { -33521811, 3180713, -2394130, 14003687, -16903474, -16270840, 17238398, 4729455, -18074513, 9256800 }, + { -25182317, -4174131, 32336398, 5036987, -21236817, 11360617, 22616405, 9761698, -19827198, 630305 }, + { -13720693, 2639453, -24237460, -7406481, 9494427, -5774029, -6554551, -15960994, -2449256, -14291300 }, + }, + { + { -3151181, -5046075, 9282714, 6866145, -31907062, -863023, -18940575, 15033784, 25105118, -7894876 }, + { -24326370, 15950226, -31801215, -14592823, -11662737, -5090925, 1573892, -2625887, 2198790, -15804619 }, + { -3099351, 10324967, -2241613, 7453183, -5446979, -2735503, -13812022, -16236442, -32461234, -12290683 }, + }, }; /* base[i][j] = (j+1)*256^i*B */ static ge_precomp base[32][8] = { - { - { - { 25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605 }, - { -12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378 }, - { -8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546 }, - }, - { - { -12815894, -12976347, -21581243, 11784320, -25355658, -2750717, -11717903, -3814571, -358445, -10211303 }, - { -21703237, 6903825, 27185491, 6451973, -29577724, -9554005, -15616551, 11189268, -26829678, -5319081 }, - { 26966642, 11152617, 32442495, 15396054, 14353839, -12752335, -3128826, -9541118, -15472047, -4166697 }, - }, - { - { 15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024 }, - { 16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574 }, - { 30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357 }, - }, - { - { -17036878, 13921892, 10945806, -6033431, 27105052, -16084379, -28926210, 15006023, 3284568, -6276540 }, - { 23599295, -8306047, -11193664, -7687416, 13236774, 10506355, 7464579, 9656445, 13059162, 10374397 }, - { 7798556, 16710257, 3033922, 2874086, 28997861, 2835604, 32406664, -3839045, -641708, -101325 }, - }, - { - { 10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380 }, - { 4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306 }, - { 19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942 }, - }, - { - { -15371964, -12862754, 32573250, 4720197, -26436522, 5875511, -19188627, -15224819, -9818940, -12085777 }, - { -8549212, 109983, 15149363, 2178705, 22900618, 4543417, 3044240, -15689887, 1762328, 14866737 }, - { -18199695, -15951423, -10473290, 1707278, -17185920, 3916101, -28236412, 3959421, 27914454, 4383652 }, - }, - { - { 5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766 }, - { -30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701 }, - { 28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300 }, - }, - { - { 14499471, -2729599, -33191113, -4254652, 28494862, 14271267, 30290735, 10876454, -33154098, 2381726 }, - { -7195431, -2655363, -14730155, 462251, -27724326, 3941372, -6236617, 3696005, -32300832, 15351955 }, - { 27431194, 8222322, 16448760, -3907995, -18707002, 11938355, -32961401, -2970515, 29551813, 10109425 }, - }, - }, - { - { - { -13657040, -13155431, -31283750, 11777098, 21447386, 6519384, -2378284, -1627556, 10092783, -4764171 }, - { 27939166, 14210322, 4677035, 16277044, -22964462, -12398139, -32508754, 12005538, -17810127, 12803510 }, - { 17228999, -15661624, -1233527, 300140, -1224870, -11714777, 30364213, -9038194, 18016357, 4397660 }, - }, - { - { -10958843, -7690207, 4776341, -14954238, 27850028, -15602212, -26619106, 14544525, -17477504, 982639 }, - { 29253598, 15796703, -2863982, -9908884, 10057023, 3163536, 7332899, -4120128, -21047696, 9934963 }, - { 5793303, 16271923, -24131614, -10116404, 29188560, 1206517, -14747930, 4559895, -30123922, -10897950 }, - }, - { - { -27643952, -11493006, 16282657, -11036493, 28414021, -15012264, 24191034, 4541697, -13338309, 5500568 }, - { 12650548, -1497113, 9052871, 11355358, -17680037, -8400164, -17430592, 12264343, 10874051, 13524335 }, - { 25556948, -3045990, 714651, 2510400, 23394682, -10415330, 33119038, 5080568, -22528059, 5376628 }, - }, - { - { -26088264, -4011052, -17013699, -3537628, -6726793, 1920897, -22321305, -9447443, 4535768, 1569007 }, - { -2255422, 14606630, -21692440, -8039818, 28430649, 8775819, -30494562, 3044290, 31848280, 12543772 }, - { -22028579, 2943893, -31857513, 6777306, 13784462, -4292203, -27377195, -2062731, 7718482, 14474653 }, - }, - { - { 2385315, 2454213, -22631320, 46603, -4437935, -15680415, 656965, -7236665, 24316168, -5253567 }, - { 13741529, 10911568, -33233417, -8603737, -20177830, -1033297, 33040651, -13424532, -20729456, 8321686 }, - { 21060490, -2212744, 15712757, -4336099, 1639040, 10656336, 23845965, -11874838, -9984458, 608372 }, - }, - { - { -13672732, -15087586, -10889693, -7557059, -6036909, 11305547, 1123968, -6780577, 27229399, 23887 }, - { -23244140, -294205, -11744728, 14712571, -29465699, -2029617, 12797024, -6440308, -1633405, 16678954 }, - { -29500620, 4770662, -16054387, 14001338, 7830047, 9564805, -1508144, -4795045, -17169265, 4904953 }, - }, - { - { 24059557, 14617003, 19037157, -15039908, 19766093, -14906429, 5169211, 16191880, 2128236, -4326833 }, - { -16981152, 4124966, -8540610, -10653797, 30336522, -14105247, -29806336, 916033, -6882542, -2986532 }, - { -22630907, 12419372, -7134229, -7473371, -16478904, 16739175, 285431, 2763829, 15736322, 4143876 }, - }, - { - { 2379352, 11839345, -4110402, -5988665, 11274298, 794957, 212801, -14594663, 23527084, -16458268 }, - { 33431127, -11130478, -17838966, -15626900, 8909499, 8376530, -32625340, 4087881, -15188911, -14416214 }, - { 1767683, 7197987, -13205226, -2022635, -13091350, 448826, 5799055, 4357868, -4774191, -16323038 }, - }, - }, - { - { - { 6721966, 13833823, -23523388, -1551314, 26354293, -11863321, 23365147, -3949732, 7390890, 2759800 }, - { 4409041, 2052381, 23373853, 10530217, 7676779, -12885954, 21302353, -4264057, 1244380, -12919645 }, - { -4421239, 7169619, 4982368, -2957590, 30256825, -2777540, 14086413, 9208236, 15886429, 16489664 }, - }, - { - { 1996075, 10375649, 14346367, 13311202, -6874135, -16438411, -13693198, 398369, -30606455, -712933 }, - { -25307465, 9795880, -2777414, 14878809, -33531835, 14780363, 13348553, 12076947, -30836462, 5113182 }, - { -17770784, 11797796, 31950843, 13929123, -25888302, 12288344, -30341101, -7336386, 13847711, 5387222 }, - }, - { - { -18582163, -3416217, 17824843, -2340966, 22744343, -10442611, 8763061, 3617786, -19600662, 10370991 }, - { 20246567, -14369378, 22358229, -543712, 18507283, -10413996, 14554437, -8746092, 32232924, 16763880 }, - { 9648505, 10094563, 26416693, 14745928, -30374318, -6472621, 11094161, 15689506, 3140038, -16510092 }, - }, - { - { -16160072, 5472695, 31895588, 4744994, 8823515, 10365685, -27224800, 9448613, -28774454, 366295 }, - { 19153450, 11523972, -11096490, -6503142, -24647631, 5420647, 28344573, 8041113, 719605, 11671788 }, - { 8678025, 2694440, -6808014, 2517372, 4964326, 11152271, -15432916, -15266516, 27000813, -10195553 }, - }, - { - { -15157904, 7134312, 8639287, -2814877, -7235688, 10421742, 564065, 5336097, 6750977, -14521026 }, - { 11836410, -3979488, 26297894, 16080799, 23455045, 15735944, 1695823, -8819122, 8169720, 16220347 }, - { -18115838, 8653647, 17578566, -6092619, -8025777, -16012763, -11144307, -2627664, -5990708, -14166033 }, - }, - { - { -23308498, -10968312, 15213228, -10081214, -30853605, -11050004, 27884329, 2847284, 2655861, 1738395 }, - { -27537433, -14253021, -25336301, -8002780, -9370762, 8129821, 21651608, -3239336, -19087449, -11005278 }, - { 1533110, 3437855, 23735889, 459276, 29970501, 11335377, 26030092, 5821408, 10478196, 8544890 }, - }, - { - { 32173121, -16129311, 24896207, 3921497, 22579056, -3410854, 19270449, 12217473, 17789017, -3395995 }, - { -30552961, -2228401, -15578829, -10147201, 13243889, 517024, 15479401, -3853233, 30460520, 1052596 }, - { -11614875, 13323618, 32618793, 8175907, -15230173, 12596687, 27491595, -4612359, 3179268, -9478891 }, - }, - { - { 31947069, -14366651, -4640583, -15339921, -15125977, -6039709, -14756777, -16411740, 19072640, -9511060 }, - { 11685058, 11822410, 3158003, -13952594, 33402194, -4165066, 5977896, -5215017, 473099, 5040608 }, - { -20290863, 8198642, -27410132, 11602123, 1290375, -2799760, 28326862, 1721092, -19558642, -3131606 }, - }, - }, - { - { - { 7881532, 10687937, 7578723, 7738378, -18951012, -2553952, 21820786, 8076149, -27868496, 11538389 }, - { -19935666, 3899861, 18283497, -6801568, -15728660, -11249211, 8754525, 7446702, -5676054, 5797016 }, - { -11295600, -3793569, -15782110, -7964573, 12708869, -8456199, 2014099, -9050574, -2369172, -5877341 }, - }, - { - { -22472376, -11568741, -27682020, 1146375, 18956691, 16640559, 1192730, -3714199, 15123619, 10811505 }, - { 14352098, -3419715, -18942044, 10822655, 32750596, 4699007, -70363, 15776356, -28886779, -11974553 }, - { -28241164, -8072475, -4978962, -5315317, 29416931, 1847569, -20654173, -16484855, 4714547, -9600655 }, - }, - { - { 15200332, 8368572, 19679101, 15970074, -31872674, 1959451, 24611599, -4543832, -11745876, 12340220 }, - { 12876937, -10480056, 33134381, 6590940, -6307776, 14872440, 9613953, 8241152, 15370987, 9608631 }, - { -4143277, -12014408, 8446281, -391603, 4407738, 13629032, -7724868, 15866074, -28210621, -8814099 }, - }, - { - { 26660628, -15677655, 8393734, 358047, -7401291, 992988, -23904233, 858697, 20571223, 8420556 }, - { 14620715, 13067227, -15447274, 8264467, 14106269, 15080814, 33531827, 12516406, -21574435, -12476749 }, - { 236881, 10476226, 57258, -14677024, 6472998, 2466984, 17258519, 7256740, 8791136, 15069930 }, - }, - { - { 1276410, -9371918, 22949635, -16322807, -23493039, -5702186, 14711875, 4874229, -30663140, -2331391 }, - { 5855666, 4990204, -13711848, 7294284, -7804282, 1924647, -1423175, -7912378, -33069337, 9234253 }, - { 20590503, -9018988, 31529744, -7352666, -2706834, 10650548, 31559055, -11609587, 18979186, 13396066 }, - }, - { - { 24474287, 4968103, 22267082, 4407354, 24063882, -8325180, -18816887, 13594782, 33514650, 7021958 }, - { -11566906, -6565505, -21365085, 15928892, -26158305, 4315421, -25948728, -3916677, -21480480, 12868082 }, - { -28635013, 13504661, 19988037, -2132761, 21078225, 6443208, -21446107, 2244500, -12455797, -8089383 }, - }, - { - { -30595528, 13793479, -5852820, 319136, -25723172, -6263899, 33086546, 8957937, -15233648, 5540521 }, - { -11630176, -11503902, -8119500, -7643073, 2620056, 1022908, -23710744, -1568984, -16128528, -14962807 }, - { 23152971, 775386, 27395463, 14006635, -9701118, 4649512, 1689819, 892185, -11513277, -15205948 }, - }, - { - { 9770129, 9586738, 26496094, 4324120, 1556511, -3550024, 27453819, 4763127, -19179614, 5867134 }, - { -32765025, 1927590, 31726409, -4753295, 23962434, -16019500, 27846559, 5931263, -29749703, -16108455 }, - { 27461885, -2977536, 22380810, 1815854, -23033753, -3031938, 7283490, -15148073, -19526700, 7734629 }, - }, - }, - { - { - { -8010264, -9590817, -11120403, 6196038, 29344158, -13430885, 7585295, -3176626, 18549497, 15302069 }, - { -32658337, -6171222, -7672793, -11051681, 6258878, 13504381, 10458790, -6418461, -8872242, 8424746 }, - { 24687205, 8613276, -30667046, -3233545, 1863892, -1830544, 19206234, 7134917, -11284482, -828919 }, - }, - { - { 11334899, -9218022, 8025293, 12707519, 17523892, -10476071, 10243738, -14685461, -5066034, 16498837 }, - { 8911542, 6887158, -9584260, -6958590, 11145641, -9543680, 17303925, -14124238, 6536641, 10543906 }, - { -28946384, 15479763, -17466835, 568876, -1497683, 11223454, -2669190, -16625574, -27235709, 8876771 }, - }, - { - { -25742899, -12566864, -15649966, -846607, -33026686, -796288, -33481822, 15824474, -604426, -9039817 }, - { 10330056, 70051, 7957388, -9002667, 9764902, 15609756, 27698697, -4890037, 1657394, 3084098 }, - { 10477963, -7470260, 12119566, -13250805, 29016247, -5365589, 31280319, 14396151, -30233575, 15272409 }, - }, - { - { -12288309, 3169463, 28813183, 16658753, 25116432, -5630466, -25173957, -12636138, -25014757, 1950504 }, - { -26180358, 9489187, 11053416, -14746161, -31053720, 5825630, -8384306, -8767532, 15341279, 8373727 }, - { 28685821, 7759505, -14378516, -12002860, -31971820, 4079242, 298136, -10232602, -2878207, 15190420 }, - }, - { - { -32932876, 13806336, -14337485, -15794431, -24004620, 10940928, 8669718, 2742393, -26033313, -6875003 }, - { -1580388, -11729417, -25979658, -11445023, -17411874, -10912854, 9291594, -16247779, -12154742, 6048605 }, - { -30305315, 14843444, 1539301, 11864366, 20201677, 1900163, 13934231, 5128323, 11213262, 9168384 }, - }, - { - { -26280513, 11007847, 19408960, -940758, -18592965, -4328580, -5088060, -11105150, 20470157, -16398701 }, - { -23136053, 9282192, 14855179, -15390078, -7362815, -14408560, -22783952, 14461608, 14042978, 5230683 }, - { 29969567, -2741594, -16711867, -8552442, 9175486, -2468974, 21556951, 3506042, -5933891, -12449708 }, - }, - { - { -3144746, 8744661, 19704003, 4581278, -20430686, 6830683, -21284170, 8971513, -28539189, 15326563 }, - { -19464629, 10110288, -17262528, -3503892, -23500387, 1355669, -15523050, 15300988, -20514118, 9168260 }, - { -5353335, 4488613, -23803248, 16314347, 7780487, -15638939, -28948358, 9601605, 33087103, -9011387 }, - }, - { - { -19443170, -15512900, -20797467, -12445323, -29824447, 10229461, -27444329, -15000531, -5996870, 15664672 }, - { 23294591, -16632613, -22650781, -8470978, 27844204, 11461195, 13099750, -2460356, 18151676, 13417686 }, - { -24722913, -4176517, -31150679, 5988919, -26858785, 6685065, 1661597, -12551441, 15271676, -15452665 }, - }, - }, - { - { - { 11433042, -13228665, 8239631, -5279517, -1985436, -725718, -18698764, 2167544, -6921301, -13440182 }, - { -31436171, 15575146, 30436815, 12192228, -22463353, 9395379, -9917708, -8638997, 12215110, 12028277 }, - { 14098400, 6555944, 23007258, 5757252, -15427832, -12950502, 30123440, 4617780, -16900089, -655628 }, - }, - { - { -4026201, -15240835, 11893168, 13718664, -14809462, 1847385, -15819999, 10154009, 23973261, -12684474 }, - { -26531820, -3695990, -1908898, 2534301, -31870557, -16550355, 18341390, -11419951, 32013174, -10103539 }, - { -25479301, 10876443, -11771086, -14625140, -12369567, 1838104, 21911214, 6354752, 4425632, -837822 }, - }, - { - { -10433389, -14612966, 22229858, -3091047, -13191166, 776729, -17415375, -12020462, 4725005, 14044970 }, - { 19268650, -7304421, 1555349, 8692754, -21474059, -9910664, 6347390, -1411784, -19522291, -16109756 }, - { -24864089, 12986008, -10898878, -5558584, -11312371, -148526, 19541418, 8180106, 9282262, 10282508 }, - }, - { - { -26205082, 4428547, -8661196, -13194263, 4098402, -14165257, 15522535, 8372215, 5542595, -10702683 }, - { -10562541, 14895633, 26814552, -16673850, -17480754, -2489360, -2781891, 6993761, -18093885, 10114655 }, - { -20107055, -929418, 31422704, 10427861, -7110749, 6150669, -29091755, -11529146, 25953725, -106158 }, - }, - { - { -4234397, -8039292, -9119125, 3046000, 2101609, -12607294, 19390020, 6094296, -3315279, 12831125 }, - { -15998678, 7578152, 5310217, 14408357, -33548620, -224739, 31575954, 6326196, 7381791, -2421839 }, - { -20902779, 3296811, 24736065, -16328389, 18374254, 7318640, 6295303, 8082724, -15362489, 12339664 }, - }, - { - { 27724736, 2291157, 6088201, -14184798, 1792727, 5857634, 13848414, 15768922, 25091167, 14856294 }, - { -18866652, 8331043, 24373479, 8541013, -701998, -9269457, 12927300, -12695493, -22182473, -9012899 }, - { -11423429, -5421590, 11632845, 3405020, 30536730, -11674039, -27260765, 13866390, 30146206, 9142070 }, - }, - { - { 3924129, -15307516, -13817122, -10054960, 12291820, -668366, -27702774, 9326384, -8237858, 4171294 }, - { -15921940, 16037937, 6713787, 16606682, -21612135, 2790944, 26396185, 3731949, 345228, -5462949 }, - { -21327538, 13448259, 25284571, 1143661, 20614966, -8849387, 2031539, -12391231, -16253183, -13582083 }, - }, - { - { 31016211, -16722429, 26371392, -14451233, -5027349, 14854137, 17477601, 3842657, 28012650, -16405420 }, - { -5075835, 9368966, -8562079, -4600902, -15249953, 6970560, -9189873, 16292057, -8867157, 3507940 }, - { 29439664, 3537914, 23333589, 6997794, -17555561, -11018068, -15209202, -15051267, -9164929, 6580396 }, - }, - }, - { - { - { -12185861, -7679788, 16438269, 10826160, -8696817, -6235611, 17860444, -9273846, -2095802, 9304567 }, - { 20714564, -4336911, 29088195, 7406487, 11426967, -5095705, 14792667, -14608617, 5289421, -477127 }, - { -16665533, -10650790, -6160345, -13305760, 9192020, -1802462, 17271490, 12349094, 26939669, -3752294 }, - }, - { - { -12889898, 9373458, 31595848, 16374215, 21471720, 13221525, -27283495, -12348559, -3698806, 117887 }, - { 22263325, -6560050, 3984570, -11174646, -15114008, -566785, 28311253, 5358056, -23319780, 541964 }, - { 16259219, 3261970, 2309254, -15534474, -16885711, -4581916, 24134070, -16705829, -13337066, -13552195 }, - }, - { - { 9378160, -13140186, -22845982, -12745264, 28198281, -7244098, -2399684, -717351, 690426, 14876244 }, - { 24977353, -314384, -8223969, -13465086, 28432343, -1176353, -13068804, -12297348, -22380984, 6618999 }, - { -1538174, 11685646, 12944378, 13682314, -24389511, -14413193, 8044829, -13817328, 32239829, -5652762 }, - }, - { - { -18603066, 4762990, -926250, 8885304, -28412480, -3187315, 9781647, -10350059, 32779359, 5095274 }, - { -33008130, -5214506, -32264887, -3685216, 9460461, -9327423, -24601656, 14506724, 21639561, -2630236 }, - { -16400943, -13112215, 25239338, 15531969, 3987758, -4499318, -1289502, -6863535, 17874574, 558605 }, - }, - { - { -13600129, 10240081, 9171883, 16131053, -20869254, 9599700, 33499487, 5080151, 2085892, 5119761 }, - { -22205145, -2519528, -16381601, 414691, -25019550, 2170430, 30634760, -8363614, -31999993, -5759884 }, - { -6845704, 15791202, 8550074, -1312654, 29928809, -12092256, 27534430, -7192145, -22351378, 12961482 }, - }, - { - { -24492060, -9570771, 10368194, 11582341, -23397293, -2245287, 16533930, 8206996, -30194652, -5159638 }, - { -11121496, -3382234, 2307366, 6362031, -135455, 8868177, -16835630, 7031275, 7589640, 8945490 }, - { -32152748, 8917967, 6661220, -11677616, -1192060, -15793393, 7251489, -11182180, 24099109, -14456170 }, - }, - { - { 5019558, -7907470, 4244127, -14714356, -26933272, 6453165, -19118182, -13289025, -6231896, -10280736 }, - { 10853594, 10721687, 26480089, 5861829, -22995819, 1972175, -1866647, -10557898, -3363451, -6441124 }, - { -17002408, 5906790, 221599, -6563147, 7828208, -13248918, 24362661, -2008168, -13866408, 7421392 }, - }, - { - { 8139927, -6546497, 32257646, -5890546, 30375719, 1886181, -21175108, 15441252, 28826358, -4123029 }, - { 6267086, 9695052, 7709135, -16603597, -32869068, -1886135, 14795160, -7840124, 13746021, -1742048 }, - { 28584902, 7787108, -6732942, -15050729, 22846041, -7571236, -3181936, -363524, 4771362, -8419958 }, - }, - }, - { - { - { 24949256, 6376279, -27466481, -8174608, -18646154, -9930606, 33543569, -12141695, 3569627, 11342593 }, - { 26514989, 4740088, 27912651, 3697550, 19331575, -11472339, 6809886, 4608608, 7325975, -14801071 }, - { -11618399, -14554430, -24321212, 7655128, -1369274, 5214312, -27400540, 10258390, -17646694, -8186692 }, - }, - { - { 11431204, 15823007, 26570245, 14329124, 18029990, 4796082, -31446179, 15580664, 9280358, -3973687 }, - { -160783, -10326257, -22855316, -4304997, -20861367, -13621002, -32810901, -11181622, -15545091, 4387441 }, - { -20799378, 12194512, 3937617, -5805892, -27154820, 9340370, -24513992, 8548137, 20617071, -7482001 }, - }, - { - { -938825, -3930586, -8714311, 16124718, 24603125, -6225393, -13775352, -11875822, 24345683, 10325460 }, - { -19855277, -1568885, -22202708, 8714034, 14007766, 6928528, 16318175, -1010689, 4766743, 3552007 }, - { -21751364, -16730916, 1351763, -803421, -4009670, 3950935, 3217514, 14481909, 10988822, -3994762 }, - }, - { - { 15564307, -14311570, 3101243, 5684148, 30446780, -8051356, 12677127, -6505343, -8295852, 13296005 }, - { -9442290, 6624296, -30298964, -11913677, -4670981, -2057379, 31521204, 9614054, -30000824, 12074674 }, - { 4771191, -135239, 14290749, -13089852, 27992298, 14998318, -1413936, -1556716, 29832613, -16391035 }, - }, - { - { 7064884, -7541174, -19161962, -5067537, -18891269, -2912736, 25825242, 5293297, -27122660, 13101590 }, - { -2298563, 2439670, -7466610, 1719965, -27267541, -16328445, 32512469, -5317593, -30356070, -4190957 }, - { -30006540, 10162316, -33180176, 3981723, -16482138, -13070044, 14413974, 9515896, 19568978, 9628812 }, - }, - { - { 33053803, 199357, 15894591, 1583059, 27380243, -4580435, -17838894, -6106839, -6291786, 3437740 }, - { -18978877, 3884493, 19469877, 12726490, 15913552, 13614290, -22961733, 70104, 7463304, 4176122 }, - { -27124001, 10659917, 11482427, -16070381, 12771467, -6635117, -32719404, -5322751, 24216882, 5944158 }, - }, - { - { 8894125, 7450974, -2664149, -9765752, -28080517, -12389115, 19345746, 14680796, 11632993, 5847885 }, - { 26942781, -2315317, 9129564, -4906607, 26024105, 11769399, -11518837, 6367194, -9727230, 4782140 }, - { 19916461, -4828410, -22910704, -11414391, 25606324, -5972441, 33253853, 8220911, 6358847, -1873857 }, - }, - { - { 801428, -2081702, 16569428, 11065167, 29875704, 96627, 7908388, -4480480, -13538503, 1387155 }, - { 19646058, 5720633, -11416706, 12814209, 11607948, 12749789, 14147075, 15156355, -21866831, 11835260 }, - { 19299512, 1155910, 28703737, 14890794, 2925026, 7269399, 26121523, 15467869, -26560550, 5052483 }, - }, - }, - { - { - { -3017432, 10058206, 1980837, 3964243, 22160966, 12322533, -6431123, -12618185, 12228557, -7003677 }, - { 32944382, 14922211, -22844894, 5188528, 21913450, -8719943, 4001465, 13238564, -6114803, 8653815 }, - { 22865569, -4652735, 27603668, -12545395, 14348958, 8234005, 24808405, 5719875, 28483275, 2841751 }, - }, - { - { -16420968, -1113305, -327719, -12107856, 21886282, -15552774, -1887966, -315658, 19932058, -12739203 }, - { -11656086, 10087521, -8864888, -5536143, -19278573, -3055912, 3999228, 13239134, -4777469, -13910208 }, - { 1382174, -11694719, 17266790, 9194690, -13324356, 9720081, 20403944, 11284705, -14013818, 3093230 }, - }, - { - { 16650921, -11037932, -1064178, 1570629, -8329746, 7352753, -302424, 16271225, -24049421, -6691850 }, - { -21911077, -5927941, -4611316, -5560156, -31744103, -10785293, 24123614, 15193618, -21652117, -16739389 }, - { -9935934, -4289447, -25279823, 4372842, 2087473, 10399484, 31870908, 14690798, 17361620, 11864968 }, - }, - { - { -11307610, 6210372, 13206574, 5806320, -29017692, -13967200, -12331205, -7486601, -25578460, -16240689 }, - { 14668462, -12270235, 26039039, 15305210, 25515617, 4542480, 10453892, 6577524, 9145645, -6443880 }, - { 5974874, 3053895, -9433049, -10385191, -31865124, 3225009, -7972642, 3936128, -5652273, -3050304 }, - }, - { - { 30625386, -4729400, -25555961, -12792866, -20484575, 7695099, 17097188, -16303496, -27999779, 1803632 }, - { -3553091, 9865099, -5228566, 4272701, -5673832, -16689700, 14911344, 12196514, -21405489, 7047412 }, - { 20093277, 9920966, -11138194, -5343857, 13161587, 12044805, -32856851, 4124601, -32343828, -10257566 }, - }, - { - { -20788824, 14084654, -13531713, 7842147, 19119038, -13822605, 4752377, -8714640, -21679658, 2288038 }, - { -26819236, -3283715, 29965059, 3039786, -14473765, 2540457, 29457502, 14625692, -24819617, 12570232 }, - { -1063558, -11551823, 16920318, 12494842, 1278292, -5869109, -21159943, -3498680, -11974704, 4724943 }, - }, - { - { 17960970, -11775534, -4140968, -9702530, -8876562, -1410617, -12907383, -8659932, -29576300, 1903856 }, - { 23134274, -14279132, -10681997, -1611936, 20684485, 15770816, -12989750, 3190296, 26955097, 14109738 }, - { 15308788, 5320727, -30113809, -14318877, 22902008, 7767164, 29425325, -11277562, 31960942, 11934971 }, - }, - { - { -27395711, 8435796, 4109644, 12222639, -24627868, 14818669, 20638173, 4875028, 10491392, 1379718 }, - { -13159415, 9197841, 3875503, -8936108, -1383712, -5879801, 33518459, 16176658, 21432314, 12180697 }, - { -11787308, 11500838, 13787581, -13832590, -22430679, 10140205, 1465425, 12689540, -10301319, -13872883 }, - }, - }, - { - { - { 5414091, -15386041, -21007664, 9643570, 12834970, 1186149, -2622916, -1342231, 26128231, 6032912 }, - { -26337395, -13766162, 32496025, -13653919, 17847801, -12669156, 3604025, 8316894, -25875034, -10437358 }, - { 3296484, 6223048, 24680646, -12246460, -23052020, 5903205, -8862297, -4639164, 12376617, 3188849 }, - }, - { - { 29190488, -14659046, 27549113, -1183516, 3520066, -10697301, 32049515, -7309113, -16109234, -9852307 }, - { -14744486, -9309156, 735818, -598978, -20407687, -5057904, 25246078, -15795669, 18640741, -960977 }, - { -6928835, -16430795, 10361374, 5642961, 4910474, 12345252, -31638386, -494430, 10530747, 1053335 }, - }, - { - { -29265967, -14186805, -13538216, -12117373, -19457059, -10655384, -31462369, -2948985, 24018831, 15026644 }, - { -22592535, -3145277, -2289276, 5953843, -13440189, 9425631, 25310643, 13003497, -2314791, -15145616 }, - { -27419985, -603321, -8043984, -1669117, -26092265, 13987819, -27297622, 187899, -23166419, -2531735 }, - }, - { - { -21744398, -13810475, 1844840, 5021428, -10434399, -15911473, 9716667, 16266922, -5070217, 726099 }, - { 29370922, -6053998, 7334071, -15342259, 9385287, 2247707, -13661962, -4839461, 30007388, -15823341 }, - { -936379, 16086691, 23751945, -543318, -1167538, -5189036, 9137109, 730663, 9835848, 4555336 }, - }, - { - { -23376435, 1410446, -22253753, -12899614, 30867635, 15826977, 17693930, 544696, -11985298, 12422646 }, - { 31117226, -12215734, -13502838, 6561947, -9876867, -12757670, -5118685, -4096706, 29120153, 13924425 }, - { -17400879, -14233209, 19675799, -2734756, -11006962, -5858820, -9383939, -11317700, 7240931, -237388 }, - }, - { - { -31361739, -11346780, -15007447, -5856218, -22453340, -12152771, 1222336, 4389483, 3293637, -15551743 }, - { -16684801, -14444245, 11038544, 11054958, -13801175, -3338533, -24319580, 7733547, 12796905, -6335822 }, - { -8759414, -10817836, -25418864, 10783769, -30615557, -9746811, -28253339, 3647836, 3222231, -11160462 }, - }, - { - { 18606113, 1693100, -25448386, -15170272, 4112353, 10045021, 23603893, -2048234, -7550776, 2484985 }, - { 9255317, -3131197, -12156162, -1004256, 13098013, -9214866, 16377220, -2102812, -19802075, -3034702 }, - { -22729289, 7496160, -5742199, 11329249, 19991973, -3347502, -31718148, 9936966, -30097688, -10618797 }, - }, - { - { 21878590, -5001297, 4338336, 13643897, -3036865, 13160960, 19708896, 5415497, -7360503, -4109293 }, - { 27736861, 10103576, 12500508, 8502413, -3413016, -9633558, 10436918, -1550276, -23659143, -8132100 }, - { 19492550, -12104365, -29681976, -852630, -3208171, 12403437, 30066266, 8367329, 13243957, 8709688 }, - }, - }, - { - { - { 12015105, 2801261, 28198131, 10151021, 24818120, -4743133, -11194191, -5645734, 5150968, 7274186 }, - { 2831366, -12492146, 1478975, 6122054, 23825128, -12733586, 31097299, 6083058, 31021603, -9793610 }, - { -2529932, -2229646, 445613, 10720828, -13849527, -11505937, -23507731, 16354465, 15067285, -14147707 }, - }, - { - { 7840942, 14037873, -33364863, 15934016, -728213, -3642706, 21403988, 1057586, -19379462, -12403220 }, - { 915865, -16469274, 15608285, -8789130, -24357026, 6060030, -17371319, 8410997, -7220461, 16527025 }, - { 32922597, -556987, 20336074, -16184568, 10903705, -5384487, 16957574, 52992, 23834301, 6588044 }, - }, - { - { 32752030, 11232950, 3381995, -8714866, 22652988, -10744103, 17159699, 16689107, -20314580, -1305992 }, - { -4689649, 9166776, -25710296, -10847306, 11576752, 12733943, 7924251, -2752281, 1976123, -7249027 }, - { 21251222, 16309901, -2983015, -6783122, 30810597, 12967303, 156041, -3371252, 12331345, -8237197 }, - }, - { - { 8651614, -4477032, -16085636, -4996994, 13002507, 2950805, 29054427, -5106970, 10008136, -4667901 }, - { 31486080, 15114593, -14261250, 12951354, 14369431, -7387845, 16347321, -13662089, 8684155, -10532952 }, - { 19443825, 11385320, 24468943, -9659068, -23919258, 2187569, -26263207, -6086921, 31316348, 14219878 }, - }, - { - { -28594490, 1193785, 32245219, 11392485, 31092169, 15722801, 27146014, 6992409, 29126555, 9207390 }, - { 32382935, 1110093, 18477781, 11028262, -27411763, -7548111, -4980517, 10843782, -7957600, -14435730 }, - { 2814918, 7836403, 27519878, -7868156, -20894015, -11553689, -21494559, 8550130, 28346258, 1994730 }, - }, - { - { -19578299, 8085545, -14000519, -3948622, 2785838, -16231307, -19516951, 7174894, 22628102, 8115180 }, - { -30405132, 955511, -11133838, -15078069, -32447087, -13278079, -25651578, 3317160, -9943017, 930272 }, - { -15303681, -6833769, 28856490, 1357446, 23421993, 1057177, 24091212, -1388970, -22765376, -10650715 }, - }, - { - { -22751231, -5303997, -12907607, -12768866, -15811511, -7797053, -14839018, -16554220, -1867018, 8398970 }, - { -31969310, 2106403, -4736360, 1362501, 12813763, 16200670, 22981545, -6291273, 18009408, -15772772 }, - { -17220923, -9545221, -27784654, 14166835, 29815394, 7444469, 29551787, -3727419, 19288549, 1325865 }, - }, - { - { 15100157, -15835752, -23923978, -1005098, -26450192, 15509408, 12376730, -3479146, 33166107, -8042750 }, - { 20909231, 13023121, -9209752, 16251778, -5778415, -8094914, 12412151, 10018715, 2213263, -13878373 }, - { 32529814, -11074689, 30361439, -16689753, -9135940, 1513226, 22922121, 6382134, -5766928, 8371348 }, - }, - }, - { - { - { 9923462, 11271500, 12616794, 3544722, -29998368, -1721626, 12891687, -8193132, -26442943, 10486144 }, - { -22597207, -7012665, 8587003, -8257861, 4084309, -12970062, 361726, 2610596, -23921530, -11455195 }, - { 5408411, -1136691, -4969122, 10561668, 24145918, 14240566, 31319731, -4235541, 19985175, -3436086 }, - }, - { - { -13994457, 16616821, 14549246, 3341099, 32155958, 13648976, -17577068, 8849297, 65030, 8370684 }, - { -8320926, -12049626, 31204563, 5839400, -20627288, -1057277, -19442942, 6922164, 12743482, -9800518 }, - { -2361371, 12678785, 28815050, 4759974, -23893047, 4884717, 23783145, 11038569, 18800704, 255233 }, - }, - { - { -5269658, -1773886, 13957886, 7990715, 23132995, 728773, 13393847, 9066957, 19258688, -14753793 }, - { -2936654, -10827535, -10432089, 14516793, -3640786, 4372541, -31934921, 2209390, -1524053, 2055794 }, - { 580882, 16705327, 5468415, -2683018, -30926419, -14696000, -7203346, -8994389, -30021019, 7394435 }, - }, - { - { 23838809, 1822728, -15738443, 15242727, 8318092, -3733104, -21672180, -3492205, -4821741, 14799921 }, - { 13345610, 9759151, 3371034, -16137791, 16353039, 8577942, 31129804, 13496856, -9056018, 7402518 }, - { 2286874, -4435931, -20042458, -2008336, -13696227, 5038122, 11006906, -15760352, 8205061, 1607563 }, - }, - { - { 14414086, -8002132, 3331830, -3208217, 22249151, -5594188, 18364661, -2906958, 30019587, -9029278 }, - { -27688051, 1585953, -10775053, 931069, -29120221, -11002319, -14410829, 12029093, 9944378, 8024 }, - { 4368715, -3709630, 29874200, -15022983, -20230386, -11410704, -16114594, -999085, -8142388, 5640030 }, - }, - { - { 10299610, 13746483, 11661824, 16234854, 7630238, 5998374, 9809887, -16694564, 15219798, -14327783 }, - { 27425505, -5719081, 3055006, 10660664, 23458024, 595578, -15398605, -1173195, -18342183, 9742717 }, - { 6744077, 2427284, 26042789, 2720740, -847906, 1118974, 32324614, 7406442, 12420155, 1994844 }, - }, - { - { 14012521, -5024720, -18384453, -9578469, -26485342, -3936439, -13033478, -10909803, 24319929, -6446333 }, - { 16412690, -4507367, 10772641, 15929391, -17068788, -4658621, 10555945, -10484049, -30102368, -4739048 }, - { 22397382, -7767684, -9293161, -12792868, 17166287, -9755136, -27333065, 6199366, 21880021, -12250760 }, - }, - { - { -4283307, 5368523, -31117018, 8163389, -30323063, 3209128, 16557151, 8890729, 8840445, 4957760 }, - { -15447727, 709327, -6919446, -10870178, -29777922, 6522332, -21720181, 12130072, -14796503, 5005757 }, - { -2114751, -14308128, 23019042, 15765735, -25269683, 6002752, 10183197, -13239326, -16395286, -2176112 }, - }, - }, - { - { - { -19025756, 1632005, 13466291, -7995100, -23640451, 16573537, -32013908, -3057104, 22208662, 2000468 }, - { 3065073, -1412761, -25598674, -361432, -17683065, -5703415, -8164212, 11248527, -3691214, -7414184 }, - { 10379208, -6045554, 8877319, 1473647, -29291284, -12507580, 16690915, 2553332, -3132688, 16400289 }, - }, - { - { 15716668, 1254266, -18472690, 7446274, -8448918, 6344164, -22097271, -7285580, 26894937, 9132066 }, - { 24158887, 12938817, 11085297, -8177598, -28063478, -4457083, -30576463, 64452, -6817084, -2692882 }, - { 13488534, 7794716, 22236231, 5989356, 25426474, -12578208, 2350710, -3418511, -4688006, 2364226 }, - }, - { - { 16335052, 9132434, 25640582, 6678888, 1725628, 8517937, -11807024, -11697457, 15445875, -7798101 }, - { 29004207, -7867081, 28661402, -640412, -12794003, -7943086, 31863255, -4135540, -278050, -15759279 }, - { -6122061, -14866665, -28614905, 14569919, -10857999, -3591829, 10343412, -6976290, -29828287, -10815811 }, - }, - { - { 27081650, 3463984, 14099042, -4517604, 1616303, -6205604, 29542636, 15372179, 17293797, 960709 }, - { 20263915, 11434237, -5765435, 11236810, 13505955, -10857102, -16111345, 6493122, -19384511, 7639714 }, - { -2830798, -14839232, 25403038, -8215196, -8317012, -16173699, 18006287, -16043750, 29994677, -15808121 }, - }, - { - { 9769828, 5202651, -24157398, -13631392, -28051003, -11561624, -24613141, -13860782, -31184575, 709464 }, - { 12286395, 13076066, -21775189, -1176622, -25003198, 4057652, -32018128, -8890874, 16102007, 13205847 }, - { 13733362, 5599946, 10557076, 3195751, -5557991, 8536970, -25540170, 8525972, 10151379, 10394400 }, - }, - { - { 4024660, -16137551, 22436262, 12276534, -9099015, -2686099, 19698229, 11743039, -33302334, 8934414 }, - { -15879800, -4525240, -8580747, -2934061, 14634845, -698278, -9449077, 3137094, -11536886, 11721158 }, - { 17555939, -5013938, 8268606, 2331751, -22738815, 9761013, 9319229, 8835153, -9205489, -1280045 }, - }, - { - { -461409, -7830014, 20614118, 16688288, -7514766, -4807119, 22300304, 505429, 6108462, -6183415 }, - { -5070281, 12367917, -30663534, 3234473, 32617080, -8422642, 29880583, -13483331, -26898490, -7867459 }, - { -31975283, 5726539, 26934134, 10237677, -3173717, -605053, 24199304, 3795095, 7592688, -14992079 }, - }, - { - { 21594432, -14964228, 17466408, -4077222, 32537084, 2739898, 6407723, 12018833, -28256052, 4298412 }, - { -20650503, -11961496, -27236275, 570498, 3767144, -1717540, 13891942, -1569194, 13717174, 10805743 }, - { -14676630, -15644296, 15287174, 11927123, 24177847, -8175568, -796431, 14860609, -26938930, -5863836 }, - }, - }, - { - { - { 12962541, 5311799, -10060768, 11658280, 18855286, -7954201, 13286263, -12808704, -4381056, 9882022 }, - { 18512079, 11319350, -20123124, 15090309, 18818594, 5271736, -22727904, 3666879, -23967430, -3299429 }, - { -6789020, -3146043, 16192429, 13241070, 15898607, -14206114, -10084880, -6661110, -2403099, 5276065 }, - }, - { - { 30169808, -5317648, 26306206, -11750859, 27814964, 7069267, 7152851, 3684982, 1449224, 13082861 }, - { 10342826, 3098505, 2119311, 193222, 25702612, 12233820, 23697382, 15056736, -21016438, -8202000 }, - { -33150110, 3261608, 22745853, 7948688, 19370557, -15177665, -26171976, 6482814, -10300080, -11060101 }, - }, - { - { 32869458, -5408545, 25609743, 15678670, -10687769, -15471071, 26112421, 2521008, -22664288, 6904815 }, - { 29506923, 4457497, 3377935, -9796444, -30510046, 12935080, 1561737, 3841096, -29003639, -6657642 }, - { 10340844, -6630377, -18656632, -2278430, 12621151, -13339055, 30878497, -11824370, -25584551, 5181966 }, - }, - { - { 25940115, -12658025, 17324188, -10307374, -8671468, 15029094, 24396252, -16450922, -2322852, -12388574 }, - { -21765684, 9916823, -1300409, 4079498, -1028346, 11909559, 1782390, 12641087, 20603771, -6561742 }, - { -18882287, -11673380, 24849422, 11501709, 13161720, -4768874, 1925523, 11914390, 4662781, 7820689 }, - }, - { - { 12241050, -425982, 8132691, 9393934, 32846760, -1599620, 29749456, 12172924, 16136752, 15264020 }, - { -10349955, -14680563, -8211979, 2330220, -17662549, -14545780, 10658213, 6671822, 19012087, 3772772 }, - { 3753511, -3421066, 10617074, 2028709, 14841030, -6721664, 28718732, -15762884, 20527771, 12988982 }, - }, - { - { -14822485, -5797269, -3707987, 12689773, -898983, -10914866, -24183046, -10564943, 3299665, -12424953 }, - { -16777703, -15253301, -9642417, 4978983, 3308785, 8755439, 6943197, 6461331, -25583147, 8991218 }, - { -17226263, 1816362, -1673288, -6086439, 31783888, -8175991, -32948145, 7417950, -30242287, 1507265 }, - }, - { - { 29692663, 6829891, -10498800, 4334896, 20945975, -11906496, -28887608, 8209391, 14606362, -10647073 }, - { -3481570, 8707081, 32188102, 5672294, 22096700, 1711240, -33020695, 9761487, 4170404, -2085325 }, - { -11587470, 14855945, -4127778, -1531857, -26649089, 15084046, 22186522, 16002000, -14276837, -8400798 }, - }, - { - { -4811456, 13761029, -31703877, -2483919, -3312471, 7869047, -7113572, -9620092, 13240845, 10965870 }, - { -7742563, -8256762, -14768334, -13656260, -23232383, 12387166, 4498947, 14147411, 29514390, 4302863 }, - { -13413405, -12407859, 20757302, -13801832, 14785143, 8976368, -5061276, -2144373, 17846988, -13971927 }, - }, - }, - { - { - { -2244452, -754728, -4597030, -1066309, -6247172, 1455299, -21647728, -9214789, -5222701, 12650267 }, - { -9906797, -16070310, 21134160, 12198166, -27064575, 708126, 387813, 13770293, -19134326, 10958663 }, - { 22470984, 12369526, 23446014, -5441109, -21520802, -9698723, -11772496, -11574455, -25083830, 4271862 }, - }, - { - { -25169565, -10053642, -19909332, 15361595, -5984358, 2159192, 75375, -4278529, -32526221, 8469673 }, - { 15854970, 4148314, -8893890, 7259002, 11666551, 13824734, -30531198, 2697372, 24154791, -9460943 }, - { 15446137, -15806644, 29759747, 14019369, 30811221, -9610191, -31582008, 12840104, 24913809, 9815020 }, - }, - { - { -4709286, -5614269, -31841498, -12288893, -14443537, 10799414, -9103676, 13438769, 18735128, 9466238 }, - { 11933045, 9281483, 5081055, -5183824, -2628162, -4905629, -7727821, -10896103, -22728655, 16199064 }, - { 14576810, 379472, -26786533, -8317236, -29426508, -10812974, -102766, 1876699, 30801119, 2164795 }, - }, - { - { 15995086, 3199873, 13672555, 13712240, -19378835, -4647646, -13081610, -15496269, -13492807, 1268052 }, - { -10290614, -3659039, -3286592, 10948818, 23037027, 3794475, -3470338, -12600221, -17055369, 3565904 }, - { 29210088, -9419337, -5919792, -4952785, 10834811, -13327726, -16512102, -10820713, -27162222, -14030531 }, - }, - { - { -13161890, 15508588, 16663704, -8156150, -28349942, 9019123, -29183421, -3769423, 2244111, -14001979 }, - { -5152875, -3800936, -9306475, -6071583, 16243069, 14684434, -25673088, -16180800, 13491506, 4641841 }, - { 10813417, 643330, -19188515, -728916, 30292062, -16600078, 27548447, -7721242, 14476989, -12767431 }, - }, - { - { 10292079, 9984945, 6481436, 8279905, -7251514, 7032743, 27282937, -1644259, -27912810, 12651324 }, - { -31185513, -813383, 22271204, 11835308, 10201545, 15351028, 17099662, 3988035, 21721536, -3148940 }, - { 10202177, -6545839, -31373232, -9574638, -32150642, -8119683, -12906320, 3852694, 13216206, 14842320 }, - }, - { - { -15815640, -10601066, -6538952, -7258995, -6984659, -6581778, -31500847, 13765824, -27434397, 9900184 }, - { 14465505, -13833331, -32133984, -14738873, -27443187, 12990492, 33046193, 15796406, -7051866, -8040114 }, - { 30924417, -8279620, 6359016, -12816335, 16508377, 9071735, -25488601, 15413635, 9524356, -7018878 }, - }, - { - { 12274201, -13175547, 32627641, -1785326, 6736625, 13267305, 5237659, -5109483, 15663516, 4035784 }, - { -2951309, 8903985, 17349946, 601635, -16432815, -4612556, -13732739, -15889334, -22258478, 4659091 }, - { -16916263, -4952973, -30393711, -15158821, 20774812, 15897498, 5736189, 15026997, -2178256, -13455585 }, - }, - }, - { - { - { -8858980, -2219056, 28571666, -10155518, -474467, -10105698, -3801496, 278095, 23440562, -290208 }, - { 10226241, -5928702, 15139956, 120818, -14867693, 5218603, 32937275, 11551483, -16571960, -7442864 }, - { 17932739, -12437276, -24039557, 10749060, 11316803, 7535897, 22503767, 5561594, -3646624, 3898661 }, - }, - { - { 7749907, -969567, -16339731, -16464, -25018111, 15122143, -1573531, 7152530, 21831162, 1245233 }, - { 26958459, -14658026, 4314586, 8346991, -5677764, 11960072, -32589295, -620035, -30402091, -16716212 }, - { -12165896, 9166947, 33491384, 13673479, 29787085, 13096535, 6280834, 14587357, -22338025, 13987525 }, - }, - { - { -24349909, 7778775, 21116000, 15572597, -4833266, -5357778, -4300898, -5124639, -7469781, -2858068 }, - { 9681908, -6737123, -31951644, 13591838, -6883821, 386950, 31622781, 6439245, -14581012, 4091397 }, - { -8426427, 1470727, -28109679, -1596990, 3978627, -5123623, -19622683, 12092163, 29077877, -14741988 }, - }, - { - { 5269168, -6859726, -13230211, -8020715, 25932563, 1763552, -5606110, -5505881, -20017847, 2357889 }, - { 32264008, -15407652, -5387735, -1160093, -2091322, -3946900, 23104804, -12869908, 5727338, 189038 }, - { 14609123, -8954470, -6000566, -16622781, -14577387, -7743898, -26745169, 10942115, -25888931, -14884697 }, - }, - { - { 20513500, 5557931, -15604613, 7829531, 26413943, -2019404, -21378968, 7471781, 13913677, -5137875 }, - { -25574376, 11967826, 29233242, 12948236, -6754465, 4713227, -8940970, 14059180, 12878652, 8511905 }, - { -25656801, 3393631, -2955415, -7075526, -2250709, 9366908, -30223418, 6812974, 5568676, -3127656 }, - }, - { - { 11630004, 12144454, 2116339, 13606037, 27378885, 15676917, -17408753, -13504373, -14395196, 8070818 }, - { 27117696, -10007378, -31282771, -5570088, 1127282, 12772488, -29845906, 10483306, -11552749, -1028714 }, - { 10637467, -5688064, 5674781, 1072708, -26343588, -6982302, -1683975, 9177853, -27493162, 15431203 }, - }, - { - { 20525145, 10892566, -12742472, 12779443, -29493034, 16150075, -28240519, 14943142, -15056790, -7935931 }, - { -30024462, 5626926, -551567, -9981087, 753598, 11981191, 25244767, -3239766, -3356550, 9594024 }, - { -23752644, 2636870, -5163910, -10103818, 585134, 7877383, 11345683, -6492290, 13352335, -10977084 }, - }, - { - { -1931799, -5407458, 3304649, -12884869, 17015806, -4877091, -29783850, -7752482, -13215537, -319204 }, - { 20239939, 6607058, 6203985, 3483793, -18386976, -779229, -20723742, 15077870, -22750759, 14523817 }, - { 27406042, -6041657, 27423596, -4497394, 4996214, 10002360, -28842031, -4545494, -30172742, -4805667 }, - }, - }, - { - { - { 11374242, 12660715, 17861383, -12540833, 10935568, 1099227, -13886076, -9091740, -27727044, 11358504 }, - { -12730809, 10311867, 1510375, 10778093, -2119455, -9145702, 32676003, 11149336, -26123651, 4985768 }, - { -19096303, 341147, -6197485, -239033, 15756973, -8796662, -983043, 13794114, -19414307, -15621255 }, - }, - { - { 6490081, 11940286, 25495923, -7726360, 8668373, -8751316, 3367603, 6970005, -1691065, -9004790 }, - { 1656497, 13457317, 15370807, 6364910, 13605745, 8362338, -19174622, -5475723, -16796596, -5031438 }, - { -22273315, -13524424, -64685, -4334223, -18605636, -10921968, -20571065, -7007978, -99853, -10237333 }, - }, - { - { 17747465, 10039260, 19368299, -4050591, -20630635, -16041286, 31992683, -15857976, -29260363, -5511971 }, - { 31932027, -4986141, -19612382, 16366580, 22023614, 88450, 11371999, -3744247, 4882242, -10626905 }, - { 29796507, 37186, 19818052, 10115756, -11829032, 3352736, 18551198, 3272828, -5190932, -4162409 }, - }, - { - { 12501286, 4044383, -8612957, -13392385, -32430052, 5136599, -19230378, -3529697, 330070, -3659409 }, - { 6384877, 2899513, 17807477, 7663917, -2358888, 12363165, 25366522, -8573892, -271295, 12071499 }, - { -8365515, -4042521, 25133448, -4517355, -6211027, 2265927, -32769618, 1936675, -5159697, 3829363 }, - }, - { - { 28425966, -5835433, -577090, -4697198, -14217555, 6870930, 7921550, -6567787, 26333140, 14267664 }, - { -11067219, 11871231, 27385719, -10559544, -4585914, -11189312, 10004786, -8709488, -21761224, 8930324 }, - { -21197785, -16396035, 25654216, -1725397, 12282012, 11008919, 1541940, 4757911, -26491501, -16408940 }, - }, - { - { 13537262, -7759490, -20604840, 10961927, -5922820, -13218065, -13156584, 6217254, -15943699, 13814990 }, - { -17422573, 15157790, 18705543, 29619, 24409717, -260476, 27361681, 9257833, -1956526, -1776914 }, - { -25045300, -10191966, 15366585, 15166509, -13105086, 8423556, -29171540, 12361135, -18685978, 4578290 }, - }, - { - { 24579768, 3711570, 1342322, -11180126, -27005135, 14124956, -22544529, 14074919, 21964432, 8235257 }, - { -6528613, -2411497, 9442966, -5925588, 12025640, -1487420, -2981514, -1669206, 13006806, 2355433 }, - { -16304899, -13605259, -6632427, -5142349, 16974359, -10911083, 27202044, 1719366, 1141648, -12796236 }, - }, - { - { -12863944, -13219986, -8318266, -11018091, -6810145, -4843894, 13475066, -3133972, 32674895, 13715045 }, - { 11423335, -5468059, 32344216, 8962751, 24989809, 9241752, -13265253, 16086212, -28740881, -15642093 }, - { -1409668, 12530728, -6368726, 10847387, 19531186, -14132160, -11709148, 7791794, -27245943, 4383347 }, - }, - }, - { - { - { -28970898, 5271447, -1266009, -9736989, -12455236, 16732599, -4862407, -4906449, 27193557, 6245191 }, - { -15193956, 5362278, -1783893, 2695834, 4960227, 12840725, 23061898, 3260492, 22510453, 8577507 }, - { -12632451, 11257346, -32692994, 13548177, -721004, 10879011, 31168030, 13952092, -29571492, -3635906 }, - }, - { - { 3877321, -9572739, 32416692, 5405324, -11004407, -13656635, 3759769, 11935320, 5611860, 8164018 }, - { -16275802, 14667797, 15906460, 12155291, -22111149, -9039718, 32003002, -8832289, 5773085, -8422109 }, - { -23788118, -8254300, 1950875, 8937633, 18686727, 16459170, -905725, 12376320, 31632953, 190926 }, - }, - { - { -24593607, -16138885, -8423991, 13378746, 14162407, 6901328, -8288749, 4508564, -25341555, -3627528 }, - { 8884438, -5884009, 6023974, 10104341, -6881569, -4941533, 18722941, -14786005, -1672488, 827625 }, - { -32720583, -16289296, -32503547, 7101210, 13354605, 2659080, -1800575, -14108036, -24878478, 1541286 }, - }, - { - { 2901347, -1117687, 3880376, -10059388, -17620940, -3612781, -21802117, -3567481, 20456845, -1885033 }, - { 27019610, 12299467, -13658288, -1603234, -12861660, -4861471, -19540150, -5016058, 29439641, 15138866 }, - { 21536104, -6626420, -32447818, -10690208, -22408077, 5175814, -5420040, -16361163, 7779328, 109896 }, - }, - { - { 30279744, 14648750, -8044871, 6425558, 13639621, -743509, 28698390, 12180118, 23177719, -554075 }, - { 26572847, 3405927, -31701700, 12890905, -19265668, 5335866, -6493768, 2378492, 4439158, -13279347 }, - { -22716706, 3489070, -9225266, -332753, 18875722, -1140095, 14819434, -12731527, -17717757, -5461437 }, - }, - { - { -5056483, 16566551, 15953661, 3767752, -10436499, 15627060, -820954, 2177225, 8550082, -15114165 }, - { -18473302, 16596775, -381660, 15663611, 22860960, 15585581, -27844109, -3582739, -23260460, -8428588 }, - { -32480551, 15707275, -8205912, -5652081, 29464558, 2713815, -22725137, 15860482, -21902570, 1494193 }, - }, - { - { -19562091, -14087393, -25583872, -9299552, 13127842, 759709, 21923482, 16529112, 8742704, 12967017 }, - { -28464899, 1553205, 32536856, -10473729, -24691605, -406174, -8914625, -2933896, -29903758, 15553883 }, - { 21877909, 3230008, 9881174, 10539357, -4797115, 2841332, 11543572, 14513274, 19375923, -12647961 }, - }, - { - { 8832269, -14495485, 13253511, 5137575, 5037871, 4078777, 24880818, -6222716, 2862653, 9455043 }, - { 29306751, 5123106, 20245049, -14149889, 9592566, 8447059, -2077124, -2990080, 15511449, 4789663 }, - { -20679756, 7004547, 8824831, -9434977, -4045704, -3750736, -5754762, 108893, 23513200, 16652362 }, - }, - }, - { - { - { -33256173, 4144782, -4476029, -6579123, 10770039, -7155542, -6650416, -12936300, -18319198, 10212860 }, - { 2756081, 8598110, 7383731, -6859892, 22312759, -1105012, 21179801, 2600940, -9988298, -12506466 }, - { -24645692, 13317462, -30449259, -15653928, 21365574, -10869657, 11344424, 864440, -2499677, -16710063 }, - }, - { - { -26432803, 6148329, -17184412, -14474154, 18782929, -275997, -22561534, 211300, 2719757, 4940997 }, - { -1323882, 3911313, -6948744, 14759765, -30027150, 7851207, 21690126, 8518463, 26699843, 5276295 }, - { -13149873, -6429067, 9396249, 365013, 24703301, -10488939, 1321586, 149635, -15452774, 7159369 }, - }, - { - { 9987780, -3404759, 17507962, 9505530, 9731535, -2165514, 22356009, 8312176, 22477218, -8403385 }, - { 18155857, -16504990, 19744716, 9006923, 15154154, -10538976, 24256460, -4864995, -22548173, 9334109 }, - { 2986088, -4911893, 10776628, -3473844, 10620590, -7083203, -21413845, 14253545, -22587149, 536906 }, - }, - { - { 4377756, 8115836, 24567078, 15495314, 11625074, 13064599, 7390551, 10589625, 10838060, -15420424 }, - { -19342404, 867880, 9277171, -3218459, -14431572, -1986443, 19295826, -15796950, 6378260, 699185 }, - { 7895026, 4057113, -7081772, -13077756, -17886831, -323126, -716039, 15693155, -5045064, -13373962 }, - }, - { - { -7737563, -5869402, -14566319, -7406919, 11385654, 13201616, 31730678, -10962840, -3918636, -9669325 }, - { 10188286, -15770834, -7336361, 13427543, 22223443, 14896287, 30743455, 7116568, -21786507, 5427593 }, - { 696102, 13206899, 27047647, -10632082, 15285305, -9853179, 10798490, -4578720, 19236243, 12477404 }, - }, - { - { -11229439, 11243796, -17054270, -8040865, -788228, -8167967, -3897669, 11180504, -23169516, 7733644 }, - { 17800790, -14036179, -27000429, -11766671, 23887827, 3149671, 23466177, -10538171, 10322027, 15313801 }, - { 26246234, 11968874, 32263343, -5468728, 6830755, -13323031, -15794704, -101982, -24449242, 10890804 }, - }, - { - { -31365647, 10271363, -12660625, -6267268, 16690207, -13062544, -14982212, 16484931, 25180797, -5334884 }, - { -586574, 10376444, -32586414, -11286356, 19801893, 10997610, 2276632, 9482883, 316878, 13820577 }, - { -9882808, -4510367, -2115506, 16457136, -11100081, 11674996, 30756178, -7515054, 30696930, -3712849 }, - }, - { - { 32988917, -9603412, 12499366, 7910787, -10617257, -11931514, -7342816, -9985397, -32349517, 7392473 }, - { -8855661, 15927861, 9866406, -3649411, -2396914, -16655781, -30409476, -9134995, 25112947, -2926644 }, - { -2504044, -436966, 25621774, -5678772, 15085042, -5479877, -24884878, -13526194, 5537438, -13914319 }, - }, - }, - { - { - { -11225584, 2320285, -9584280, 10149187, -33444663, 5808648, -14876251, -1729667, 31234590, 6090599 }, - { -9633316, 116426, 26083934, 2897444, -6364437, -2688086, 609721, 15878753, -6970405, -9034768 }, - { -27757857, 247744, -15194774, -9002551, 23288161, -10011936, -23869595, 6503646, 20650474, 1804084 }, - }, - { - { -27589786, 15456424, 8972517, 8469608, 15640622, 4439847, 3121995, -10329713, 27842616, -202328 }, - { -15306973, 2839644, 22530074, 10026331, 4602058, 5048462, 28248656, 5031932, -11375082, 12714369 }, - { 20807691, -7270825, 29286141, 11421711, -27876523, -13868230, -21227475, 1035546, -19733229, 12796920 }, - }, - { - { 12076899, -14301286, -8785001, -11848922, -25012791, 16400684, -17591495, -12899438, 3480665, -15182815 }, - { -32361549, 5457597, 28548107, 7833186, 7303070, -11953545, -24363064, -15921875, -33374054, 2771025 }, - { -21389266, 421932, 26597266, 6860826, 22486084, -6737172, -17137485, -4210226, -24552282, 15673397 }, - }, - { - { -20184622, 2338216, 19788685, -9620956, -4001265, -8740893, -20271184, 4733254, 3727144, -12934448 }, - { 6120119, 814863, -11794402, -622716, 6812205, -15747771, 2019594, 7975683, 31123697, -10958981 }, - { 30069250, -11435332, 30434654, 2958439, 18399564, -976289, 12296869, 9204260, -16432438, 9648165 }, - }, - { - { 32705432, -1550977, 30705658, 7451065, -11805606, 9631813, 3305266, 5248604, -26008332, -11377501 }, - { 17219865, 2375039, -31570947, -5575615, -19459679, 9219903, 294711, 15298639, 2662509, -16297073 }, - { -1172927, -7558695, -4366770, -4287744, -21346413, -8434326, 32087529, -1222777, 32247248, -14389861 }, - }, - { - { 14312628, 1221556, 17395390, -8700143, -4945741, -8684635, -28197744, -9637817, -16027623, -13378845 }, - { -1428825, -9678990, -9235681, 6549687, -7383069, -468664, 23046502, 9803137, 17597934, 2346211 }, - { 18510800, 15337574, 26171504, 981392, -22241552, 7827556, -23491134, -11323352, 3059833, -11782870 }, - }, - { - { 10141598, 6082907, 17829293, -1947643, 9830092, 13613136, -25556636, -5544586, -33502212, 3592096 }, - { 33114168, -15889352, -26525686, -13343397, 33076705, 8716171, 1151462, 1521897, -982665, -6837803 }, - { -32939165, -4255815, 23947181, -324178, -33072974, -12305637, -16637686, 3891704, 26353178, 693168 }, - }, - { - { 30374239, 1595580, -16884039, 13186931, 4600344, 406904, 9585294, -400668, 31375464, 14369965 }, - { -14370654, -7772529, 1510301, 6434173, -18784789, -6262728, 32732230, -13108839, 17901441, 16011505 }, - { 18171223, -11934626, -12500402, 15197122, -11038147, -15230035, -19172240, -16046376, 8764035, 12309598 }, - }, - }, - { - { - { 5975908, -5243188, -19459362, -9681747, -11541277, 14015782, -23665757, 1228319, 17544096, -10593782 }, - { 5811932, -1715293, 3442887, -2269310, -18367348, -8359541, -18044043, -15410127, -5565381, 12348900 }, - { -31399660, 11407555, 25755363, 6891399, -3256938, 14872274, -24849353, 8141295, -10632534, -585479 }, - }, - { - { -12675304, 694026, -5076145, 13300344, 14015258, -14451394, -9698672, -11329050, 30944593, 1130208 }, - { 8247766, -6710942, -26562381, -7709309, -14401939, -14648910, 4652152, 2488540, 23550156, -271232 }, - { 17294316, -3788438, 7026748, 15626851, 22990044, 113481, 2267737, -5908146, -408818, -137719 }, - }, - { - { 16091085, -16253926, 18599252, 7340678, 2137637, -1221657, -3364161, 14550936, 3260525, -7166271 }, - { -4910104, -13332887, 18550887, 10864893, -16459325, -7291596, -23028869, -13204905, -12748722, 2701326 }, - { -8574695, 16099415, 4629974, -16340524, -20786213, -6005432, -10018363, 9276971, 11329923, 1862132 }, - }, - { - { 14763076, -15903608, -30918270, 3689867, 3511892, 10313526, -21951088, 12219231, -9037963, -940300 }, - { 8894987, -3446094, 6150753, 3013931, 301220, 15693451, -31981216, -2909717, -15438168, 11595570 }, - { 15214962, 3537601, -26238722, -14058872, 4418657, -15230761, 13947276, 10730794, -13489462, -4363670 }, - }, - { - { -2538306, 7682793, 32759013, 263109, -29984731, -7955452, -22332124, -10188635, 977108, 699994 }, - { -12466472, 4195084, -9211532, 550904, -15565337, 12917920, 19118110, -439841, -30534533, -14337913 }, - { 31788461, -14507657, 4799989, 7372237, 8808585, -14747943, 9408237, -10051775, 12493932, -5409317 }, - }, - { - { -25680606, 5260744, -19235809, -6284470, -3695942, 16566087, 27218280, 2607121, 29375955, 6024730 }, - { 842132, -2794693, -4763381, -8722815, 26332018, -12405641, 11831880, 6985184, -9940361, 2854096 }, - { -4847262, -7969331, 2516242, -5847713, 9695691, -7221186, 16512645, 960770, 12121869, 16648078 }, - }, - { - { -15218652, 14667096, -13336229, 2013717, 30598287, -464137, -31504922, -7882064, 20237806, 2838411 }, - { -19288047, 4453152, 15298546, -16178388, 22115043, -15972604, 12544294, -13470457, 1068881, -12499905 }, - { -9558883, -16518835, 33238498, 13506958, 30505848, -1114596, -8486907, -2630053, 12521378, 4845654 }, - }, - { - { -28198521, 10744108, -2958380, 10199664, 7759311, -13088600, 3409348, -873400, -6482306, -12885870 }, - { -23561822, 6230156, -20382013, 10655314, -24040585, -11621172, 10477734, -1240216, -3113227, 13974498 }, - { 12966261, 15550616, -32038948, -1615346, 21025980, -629444, 5642325, 7188737, 18895762, 12629579 }, - }, - }, - { - { - { 14741879, -14946887, 22177208, -11721237, 1279741, 8058600, 11758140, 789443, 32195181, 3895677 }, - { 10758205, 15755439, -4509950, 9243698, -4879422, 6879879, -2204575, -3566119, -8982069, 4429647 }, - { -2453894, 15725973, -20436342, -10410672, -5803908, -11040220, -7135870, -11642895, 18047436, -15281743 }, - }, - { - { -25173001, -11307165, 29759956, 11776784, -22262383, -15820455, 10993114, -12850837, -17620701, -9408468 }, - { 21987233, 700364, -24505048, 14972008, -7774265, -5718395, 32155026, 2581431, -29958985, 8773375 }, - { -25568350, 454463, -13211935, 16126715, 25240068, 8594567, 20656846, 12017935, -7874389, -13920155 }, - }, - { - { 6028182, 6263078, -31011806, -11301710, -818919, 2461772, -31841174, -5468042, -1721788, -2776725 }, - { -12278994, 16624277, 987579, -5922598, 32908203, 1248608, 7719845, -4166698, 28408820, 6816612 }, - { -10358094, -8237829, 19549651, -12169222, 22082623, 16147817, 20613181, 13982702, -10339570, 5067943 }, - }, - { - { -30505967, -3821767, 12074681, 13582412, -19877972, 2443951, -19719286, 12746132, 5331210, -10105944 }, - { 30528811, 3601899, -1957090, 4619785, -27361822, -15436388, 24180793, -12570394, 27679908, -1648928 }, - { 9402404, -13957065, 32834043, 10838634, -26580150, -13237195, 26653274, -8685565, 22611444, -12715406 }, - }, - { - { 22190590, 1118029, 22736441, 15130463, -30460692, -5991321, 19189625, -4648942, 4854859, 6622139 }, - { -8310738, -2953450, -8262579, -3388049, -10401731, -271929, 13424426, -3567227, 26404409, 13001963 }, - { -31241838, -15415700, -2994250, 8939346, 11562230, -12840670, -26064365, -11621720, -15405155, 11020693 }, - }, - { - { 1866042, -7949489, -7898649, -10301010, 12483315, 13477547, 3175636, -12424163, 28761762, 1406734 }, - { -448555, -1777666, 13018551, 3194501, -9580420, -11161737, 24760585, -4347088, 25577411, -13378680 }, - { -24290378, 4759345, -690653, -1852816, 2066747, 10693769, -29595790, 9884936, -9368926, 4745410 }, - }, - { - { -9141284, 6049714, -19531061, -4341411, -31260798, 9944276, -15462008, -11311852, 10931924, -11931931 }, - { -16561513, 14112680, -8012645, 4817318, -8040464, -11414606, -22853429, 10856641, -20470770, 13434654 }, - { 22759489, -10073434, -16766264, -1871422, 13637442, -10168091, 1765144, -12654326, 28445307, -5364710 }, - }, - { - { 29875063, 12493613, 2795536, -3786330, 1710620, 15181182, -10195717, -8788675, 9074234, 1167180 }, - { -26205683, 11014233, -9842651, -2635485, -26908120, 7532294, -18716888, -9535498, 3843903, 9367684 }, - { -10969595, -6403711, 9591134, 9582310, 11349256, 108879, 16235123, 8601684, -139197, 4242895 }, - }, - }, - { - { - { 22092954, -13191123, -2042793, -11968512, 32186753, -11517388, -6574341, 2470660, -27417366, 16625501 }, - { -11057722, 3042016, 13770083, -9257922, 584236, -544855, -7770857, 2602725, -27351616, 14247413 }, - { 6314175, -10264892, -32772502, 15957557, -10157730, 168750, -8618807, 14290061, 27108877, -1180880 }, - }, - { - { -8586597, -7170966, 13241782, 10960156, -32991015, -13794596, 33547976, -11058889, -27148451, 981874 }, - { 22833440, 9293594, -32649448, -13618667, -9136966, 14756819, -22928859, -13970780, -10479804, -16197962 }, - { -7768587, 3326786, -28111797, 10783824, 19178761, 14905060, 22680049, 13906969, -15933690, 3797899 }, - }, - { - { 21721356, -4212746, -12206123, 9310182, -3882239, -13653110, 23740224, -2709232, 20491983, -8042152 }, - { 9209270, -15135055, -13256557, -6167798, -731016, 15289673, 25947805, 15286587, 30997318, -6703063 }, - { 7392032, 16618386, 23946583, -8039892, -13265164, -1533858, -14197445, -2321576, 17649998, -250080 }, - }, - { - { -9301088, -14193827, 30609526, -3049543, -25175069, -1283752, -15241566, -9525724, -2233253, 7662146 }, - { -17558673, 1763594, -33114336, 15908610, -30040870, -12174295, 7335080, -8472199, -3174674, 3440183 }, - { -19889700, -5977008, -24111293, -9688870, 10799743, -16571957, 40450, -4431835, 4862400, 1133 }, - }, - { - { -32856209, -7873957, -5422389, 14860950, -16319031, 7956142, 7258061, 311861, -30594991, -7379421 }, - { -3773428, -1565936, 28985340, 7499440, 24445838, 9325937, 29727763, 16527196, 18278453, 15405622 }, - { -4381906, 8508652, -19898366, -3674424, -5984453, 15149970, -13313598, 843523, -21875062, 13626197 }, - }, - { - { 2281448, -13487055, -10915418, -2609910, 1879358, 16164207, -10783882, 3953792, 13340839, 15928663 }, - { 31727126, -7179855, -18437503, -8283652, 2875793, -16390330, -25269894, -7014826, -23452306, 5964753 }, - { 4100420, -5959452, -17179337, 6017714, -18705837, 12227141, -26684835, 11344144, 2538215, -7570755 }, - }, - { - { -9433605, 6123113, 11159803, -2156608, 30016280, 14966241, -20474983, 1485421, -629256, -15958862 }, - { -26804558, 4260919, 11851389, 9658551, -32017107, 16367492, -20205425, -13191288, 11659922, -11115118 }, - { 26180396, 10015009, -30844224, -8581293, 5418197, 9480663, 2231568, -10170080, 33100372, -1306171 }, - }, - { - { 15121113, -5201871, -10389905, 15427821, -27509937, -15992507, 21670947, 4486675, -5931810, -14466380 }, - { 16166486, -9483733, -11104130, 6023908, -31926798, -1364923, 2340060, -16254968, -10735770, -10039824 }, - { 28042865, -3557089, -12126526, 12259706, -3717498, -6945899, 6766453, -8689599, 18036436, 5803270 }, - }, - }, - { - { - { -817581, 6763912, 11803561, 1585585, 10958447, -2671165, 23855391, 4598332, -6159431, -14117438 }, - { -31031306, -14256194, 17332029, -2383520, 31312682, -5967183, 696309, 50292, -20095739, 11763584 }, - { -594563, -2514283, -32234153, 12643980, 12650761, 14811489, 665117, -12613632, -19773211, -10713562 }, - }, - { - { 30464590, -11262872, -4127476, -12734478, 19835327, -7105613, -24396175, 2075773, -17020157, 992471 }, - { 18357185, -6994433, 7766382, 16342475, -29324918, 411174, 14578841, 8080033, -11574335, -10601610 }, - { 19598397, 10334610, 12555054, 2555664, 18821899, -10339780, 21873263, 16014234, 26224780, 16452269 }, - }, - { - { -30223925, 5145196, 5944548, 16385966, 3976735, 2009897, -11377804, -7618186, -20533829, 3698650 }, - { 14187449, 3448569, -10636236, -10810935, -22663880, -3433596, 7268410, -10890444, 27394301, 12015369 }, - { 19695761, 16087646, 28032085, 12999827, 6817792, 11427614, 20244189, -1312777, -13259127, -3402461 }, - }, - { - { 30860103, 12735208, -1888245, -4699734, -16974906, 2256940, -8166013, 12298312, -8550524, -10393462 }, - { -5719826, -11245325, -1910649, 15569035, 26642876, -7587760, -5789354, -15118654, -4976164, 12651793 }, - { -2848395, 9953421, 11531313, -5282879, 26895123, -12697089, -13118820, -16517902, 9768698, -2533218 }, - }, - { - { -24719459, 1894651, -287698, -4704085, 15348719, -8156530, 32767513, 12765450, 4940095, 10678226 }, - { 18860224, 15980149, -18987240, -1562570, -26233012, -11071856, -7843882, 13944024, -24372348, 16582019 }, - { -15504260, 4970268, -29893044, 4175593, -20993212, -2199756, -11704054, 15444560, -11003761, 7989037 }, - }, - { - { 31490452, 5568061, -2412803, 2182383, -32336847, 4531686, -32078269, 6200206, -19686113, -14800171 }, - { -17308668, -15879940, -31522777, -2831, -32887382, 16375549, 8680158, -16371713, 28550068, -6857132 }, - { -28126887, -5688091, 16837845, -1820458, -6850681, 12700016, -30039981, 4364038, 1155602, 5988841 }, - }, - { - { 21890435, -13272907, -12624011, 12154349, -7831873, 15300496, 23148983, -4470481, 24618407, 8283181 }, - { -33136107, -10512751, 9975416, 6841041, -31559793, 16356536, 3070187, -7025928, 1466169, 10740210 }, - { -1509399, -15488185, -13503385, -10655916, 32799044, 909394, -13938903, -5779719, -32164649, -15327040 }, - }, - { - { 3960823, -14267803, -28026090, -15918051, -19404858, 13146868, 15567327, 951507, -3260321, -573935 }, - { 24740841, 5052253, -30094131, 8961361, 25877428, 6165135, -24368180, 14397372, -7380369, -6144105 }, - { -28888365, 3510803, -28103278, -1158478, -11238128, -10631454, -15441463, -14453128, -1625486, -6494814 }, - }, - }, - { - { - { 793299, -9230478, 8836302, -6235707, -27360908, -2369593, 33152843, -4885251, -9906200, -621852 }, - { 5666233, 525582, 20782575, -8038419, -24538499, 14657740, 16099374, 1468826, -6171428, -15186581 }, - { -4859255, -3779343, -2917758, -6748019, 7778750, 11688288, -30404353, -9871238, -1558923, -9863646 }, - }, - { - { 10896332, -7719704, 824275, 472601, -19460308, 3009587, 25248958, 14783338, -30581476, -15757844 }, - { 10566929, 12612572, -31944212, 11118703, -12633376, 12362879, 21752402, 8822496, 24003793, 14264025 }, - { 27713862, -7355973, -11008240, 9227530, 27050101, 2504721, 23886875, -13117525, 13958495, -5732453 }, - }, - { - { -23481610, 4867226, -27247128, 3900521, 29838369, -8212291, -31889399, -10041781, 7340521, -15410068 }, - { 4646514, -8011124, -22766023, -11532654, 23184553, 8566613, 31366726, -1381061, -15066784, -10375192 }, - { -17270517, 12723032, -16993061, 14878794, 21619651, -6197576, 27584817, 3093888, -8843694, 3849921 }, - }, - { - { -9064912, 2103172, 25561640, -15125738, -5239824, 9582958, 32477045, -9017955, 5002294, -15550259 }, - { -12057553, -11177906, 21115585, -13365155, 8808712, -12030708, 16489530, 13378448, -25845716, 12741426 }, - { -5946367, 10645103, -30911586, 15390284, -3286982, -7118677, 24306472, 15852464, 28834118, -7646072 }, - }, - { - { -17335748, -9107057, -24531279, 9434953, -8472084, -583362, -13090771, 455841, 20461858, 5491305 }, - { 13669248, -16095482, -12481974, -10203039, -14569770, -11893198, -24995986, 11293807, -28588204, -9421832 }, - { 28497928, 6272777, -33022994, 14470570, 8906179, -1225630, 18504674, -14165166, 29867745, -8795943 }, - }, - { - { -16207023, 13517196, -27799630, -13697798, 24009064, -6373891, -6367600, -13175392, 22853429, -4012011 }, - { 24191378, 16712145, -13931797, 15217831, 14542237, 1646131, 18603514, -11037887, 12876623, -2112447 }, - { 17902668, 4518229, -411702, -2829247, 26878217, 5258055, -12860753, 608397, 16031844, 3723494 }, - }, - { - { -28632773, 12763728, -20446446, 7577504, 33001348, -13017745, 17558842, -7872890, 23896954, -4314245 }, - { -20005381, -12011952, 31520464, 605201, 2543521, 5991821, -2945064, 7229064, -9919646, -8826859 }, - { 28816045, 298879, -28165016, -15920938, 19000928, -1665890, -12680833, -2949325, -18051778, -2082915 }, - }, - { - { 16000882, -344896, 3493092, -11447198, -29504595, -13159789, 12577740, 16041268, -19715240, 7847707 }, - { 10151868, 10572098, 27312476, 7922682, 14825339, 4723128, -32855931, -6519018, -10020567, 3852848 }, - { -11430470, 15697596, -21121557, -4420647, 5386314, 15063598, 16514493, -15932110, 29330899, -15076224 }, - }, - }, - { - { - { -25499735, -4378794, -15222908, -6901211, 16615731, 2051784, 3303702, 15490, -27548796, 12314391 }, - { 15683520, -6003043, 18109120, -9980648, 15337968, -5997823, -16717435, 15921866, 16103996, -3731215 }, - { -23169824, -10781249, 13588192, -1628807, -3798557, -1074929, -19273607, 5402699, -29815713, -9841101 }, - }, - { - { 23190676, 2384583, -32714340, 3462154, -29903655, -1529132, -11266856, 8911517, -25205859, 2739713 }, - { 21374101, -3554250, -33524649, 9874411, 15377179, 11831242, -33529904, 6134907, 4931255, 11987849 }, - { -7732, -2978858, -16223486, 7277597, 105524, -322051, -31480539, 13861388, -30076310, 10117930 }, - }, - { - { -29501170, -10744872, -26163768, 13051539, -25625564, 5089643, -6325503, 6704079, 12890019, 15728940 }, - { -21972360, -11771379, -951059, -4418840, 14704840, 2695116, 903376, -10428139, 12885167, 8311031 }, - { -17516482, 5352194, 10384213, -13811658, 7506451, 13453191, 26423267, 4384730, 1888765, -5435404 }, - }, - { - { -25817338, -3107312, -13494599, -3182506, 30896459, -13921729, -32251644, -12707869, -19464434, -3340243 }, - { -23607977, -2665774, -526091, 4651136, 5765089, 4618330, 6092245, 14845197, 17151279, -9854116 }, - { -24830458, -12733720, -15165978, 10367250, -29530908, -265356, 22825805, -7087279, -16866484, 16176525 }, - }, - { - { -23583256, 6564961, 20063689, 3798228, -4740178, 7359225, 2006182, -10363426, -28746253, -10197509 }, - { -10626600, -4486402, -13320562, -5125317, 3432136, -6393229, 23632037, -1940610, 32808310, 1099883 }, - { 15030977, 5768825, -27451236, -2887299, -6427378, -15361371, -15277896, -6809350, 2051441, -15225865 }, - }, - { - { -3362323, -7239372, 7517890, 9824992, 23555850, 295369, 5148398, -14154188, -22686354, 16633660 }, - { 4577086, -16752288, 13249841, -15304328, 19958763, -14537274, 18559670, -10759549, 8402478, -9864273 }, - { -28406330, -1051581, -26790155, -907698, -17212414, -11030789, 9453451, -14980072, 17983010, 9967138 }, - }, - { - { -25762494, 6524722, 26585488, 9969270, 24709298, 1220360, -1677990, 7806337, 17507396, 3651560 }, - { -10420457, -4118111, 14584639, 15971087, -15768321, 8861010, 26556809, -5574557, -18553322, -11357135 }, - { 2839101, 14284142, 4029895, 3472686, 14402957, 12689363, -26642121, 8459447, -5605463, -7621941 }, - }, - { - { -4839289, -3535444, 9744961, 2871048, 25113978, 3187018, -25110813, -849066, 17258084, -7977739 }, - { 18164541, -10595176, -17154882, -1542417, 19237078, -9745295, 23357533, -15217008, 26908270, 12150756 }, - { -30264870, -7647865, 5112249, -7036672, -1499807, -6974257, 43168, -5537701, -32302074, 16215819 }, - }, - }, - { - { - { -6898905, 9824394, -12304779, -4401089, -31397141, -6276835, 32574489, 12532905, -7503072, -8675347 }, - { -27343522, -16515468, -27151524, -10722951, 946346, 16291093, 254968, 7168080, 21676107, -1943028 }, - { 21260961, -8424752, -16831886, -11920822, -23677961, 3968121, -3651949, -6215466, -3556191, -7913075 }, - }, - { - { 16544754, 13250366, -16804428, 15546242, -4583003, 12757258, -2462308, -8680336, -18907032, -9662799 }, - { -2415239, -15577728, 18312303, 4964443, -15272530, -12653564, 26820651, 16690659, 25459437, -4564609 }, - { -25144690, 11425020, 28423002, -11020557, -6144921, -15826224, 9142795, -2391602, -6432418, -1644817 }, - }, - { - { -23104652, 6253476, 16964147, -3768872, -25113972, -12296437, -27457225, -16344658, 6335692, 7249989 }, - { -30333227, 13979675, 7503222, -12368314, -11956721, -4621693, -30272269, 2682242, 25993170, -12478523 }, - { 4364628, 5930691, 32304656, -10044554, -8054781, 15091131, 22857016, -10598955, 31820368, 15075278 }, - }, - { - { 31879134, -8918693, 17258761, 90626, -8041836, -4917709, 24162788, -9650886, -17970238, 12833045 }, - { 19073683, 14851414, -24403169, -11860168, 7625278, 11091125, -19619190, 2074449, -9413939, 14905377 }, - { 24483667, -11935567, -2518866, -11547418, -1553130, 15355506, -25282080, 9253129, 27628530, -7555480 }, - }, - { - { 17597607, 8340603, 19355617, 552187, 26198470, -3176583, 4593324, -9157582, -14110875, 15297016 }, - { 510886, 14337390, -31785257, 16638632, 6328095, 2713355, -20217417, -11864220, 8683221, 2921426 }, - { 18606791, 11874196, 27155355, -5281482, -24031742, 6265446, -25178240, -1278924, 4674690, 13890525 }, - }, - { - { 13609624, 13069022, -27372361, -13055908, 24360586, 9592974, 14977157, 9835105, 4389687, 288396 }, - { 9922506, -519394, 13613107, 5883594, -18758345, -434263, -12304062, 8317628, 23388070, 16052080 }, - { 12720016, 11937594, -31970060, -5028689, 26900120, 8561328, -20155687, -11632979, -14754271, -10812892 }, - }, - { - { 15961858, 14150409, 26716931, -665832, -22794328, 13603569, 11829573, 7467844, -28822128, 929275 }, - { 11038231, -11582396, -27310482, -7316562, -10498527, -16307831, -23479533, -9371869, -21393143, 2465074 }, - { 20017163, -4323226, 27915242, 1529148, 12396362, 15675764, 13817261, -9658066, 2463391, -4622140 }, - }, - { - { -16358878, -12663911, -12065183, 4996454, -1256422, 1073572, 9583558, 12851107, 4003896, 12673717 }, - { -1731589, -15155870, -3262930, 16143082, 19294135, 13385325, 14741514, -9103726, 7903886, 2348101 }, - { 24536016, -16515207, 12715592, -3862155, 1511293, 10047386, -3842346, -7129159, -28377538, 10048127 }, - }, - }, - { - { - { -12622226, -6204820, 30718825, 2591312, -10617028, 12192840, 18873298, -7297090, -32297756, 15221632 }, - { -26478122, -11103864, 11546244, -1852483, 9180880, 7656409, -21343950, 2095755, 29769758, 6593415 }, - { -31994208, -2907461, 4176912, 3264766, 12538965, -868111, 26312345, -6118678, 30958054, 8292160 }, - }, - { - { 31429822, -13959116, 29173532, 15632448, 12174511, -2760094, 32808831, 3977186, 26143136, -3148876 }, - { 22648901, 1402143, -22799984, 13746059, 7936347, 365344, -8668633, -1674433, -3758243, -2304625 }, - { -15491917, 8012313, -2514730, -12702462, -23965846, -10254029, -1612713, -1535569, -16664475, 8194478 }, - }, - { - { 27338066, -7507420, -7414224, 10140405, -19026427, -6589889, 27277191, 8855376, 28572286, 3005164 }, - { 26287124, 4821776, 25476601, -4145903, -3764513, -15788984, -18008582, 1182479, -26094821, -13079595 }, - { -7171154, 3178080, 23970071, 6201893, -17195577, -4489192, -21876275, -13982627, 32208683, -1198248 }, - }, - { - { -16657702, 2817643, -10286362, 14811298, 6024667, 13349505, -27315504, -10497842, -27672585, -11539858 }, - { 15941029, -9405932, -21367050, 8062055, 31876073, -238629, -15278393, -1444429, 15397331, -4130193 }, - { 8934485, -13485467, -23286397, -13423241, -32446090, 14047986, 31170398, -1441021, -27505566, 15087184 }, - }, - { - { -18357243, -2156491, 24524913, -16677868, 15520427, -6360776, -15502406, 11461896, 16788528, -5868942 }, - { -1947386, 16013773, 21750665, 3714552, -17401782, -16055433, -3770287, -10323320, 31322514, -11615635 }, - { 21426655, -5650218, -13648287, -5347537, -28812189, -4920970, -18275391, -14621414, 13040862, -12112948 }, - }, - { - { 11293895, 12478086, -27136401, 15083750, -29307421, 14748872, 14555558, -13417103, 1613711, 4896935 }, - { -25894883, 15323294, -8489791, -8057900, 25967126, -13425460, 2825960, -4897045, -23971776, -11267415 }, - { -15924766, -5229880, -17443532, 6410664, 3622847, 10243618, 20615400, 12405433, -23753030, -8436416 }, - }, - { - { -7091295, 12556208, -20191352, 9025187, -17072479, 4333801, 4378436, 2432030, 23097949, -566018 }, - { 4565804, -16025654, 20084412, -7842817, 1724999, 189254, 24767264, 10103221, -18512313, 2424778 }, - { 366633, -11976806, 8173090, -6890119, 30788634, 5745705, -7168678, 1344109, -3642553, 12412659 }, - }, - { - { -24001791, 7690286, 14929416, -168257, -32210835, -13412986, 24162697, -15326504, -3141501, 11179385 }, - { 18289522, -14724954, 8056945, 16430056, -21729724, 7842514, -6001441, -1486897, -18684645, -11443503 }, - { 476239, 6601091, -6152790, -9723375, 17503545, -4863900, 27672959, 13403813, 11052904, 5219329 }, - }, - }, - { - { - { 20678546, -8375738, -32671898, 8849123, -5009758, 14574752, 31186971, -3973730, 9014762, -8579056 }, - { -13644050, -10350239, -15962508, 5075808, -1514661, -11534600, -33102500, 9160280, 8473550, -3256838 }, - { 24900749, 14435722, 17209120, -15292541, -22592275, 9878983, -7689309, -16335821, -24568481, 11788948 }, - }, - { - { -3118155, -11395194, -13802089, 14797441, 9652448, -6845904, -20037437, 10410733, -24568470, -1458691 }, - { -15659161, 16736706, -22467150, 10215878, -9097177, 7563911, 11871841, -12505194, -18513325, 8464118 }, - { -23400612, 8348507, -14585951, -861714, -3950205, -6373419, 14325289, 8628612, 33313881, -8370517 }, - }, - { - { -20186973, -4967935, 22367356, 5271547, -1097117, -4788838, -24805667, -10236854, -8940735, -5818269 }, - { -6948785, -1795212, -32625683, -16021179, 32635414, -7374245, 15989197, -12838188, 28358192, -4253904 }, - { -23561781, -2799059, -32351682, -1661963, -9147719, 10429267, -16637684, 4072016, -5351664, 5596589 }, - }, - { - { -28236598, -3390048, 12312896, 6213178, 3117142, 16078565, 29266239, 2557221, 1768301, 15373193 }, - { -7243358, -3246960, -4593467, -7553353, -127927, -912245, -1090902, -4504991, -24660491, 3442910 }, - { -30210571, 5124043, 14181784, 8197961, 18964734, -11939093, 22597931, 7176455, -18585478, 13365930 }, - }, - { - { -7877390, -1499958, 8324673, 4690079, 6261860, 890446, 24538107, -8570186, -9689599, -3031667 }, - { 25008904, -10771599, -4305031, -9638010, 16265036, 15721635, 683793, -11823784, 15723479, -15163481 }, - { -9660625, 12374379, -27006999, -7026148, -7724114, -12314514, 11879682, 5400171, 519526, -1235876 }, - }, - { - { 22258397, -16332233, -7869817, 14613016, -22520255, -2950923, -20353881, 7315967, 16648397, 7605640 }, - { -8081308, -8464597, -8223311, 9719710, 19259459, -15348212, 23994942, -5281555, -9468848, 4763278 }, - { -21699244, 9220969, -15730624, 1084137, -25476107, -2852390, 31088447, -7764523, -11356529, 728112 }, - }, - { - { 26047220, -11751471, -6900323, -16521798, 24092068, 9158119, -4273545, -12555558, -29365436, -5498272 }, - { 17510331, -322857, 5854289, 8403524, 17133918, -3112612, -28111007, 12327945, 10750447, 10014012 }, - { -10312768, 3936952, 9156313, -8897683, 16498692, -994647, -27481051, -666732, 3424691, 7540221 }, - }, - { - { 30322361, -6964110, 11361005, -4143317, 7433304, 4989748, -7071422, -16317219, -9244265, 15258046 }, - { 13054562, -2779497, 19155474, 469045, -12482797, 4566042, 5631406, 2711395, 1062915, -5136345 }, - { -19240248, -11254599, -29509029, -7499965, -5835763, 13005411, -6066489, 12194497, 32960380, 1459310 }, - }, - }, - { - { - { 19852034, 7027924, 23669353, 10020366, 8586503, -6657907, 394197, -6101885, 18638003, -11174937 }, - { 31395534, 15098109, 26581030, 8030562, -16527914, -5007134, 9012486, -7584354, -6643087, -5442636 }, - { -9192165, -2347377, -1997099, 4529534, 25766844, 607986, -13222, 9677543, -32294889, -6456008 }, - }, - { - { -2444496, -149937, 29348902, 8186665, 1873760, 12489863, -30934579, -7839692, -7852844, -8138429 }, - { -15236356, -15433509, 7766470, 746860, 26346930, -10221762, -27333451, 10754588, -9431476, 5203576 }, - { 31834314, 14135496, -770007, 5159118, 20917671, -16768096, -7467973, -7337524, 31809243, 7347066 }, - }, - { - { -9606723, -11874240, 20414459, 13033986, 13716524, -11691881, 19797970, -12211255, 15192876, -2087490 }, - { -12663563, -2181719, 1168162, -3804809, 26747877, -14138091, 10609330, 12694420, 33473243, -13382104 }, - { 33184999, 11180355, 15832085, -11385430, -1633671, 225884, 15089336, -11023903, -6135662, 14480053 }, - }, - { - { 31308717, -5619998, 31030840, -1897099, 15674547, -6582883, 5496208, 13685227, 27595050, 8737275 }, - { -20318852, -15150239, 10933843, -16178022, 8335352, -7546022, -31008351, -12610604, 26498114, 66511 }, - { 22644454, -8761729, -16671776, 4884562, -3105614, -13559366, 30540766, -4286747, -13327787, -7515095 }, - }, - { - { -28017847, 9834845, 18617207, -2681312, -3401956, -13307506, 8205540, 13585437, -17127465, 15115439 }, - { 23711543, -672915, 31206561, -8362711, 6164647, -9709987, -33535882, -1426096, 8236921, 16492939 }, - { -23910559, -13515526, -26299483, -4503841, 25005590, -7687270, 19574902, 10071562, 6708380, -6222424 }, - }, - { - { 2101391, -4930054, 19702731, 2367575, -15427167, 1047675, 5301017, 9328700, 29955601, -11678310 }, - { 3096359, 9271816, -21620864, -15521844, -14847996, -7592937, -25892142, -12635595, -9917575, 6216608 }, - { -32615849, 338663, -25195611, 2510422, -29213566, -13820213, 24822830, -6146567, -26767480, 7525079 }, - }, - { - { -23066649, -13985623, 16133487, -7896178, -3389565, 778788, -910336, -2782495, -19386633, 11994101 }, - { 21691500, -13624626, -641331, -14367021, 3285881, -3483596, -25064666, 9718258, -7477437, 13381418 }, - { 18445390, -4202236, 14979846, 11622458, -1727110, -3582980, 23111648, -6375247, 28535282, 15779576 }, - }, - { - { 30098053, 3089662, -9234387, 16662135, -21306940, 11308411, -14068454, 12021730, 9955285, -16303356 }, - { 9734894, -14576830, -7473633, -9138735, 2060392, 11313496, -18426029, 9924399, 20194861, 13380996 }, - { -26378102, -7965207, -22167821, 15789297, -18055342, -6168792, -1984914, 15707771, 26342023, 10146099 }, - }, - }, - { - { - { -26016874, -219943, 21339191, -41388, 19745256, -2878700, -29637280, 2227040, 21612326, -545728 }, - { -13077387, 1184228, 23562814, -5970442, -20351244, -6348714, 25764461, 12243797, -20856566, 11649658 }, - { -10031494, 11262626, 27384172, 2271902, 26947504, -15997771, 39944, 6114064, 33514190, 2333242 }, - }, - { - { -21433588, -12421821, 8119782, 7219913, -21830522, -9016134, -6679750, -12670638, 24350578, -13450001 }, - { -4116307, -11271533, -23886186, 4843615, -30088339, 690623, -31536088, -10406836, 8317860, 12352766 }, - { 18200138, -14475911, -33087759, -2696619, -23702521, -9102511, -23552096, -2287550, 20712163, 6719373 }, - }, - { - { 26656208, 6075253, -7858556, 1886072, -28344043, 4262326, 11117530, -3763210, 26224235, -3297458 }, - { -17168938, -14854097, -3395676, -16369877, -19954045, 14050420, 21728352, 9493610, 18620611, -16428628 }, - { -13323321, 13325349, 11432106, 5964811, 18609221, 6062965, -5269471, -9725556, -30701573, -16479657 }, - }, - { - { -23860538, -11233159, 26961357, 1640861, -32413112, -16737940, 12248509, -5240639, 13735342, 1934062 }, - { 25089769, 6742589, 17081145, -13406266, 21909293, -16067981, -15136294, -3765346, -21277997, 5473616 }, - { 31883677, -7961101, 1083432, -11572403, 22828471, 13290673, -7125085, 12469656, 29111212, -5451014 }, - }, - { - { 24244947, -15050407, -26262976, 2791540, -14997599, 16666678, 24367466, 6388839, -10295587, 452383 }, - { -25640782, -3417841, 5217916, 16224624, 19987036, -4082269, -24236251, -5915248, 15766062, 8407814 }, - { -20406999, 13990231, 15495425, 16395525, 5377168, 15166495, -8917023, -4388953, -8067909, 2276718 }, - }, - { - { 30157918, 12924066, -17712050, 9245753, 19895028, 3368142, -23827587, 5096219, 22740376, -7303417 }, - { 2041139, -14256350, 7783687, 13876377, -25946985, -13352459, 24051124, 13742383, -15637599, 13295222 }, - { 33338237, -8505733, 12532113, 7977527, 9106186, -1715251, -17720195, -4612972, -4451357, -14669444 }, - }, - { - { -20045281, 5454097, -14346548, 6447146, 28862071, 1883651, -2469266, -4141880, 7770569, 9620597 }, - { 23208068, 7979712, 33071466, 8149229, 1758231, -10834995, 30945528, -1694323, -33502340, -14767970 }, - { 1439958, -16270480, -1079989, -793782, 4625402, 10647766, -5043801, 1220118, 30494170, -11440799 }, - }, - { - { -5037580, -13028295, -2970559, -3061767, 15640974, -6701666, -26739026, 926050, -1684339, -13333647 }, - { 13908495, -3549272, 30919928, -6273825, -21521863, 7989039, 9021034, 9078865, 3353509, 4033511 }, - { -29663431, -15113610, 32259991, -344482, 24295849, -12912123, 23161163, 8839127, 27485041, 7356032 }, - }, - }, - { - { - { 9661027, 705443, 11980065, -5370154, -1628543, 14661173, -6346142, 2625015, 28431036, -16771834 }, - { -23839233, -8311415, -25945511, 7480958, -17681669, -8354183, -22545972, 14150565, 15970762, 4099461 }, - { 29262576, 16756590, 26350592, -8793563, 8529671, -11208050, 13617293, -9937143, 11465739, 8317062 }, - }, - { - { -25493081, -6962928, 32500200, -9419051, -23038724, -2302222, 14898637, 3848455, 20969334, -5157516 }, - { -20384450, -14347713, -18336405, 13884722, -33039454, 2842114, -21610826, -3649888, 11177095, 14989547 }, - { -24496721, -11716016, 16959896, 2278463, 12066309, 10137771, 13515641, 2581286, -28487508, 9930240 }, - }, - { - { -17751622, -2097826, 16544300, -13009300, -15914807, -14949081, 18345767, -13403753, 16291481, -5314038 }, - { -33229194, 2553288, 32678213, 9875984, 8534129, 6889387, -9676774, 6957617, 4368891, 9788741 }, - { 16660756, 7281060, -10830758, 12911820, 20108584, -8101676, -21722536, -8613148, 16250552, -11111103 }, - }, - { - { -19765507, 2390526, -16551031, 14161980, 1905286, 6414907, 4689584, 10604807, -30190403, 4782747 }, - { -1354539, 14736941, -7367442, -13292886, 7710542, -14155590, -9981571, 4383045, 22546403, 437323 }, - { 31665577, -12180464, -16186830, 1491339, -18368625, 3294682, 27343084, 2786261, -30633590, -14097016 }, - }, - { - { -14467279, -683715, -33374107, 7448552, 19294360, 14334329, -19690631, 2355319, -19284671, -6114373 }, - { 15121312, -15796162, 6377020, -6031361, -10798111, -12957845, 18952177, 15496498, -29380133, 11754228 }, - { -2637277, -13483075, 8488727, -14303896, 12728761, -1622493, 7141596, 11724556, 22761615, -10134141 }, - }, - { - { 16918416, 11729663, -18083579, 3022987, -31015732, -13339659, -28741185, -12227393, 32851222, 11717399 }, - { 11166634, 7338049, -6722523, 4531520, -29468672, -7302055, 31474879, 3483633, -1193175, -4030831 }, - { -185635, 9921305, 31456609, -13536438, -12013818, 13348923, 33142652, 6546660, -19985279, -3948376 }, - }, - { - { -32460596, 11266712, -11197107, -7899103, 31703694, 3855903, -8537131, -12833048, -30772034, -15486313 }, - { -18006477, 12709068, 3991746, -6479188, -21491523, -10550425, -31135347, -16049879, 10928917, 3011958 }, - { -6957757, -15594337, 31696059, 334240, 29576716, 14796075, -30831056, -12805180, 18008031, 10258577 }, - }, - { - { -22448644, 15655569, 7018479, -4410003, -30314266, -1201591, -1853465, 1367120, 25127874, 6671743 }, - { 29701166, -14373934, -10878120, 9279288, -17568, 13127210, 21382910, 11042292, 25838796, 4642684 }, - { -20430234, 14955537, -24126347, 8124619, -5369288, -5990470, 30468147, -13900640, 18423289, 4177476 }, - }, - }, + { + { + { 25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605 }, + { -12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378 }, + { -8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546 }, + }, + { + { -12815894, -12976347, -21581243, 11784320, -25355658, -2750717, -11717903, -3814571, -358445, -10211303 }, + { -21703237, 6903825, 27185491, 6451973, -29577724, -9554005, -15616551, 11189268, -26829678, -5319081 }, + { 26966642, 11152617, 32442495, 15396054, 14353839, -12752335, -3128826, -9541118, -15472047, -4166697 }, + }, + { + { 15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024 }, + { 16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574 }, + { 30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357 }, + }, + { + { -17036878, 13921892, 10945806, -6033431, 27105052, -16084379, -28926210, 15006023, 3284568, -6276540 }, + { 23599295, -8306047, -11193664, -7687416, 13236774, 10506355, 7464579, 9656445, 13059162, 10374397 }, + { 7798556, 16710257, 3033922, 2874086, 28997861, 2835604, 32406664, -3839045, -641708, -101325 }, + }, + { + { 10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380 }, + { 4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306 }, + { 19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942 }, + }, + { + { -15371964, -12862754, 32573250, 4720197, -26436522, 5875511, -19188627, -15224819, -9818940, -12085777 }, + { -8549212, 109983, 15149363, 2178705, 22900618, 4543417, 3044240, -15689887, 1762328, 14866737 }, + { -18199695, -15951423, -10473290, 1707278, -17185920, 3916101, -28236412, 3959421, 27914454, 4383652 }, + }, + { + { 5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766 }, + { -30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701 }, + { 28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300 }, + }, + { + { 14499471, -2729599, -33191113, -4254652, 28494862, 14271267, 30290735, 10876454, -33154098, 2381726 }, + { -7195431, -2655363, -14730155, 462251, -27724326, 3941372, -6236617, 3696005, -32300832, 15351955 }, + { 27431194, 8222322, 16448760, -3907995, -18707002, 11938355, -32961401, -2970515, 29551813, 10109425 }, + }, + }, + { + { + { -13657040, -13155431, -31283750, 11777098, 21447386, 6519384, -2378284, -1627556, 10092783, -4764171 }, + { 27939166, 14210322, 4677035, 16277044, -22964462, -12398139, -32508754, 12005538, -17810127, 12803510 }, + { 17228999, -15661624, -1233527, 300140, -1224870, -11714777, 30364213, -9038194, 18016357, 4397660 }, + }, + { + { -10958843, -7690207, 4776341, -14954238, 27850028, -15602212, -26619106, 14544525, -17477504, 982639 }, + { 29253598, 15796703, -2863982, -9908884, 10057023, 3163536, 7332899, -4120128, -21047696, 9934963 }, + { 5793303, 16271923, -24131614, -10116404, 29188560, 1206517, -14747930, 4559895, -30123922, -10897950 }, + }, + { + { -27643952, -11493006, 16282657, -11036493, 28414021, -15012264, 24191034, 4541697, -13338309, 5500568 }, + { 12650548, -1497113, 9052871, 11355358, -17680037, -8400164, -17430592, 12264343, 10874051, 13524335 }, + { 25556948, -3045990, 714651, 2510400, 23394682, -10415330, 33119038, 5080568, -22528059, 5376628 }, + }, + { + { -26088264, -4011052, -17013699, -3537628, -6726793, 1920897, -22321305, -9447443, 4535768, 1569007 }, + { -2255422, 14606630, -21692440, -8039818, 28430649, 8775819, -30494562, 3044290, 31848280, 12543772 }, + { -22028579, 2943893, -31857513, 6777306, 13784462, -4292203, -27377195, -2062731, 7718482, 14474653 }, + }, + { + { 2385315, 2454213, -22631320, 46603, -4437935, -15680415, 656965, -7236665, 24316168, -5253567 }, + { 13741529, 10911568, -33233417, -8603737, -20177830, -1033297, 33040651, -13424532, -20729456, 8321686 }, + { 21060490, -2212744, 15712757, -4336099, 1639040, 10656336, 23845965, -11874838, -9984458, 608372 }, + }, + { + { -13672732, -15087586, -10889693, -7557059, -6036909, 11305547, 1123968, -6780577, 27229399, 23887 }, + { -23244140, -294205, -11744728, 14712571, -29465699, -2029617, 12797024, -6440308, -1633405, 16678954 }, + { -29500620, 4770662, -16054387, 14001338, 7830047, 9564805, -1508144, -4795045, -17169265, 4904953 }, + }, + { + { 24059557, 14617003, 19037157, -15039908, 19766093, -14906429, 5169211, 16191880, 2128236, -4326833 }, + { -16981152, 4124966, -8540610, -10653797, 30336522, -14105247, -29806336, 916033, -6882542, -2986532 }, + { -22630907, 12419372, -7134229, -7473371, -16478904, 16739175, 285431, 2763829, 15736322, 4143876 }, + }, + { + { 2379352, 11839345, -4110402, -5988665, 11274298, 794957, 212801, -14594663, 23527084, -16458268 }, + { 33431127, -11130478, -17838966, -15626900, 8909499, 8376530, -32625340, 4087881, -15188911, -14416214 }, + { 1767683, 7197987, -13205226, -2022635, -13091350, 448826, 5799055, 4357868, -4774191, -16323038 }, + }, + }, + { + { + { 6721966, 13833823, -23523388, -1551314, 26354293, -11863321, 23365147, -3949732, 7390890, 2759800 }, + { 4409041, 2052381, 23373853, 10530217, 7676779, -12885954, 21302353, -4264057, 1244380, -12919645 }, + { -4421239, 7169619, 4982368, -2957590, 30256825, -2777540, 14086413, 9208236, 15886429, 16489664 }, + }, + { + { 1996075, 10375649, 14346367, 13311202, -6874135, -16438411, -13693198, 398369, -30606455, -712933 }, + { -25307465, 9795880, -2777414, 14878809, -33531835, 14780363, 13348553, 12076947, -30836462, 5113182 }, + { -17770784, 11797796, 31950843, 13929123, -25888302, 12288344, -30341101, -7336386, 13847711, 5387222 }, + }, + { + { -18582163, -3416217, 17824843, -2340966, 22744343, -10442611, 8763061, 3617786, -19600662, 10370991 }, + { 20246567, -14369378, 22358229, -543712, 18507283, -10413996, 14554437, -8746092, 32232924, 16763880 }, + { 9648505, 10094563, 26416693, 14745928, -30374318, -6472621, 11094161, 15689506, 3140038, -16510092 }, + }, + { + { -16160072, 5472695, 31895588, 4744994, 8823515, 10365685, -27224800, 9448613, -28774454, 366295 }, + { 19153450, 11523972, -11096490, -6503142, -24647631, 5420647, 28344573, 8041113, 719605, 11671788 }, + { 8678025, 2694440, -6808014, 2517372, 4964326, 11152271, -15432916, -15266516, 27000813, -10195553 }, + }, + { + { -15157904, 7134312, 8639287, -2814877, -7235688, 10421742, 564065, 5336097, 6750977, -14521026 }, + { 11836410, -3979488, 26297894, 16080799, 23455045, 15735944, 1695823, -8819122, 8169720, 16220347 }, + { -18115838, 8653647, 17578566, -6092619, -8025777, -16012763, -11144307, -2627664, -5990708, -14166033 }, + }, + { + { -23308498, -10968312, 15213228, -10081214, -30853605, -11050004, 27884329, 2847284, 2655861, 1738395 }, + { -27537433, -14253021, -25336301, -8002780, -9370762, 8129821, 21651608, -3239336, -19087449, -11005278 }, + { 1533110, 3437855, 23735889, 459276, 29970501, 11335377, 26030092, 5821408, 10478196, 8544890 }, + }, + { + { 32173121, -16129311, 24896207, 3921497, 22579056, -3410854, 19270449, 12217473, 17789017, -3395995 }, + { -30552961, -2228401, -15578829, -10147201, 13243889, 517024, 15479401, -3853233, 30460520, 1052596 }, + { -11614875, 13323618, 32618793, 8175907, -15230173, 12596687, 27491595, -4612359, 3179268, -9478891 }, + }, + { + { 31947069, -14366651, -4640583, -15339921, -15125977, -6039709, -14756777, -16411740, 19072640, -9511060 }, + { 11685058, 11822410, 3158003, -13952594, 33402194, -4165066, 5977896, -5215017, 473099, 5040608 }, + { -20290863, 8198642, -27410132, 11602123, 1290375, -2799760, 28326862, 1721092, -19558642, -3131606 }, + }, + }, + { + { + { 7881532, 10687937, 7578723, 7738378, -18951012, -2553952, 21820786, 8076149, -27868496, 11538389 }, + { -19935666, 3899861, 18283497, -6801568, -15728660, -11249211, 8754525, 7446702, -5676054, 5797016 }, + { -11295600, -3793569, -15782110, -7964573, 12708869, -8456199, 2014099, -9050574, -2369172, -5877341 }, + }, + { + { -22472376, -11568741, -27682020, 1146375, 18956691, 16640559, 1192730, -3714199, 15123619, 10811505 }, + { 14352098, -3419715, -18942044, 10822655, 32750596, 4699007, -70363, 15776356, -28886779, -11974553 }, + { -28241164, -8072475, -4978962, -5315317, 29416931, 1847569, -20654173, -16484855, 4714547, -9600655 }, + }, + { + { 15200332, 8368572, 19679101, 15970074, -31872674, 1959451, 24611599, -4543832, -11745876, 12340220 }, + { 12876937, -10480056, 33134381, 6590940, -6307776, 14872440, 9613953, 8241152, 15370987, 9608631 }, + { -4143277, -12014408, 8446281, -391603, 4407738, 13629032, -7724868, 15866074, -28210621, -8814099 }, + }, + { + { 26660628, -15677655, 8393734, 358047, -7401291, 992988, -23904233, 858697, 20571223, 8420556 }, + { 14620715, 13067227, -15447274, 8264467, 14106269, 15080814, 33531827, 12516406, -21574435, -12476749 }, + { 236881, 10476226, 57258, -14677024, 6472998, 2466984, 17258519, 7256740, 8791136, 15069930 }, + }, + { + { 1276410, -9371918, 22949635, -16322807, -23493039, -5702186, 14711875, 4874229, -30663140, -2331391 }, + { 5855666, 4990204, -13711848, 7294284, -7804282, 1924647, -1423175, -7912378, -33069337, 9234253 }, + { 20590503, -9018988, 31529744, -7352666, -2706834, 10650548, 31559055, -11609587, 18979186, 13396066 }, + }, + { + { 24474287, 4968103, 22267082, 4407354, 24063882, -8325180, -18816887, 13594782, 33514650, 7021958 }, + { -11566906, -6565505, -21365085, 15928892, -26158305, 4315421, -25948728, -3916677, -21480480, 12868082 }, + { -28635013, 13504661, 19988037, -2132761, 21078225, 6443208, -21446107, 2244500, -12455797, -8089383 }, + }, + { + { -30595528, 13793479, -5852820, 319136, -25723172, -6263899, 33086546, 8957937, -15233648, 5540521 }, + { -11630176, -11503902, -8119500, -7643073, 2620056, 1022908, -23710744, -1568984, -16128528, -14962807 }, + { 23152971, 775386, 27395463, 14006635, -9701118, 4649512, 1689819, 892185, -11513277, -15205948 }, + }, + { + { 9770129, 9586738, 26496094, 4324120, 1556511, -3550024, 27453819, 4763127, -19179614, 5867134 }, + { -32765025, 1927590, 31726409, -4753295, 23962434, -16019500, 27846559, 5931263, -29749703, -16108455 }, + { 27461885, -2977536, 22380810, 1815854, -23033753, -3031938, 7283490, -15148073, -19526700, 7734629 }, + }, + }, + { + { + { -8010264, -9590817, -11120403, 6196038, 29344158, -13430885, 7585295, -3176626, 18549497, 15302069 }, + { -32658337, -6171222, -7672793, -11051681, 6258878, 13504381, 10458790, -6418461, -8872242, 8424746 }, + { 24687205, 8613276, -30667046, -3233545, 1863892, -1830544, 19206234, 7134917, -11284482, -828919 }, + }, + { + { 11334899, -9218022, 8025293, 12707519, 17523892, -10476071, 10243738, -14685461, -5066034, 16498837 }, + { 8911542, 6887158, -9584260, -6958590, 11145641, -9543680, 17303925, -14124238, 6536641, 10543906 }, + { -28946384, 15479763, -17466835, 568876, -1497683, 11223454, -2669190, -16625574, -27235709, 8876771 }, + }, + { + { -25742899, -12566864, -15649966, -846607, -33026686, -796288, -33481822, 15824474, -604426, -9039817 }, + { 10330056, 70051, 7957388, -9002667, 9764902, 15609756, 27698697, -4890037, 1657394, 3084098 }, + { 10477963, -7470260, 12119566, -13250805, 29016247, -5365589, 31280319, 14396151, -30233575, 15272409 }, + }, + { + { -12288309, 3169463, 28813183, 16658753, 25116432, -5630466, -25173957, -12636138, -25014757, 1950504 }, + { -26180358, 9489187, 11053416, -14746161, -31053720, 5825630, -8384306, -8767532, 15341279, 8373727 }, + { 28685821, 7759505, -14378516, -12002860, -31971820, 4079242, 298136, -10232602, -2878207, 15190420 }, + }, + { + { -32932876, 13806336, -14337485, -15794431, -24004620, 10940928, 8669718, 2742393, -26033313, -6875003 }, + { -1580388, -11729417, -25979658, -11445023, -17411874, -10912854, 9291594, -16247779, -12154742, 6048605 }, + { -30305315, 14843444, 1539301, 11864366, 20201677, 1900163, 13934231, 5128323, 11213262, 9168384 }, + }, + { + { -26280513, 11007847, 19408960, -940758, -18592965, -4328580, -5088060, -11105150, 20470157, -16398701 }, + { -23136053, 9282192, 14855179, -15390078, -7362815, -14408560, -22783952, 14461608, 14042978, 5230683 }, + { 29969567, -2741594, -16711867, -8552442, 9175486, -2468974, 21556951, 3506042, -5933891, -12449708 }, + }, + { + { -3144746, 8744661, 19704003, 4581278, -20430686, 6830683, -21284170, 8971513, -28539189, 15326563 }, + { -19464629, 10110288, -17262528, -3503892, -23500387, 1355669, -15523050, 15300988, -20514118, 9168260 }, + { -5353335, 4488613, -23803248, 16314347, 7780487, -15638939, -28948358, 9601605, 33087103, -9011387 }, + }, + { + { -19443170, -15512900, -20797467, -12445323, -29824447, 10229461, -27444329, -15000531, -5996870, 15664672 }, + { 23294591, -16632613, -22650781, -8470978, 27844204, 11461195, 13099750, -2460356, 18151676, 13417686 }, + { -24722913, -4176517, -31150679, 5988919, -26858785, 6685065, 1661597, -12551441, 15271676, -15452665 }, + }, + }, + { + { + { 11433042, -13228665, 8239631, -5279517, -1985436, -725718, -18698764, 2167544, -6921301, -13440182 }, + { -31436171, 15575146, 30436815, 12192228, -22463353, 9395379, -9917708, -8638997, 12215110, 12028277 }, + { 14098400, 6555944, 23007258, 5757252, -15427832, -12950502, 30123440, 4617780, -16900089, -655628 }, + }, + { + { -4026201, -15240835, 11893168, 13718664, -14809462, 1847385, -15819999, 10154009, 23973261, -12684474 }, + { -26531820, -3695990, -1908898, 2534301, -31870557, -16550355, 18341390, -11419951, 32013174, -10103539 }, + { -25479301, 10876443, -11771086, -14625140, -12369567, 1838104, 21911214, 6354752, 4425632, -837822 }, + }, + { + { -10433389, -14612966, 22229858, -3091047, -13191166, 776729, -17415375, -12020462, 4725005, 14044970 }, + { 19268650, -7304421, 1555349, 8692754, -21474059, -9910664, 6347390, -1411784, -19522291, -16109756 }, + { -24864089, 12986008, -10898878, -5558584, -11312371, -148526, 19541418, 8180106, 9282262, 10282508 }, + }, + { + { -26205082, 4428547, -8661196, -13194263, 4098402, -14165257, 15522535, 8372215, 5542595, -10702683 }, + { -10562541, 14895633, 26814552, -16673850, -17480754, -2489360, -2781891, 6993761, -18093885, 10114655 }, + { -20107055, -929418, 31422704, 10427861, -7110749, 6150669, -29091755, -11529146, 25953725, -106158 }, + }, + { + { -4234397, -8039292, -9119125, 3046000, 2101609, -12607294, 19390020, 6094296, -3315279, 12831125 }, + { -15998678, 7578152, 5310217, 14408357, -33548620, -224739, 31575954, 6326196, 7381791, -2421839 }, + { -20902779, 3296811, 24736065, -16328389, 18374254, 7318640, 6295303, 8082724, -15362489, 12339664 }, + }, + { + { 27724736, 2291157, 6088201, -14184798, 1792727, 5857634, 13848414, 15768922, 25091167, 14856294 }, + { -18866652, 8331043, 24373479, 8541013, -701998, -9269457, 12927300, -12695493, -22182473, -9012899 }, + { -11423429, -5421590, 11632845, 3405020, 30536730, -11674039, -27260765, 13866390, 30146206, 9142070 }, + }, + { + { 3924129, -15307516, -13817122, -10054960, 12291820, -668366, -27702774, 9326384, -8237858, 4171294 }, + { -15921940, 16037937, 6713787, 16606682, -21612135, 2790944, 26396185, 3731949, 345228, -5462949 }, + { -21327538, 13448259, 25284571, 1143661, 20614966, -8849387, 2031539, -12391231, -16253183, -13582083 }, + }, + { + { 31016211, -16722429, 26371392, -14451233, -5027349, 14854137, 17477601, 3842657, 28012650, -16405420 }, + { -5075835, 9368966, -8562079, -4600902, -15249953, 6970560, -9189873, 16292057, -8867157, 3507940 }, + { 29439664, 3537914, 23333589, 6997794, -17555561, -11018068, -15209202, -15051267, -9164929, 6580396 }, + }, + }, + { + { + { -12185861, -7679788, 16438269, 10826160, -8696817, -6235611, 17860444, -9273846, -2095802, 9304567 }, + { 20714564, -4336911, 29088195, 7406487, 11426967, -5095705, 14792667, -14608617, 5289421, -477127 }, + { -16665533, -10650790, -6160345, -13305760, 9192020, -1802462, 17271490, 12349094, 26939669, -3752294 }, + }, + { + { -12889898, 9373458, 31595848, 16374215, 21471720, 13221525, -27283495, -12348559, -3698806, 117887 }, + { 22263325, -6560050, 3984570, -11174646, -15114008, -566785, 28311253, 5358056, -23319780, 541964 }, + { 16259219, 3261970, 2309254, -15534474, -16885711, -4581916, 24134070, -16705829, -13337066, -13552195 }, + }, + { + { 9378160, -13140186, -22845982, -12745264, 28198281, -7244098, -2399684, -717351, 690426, 14876244 }, + { 24977353, -314384, -8223969, -13465086, 28432343, -1176353, -13068804, -12297348, -22380984, 6618999 }, + { -1538174, 11685646, 12944378, 13682314, -24389511, -14413193, 8044829, -13817328, 32239829, -5652762 }, + }, + { + { -18603066, 4762990, -926250, 8885304, -28412480, -3187315, 9781647, -10350059, 32779359, 5095274 }, + { -33008130, -5214506, -32264887, -3685216, 9460461, -9327423, -24601656, 14506724, 21639561, -2630236 }, + { -16400943, -13112215, 25239338, 15531969, 3987758, -4499318, -1289502, -6863535, 17874574, 558605 }, + }, + { + { -13600129, 10240081, 9171883, 16131053, -20869254, 9599700, 33499487, 5080151, 2085892, 5119761 }, + { -22205145, -2519528, -16381601, 414691, -25019550, 2170430, 30634760, -8363614, -31999993, -5759884 }, + { -6845704, 15791202, 8550074, -1312654, 29928809, -12092256, 27534430, -7192145, -22351378, 12961482 }, + }, + { + { -24492060, -9570771, 10368194, 11582341, -23397293, -2245287, 16533930, 8206996, -30194652, -5159638 }, + { -11121496, -3382234, 2307366, 6362031, -135455, 8868177, -16835630, 7031275, 7589640, 8945490 }, + { -32152748, 8917967, 6661220, -11677616, -1192060, -15793393, 7251489, -11182180, 24099109, -14456170 }, + }, + { + { 5019558, -7907470, 4244127, -14714356, -26933272, 6453165, -19118182, -13289025, -6231896, -10280736 }, + { 10853594, 10721687, 26480089, 5861829, -22995819, 1972175, -1866647, -10557898, -3363451, -6441124 }, + { -17002408, 5906790, 221599, -6563147, 7828208, -13248918, 24362661, -2008168, -13866408, 7421392 }, + }, + { + { 8139927, -6546497, 32257646, -5890546, 30375719, 1886181, -21175108, 15441252, 28826358, -4123029 }, + { 6267086, 9695052, 7709135, -16603597, -32869068, -1886135, 14795160, -7840124, 13746021, -1742048 }, + { 28584902, 7787108, -6732942, -15050729, 22846041, -7571236, -3181936, -363524, 4771362, -8419958 }, + }, + }, + { + { + { 24949256, 6376279, -27466481, -8174608, -18646154, -9930606, 33543569, -12141695, 3569627, 11342593 }, + { 26514989, 4740088, 27912651, 3697550, 19331575, -11472339, 6809886, 4608608, 7325975, -14801071 }, + { -11618399, -14554430, -24321212, 7655128, -1369274, 5214312, -27400540, 10258390, -17646694, -8186692 }, + }, + { + { 11431204, 15823007, 26570245, 14329124, 18029990, 4796082, -31446179, 15580664, 9280358, -3973687 }, + { -160783, -10326257, -22855316, -4304997, -20861367, -13621002, -32810901, -11181622, -15545091, 4387441 }, + { -20799378, 12194512, 3937617, -5805892, -27154820, 9340370, -24513992, 8548137, 20617071, -7482001 }, + }, + { + { -938825, -3930586, -8714311, 16124718, 24603125, -6225393, -13775352, -11875822, 24345683, 10325460 }, + { -19855277, -1568885, -22202708, 8714034, 14007766, 6928528, 16318175, -1010689, 4766743, 3552007 }, + { -21751364, -16730916, 1351763, -803421, -4009670, 3950935, 3217514, 14481909, 10988822, -3994762 }, + }, + { + { 15564307, -14311570, 3101243, 5684148, 30446780, -8051356, 12677127, -6505343, -8295852, 13296005 }, + { -9442290, 6624296, -30298964, -11913677, -4670981, -2057379, 31521204, 9614054, -30000824, 12074674 }, + { 4771191, -135239, 14290749, -13089852, 27992298, 14998318, -1413936, -1556716, 29832613, -16391035 }, + }, + { + { 7064884, -7541174, -19161962, -5067537, -18891269, -2912736, 25825242, 5293297, -27122660, 13101590 }, + { -2298563, 2439670, -7466610, 1719965, -27267541, -16328445, 32512469, -5317593, -30356070, -4190957 }, + { -30006540, 10162316, -33180176, 3981723, -16482138, -13070044, 14413974, 9515896, 19568978, 9628812 }, + }, + { + { 33053803, 199357, 15894591, 1583059, 27380243, -4580435, -17838894, -6106839, -6291786, 3437740 }, + { -18978877, 3884493, 19469877, 12726490, 15913552, 13614290, -22961733, 70104, 7463304, 4176122 }, + { -27124001, 10659917, 11482427, -16070381, 12771467, -6635117, -32719404, -5322751, 24216882, 5944158 }, + }, + { + { 8894125, 7450974, -2664149, -9765752, -28080517, -12389115, 19345746, 14680796, 11632993, 5847885 }, + { 26942781, -2315317, 9129564, -4906607, 26024105, 11769399, -11518837, 6367194, -9727230, 4782140 }, + { 19916461, -4828410, -22910704, -11414391, 25606324, -5972441, 33253853, 8220911, 6358847, -1873857 }, + }, + { + { 801428, -2081702, 16569428, 11065167, 29875704, 96627, 7908388, -4480480, -13538503, 1387155 }, + { 19646058, 5720633, -11416706, 12814209, 11607948, 12749789, 14147075, 15156355, -21866831, 11835260 }, + { 19299512, 1155910, 28703737, 14890794, 2925026, 7269399, 26121523, 15467869, -26560550, 5052483 }, + }, + }, + { + { + { -3017432, 10058206, 1980837, 3964243, 22160966, 12322533, -6431123, -12618185, 12228557, -7003677 }, + { 32944382, 14922211, -22844894, 5188528, 21913450, -8719943, 4001465, 13238564, -6114803, 8653815 }, + { 22865569, -4652735, 27603668, -12545395, 14348958, 8234005, 24808405, 5719875, 28483275, 2841751 }, + }, + { + { -16420968, -1113305, -327719, -12107856, 21886282, -15552774, -1887966, -315658, 19932058, -12739203 }, + { -11656086, 10087521, -8864888, -5536143, -19278573, -3055912, 3999228, 13239134, -4777469, -13910208 }, + { 1382174, -11694719, 17266790, 9194690, -13324356, 9720081, 20403944, 11284705, -14013818, 3093230 }, + }, + { + { 16650921, -11037932, -1064178, 1570629, -8329746, 7352753, -302424, 16271225, -24049421, -6691850 }, + { -21911077, -5927941, -4611316, -5560156, -31744103, -10785293, 24123614, 15193618, -21652117, -16739389 }, + { -9935934, -4289447, -25279823, 4372842, 2087473, 10399484, 31870908, 14690798, 17361620, 11864968 }, + }, + { + { -11307610, 6210372, 13206574, 5806320, -29017692, -13967200, -12331205, -7486601, -25578460, -16240689 }, + { 14668462, -12270235, 26039039, 15305210, 25515617, 4542480, 10453892, 6577524, 9145645, -6443880 }, + { 5974874, 3053895, -9433049, -10385191, -31865124, 3225009, -7972642, 3936128, -5652273, -3050304 }, + }, + { + { 30625386, -4729400, -25555961, -12792866, -20484575, 7695099, 17097188, -16303496, -27999779, 1803632 }, + { -3553091, 9865099, -5228566, 4272701, -5673832, -16689700, 14911344, 12196514, -21405489, 7047412 }, + { 20093277, 9920966, -11138194, -5343857, 13161587, 12044805, -32856851, 4124601, -32343828, -10257566 }, + }, + { + { -20788824, 14084654, -13531713, 7842147, 19119038, -13822605, 4752377, -8714640, -21679658, 2288038 }, + { -26819236, -3283715, 29965059, 3039786, -14473765, 2540457, 29457502, 14625692, -24819617, 12570232 }, + { -1063558, -11551823, 16920318, 12494842, 1278292, -5869109, -21159943, -3498680, -11974704, 4724943 }, + }, + { + { 17960970, -11775534, -4140968, -9702530, -8876562, -1410617, -12907383, -8659932, -29576300, 1903856 }, + { 23134274, -14279132, -10681997, -1611936, 20684485, 15770816, -12989750, 3190296, 26955097, 14109738 }, + { 15308788, 5320727, -30113809, -14318877, 22902008, 7767164, 29425325, -11277562, 31960942, 11934971 }, + }, + { + { -27395711, 8435796, 4109644, 12222639, -24627868, 14818669, 20638173, 4875028, 10491392, 1379718 }, + { -13159415, 9197841, 3875503, -8936108, -1383712, -5879801, 33518459, 16176658, 21432314, 12180697 }, + { -11787308, 11500838, 13787581, -13832590, -22430679, 10140205, 1465425, 12689540, -10301319, -13872883 }, + }, + }, + { + { + { 5414091, -15386041, -21007664, 9643570, 12834970, 1186149, -2622916, -1342231, 26128231, 6032912 }, + { -26337395, -13766162, 32496025, -13653919, 17847801, -12669156, 3604025, 8316894, -25875034, -10437358 }, + { 3296484, 6223048, 24680646, -12246460, -23052020, 5903205, -8862297, -4639164, 12376617, 3188849 }, + }, + { + { 29190488, -14659046, 27549113, -1183516, 3520066, -10697301, 32049515, -7309113, -16109234, -9852307 }, + { -14744486, -9309156, 735818, -598978, -20407687, -5057904, 25246078, -15795669, 18640741, -960977 }, + { -6928835, -16430795, 10361374, 5642961, 4910474, 12345252, -31638386, -494430, 10530747, 1053335 }, + }, + { + { -29265967, -14186805, -13538216, -12117373, -19457059, -10655384, -31462369, -2948985, 24018831, 15026644 }, + { -22592535, -3145277, -2289276, 5953843, -13440189, 9425631, 25310643, 13003497, -2314791, -15145616 }, + { -27419985, -603321, -8043984, -1669117, -26092265, 13987819, -27297622, 187899, -23166419, -2531735 }, + }, + { + { -21744398, -13810475, 1844840, 5021428, -10434399, -15911473, 9716667, 16266922, -5070217, 726099 }, + { 29370922, -6053998, 7334071, -15342259, 9385287, 2247707, -13661962, -4839461, 30007388, -15823341 }, + { -936379, 16086691, 23751945, -543318, -1167538, -5189036, 9137109, 730663, 9835848, 4555336 }, + }, + { + { -23376435, 1410446, -22253753, -12899614, 30867635, 15826977, 17693930, 544696, -11985298, 12422646 }, + { 31117226, -12215734, -13502838, 6561947, -9876867, -12757670, -5118685, -4096706, 29120153, 13924425 }, + { -17400879, -14233209, 19675799, -2734756, -11006962, -5858820, -9383939, -11317700, 7240931, -237388 }, + }, + { + { -31361739, -11346780, -15007447, -5856218, -22453340, -12152771, 1222336, 4389483, 3293637, -15551743 }, + { -16684801, -14444245, 11038544, 11054958, -13801175, -3338533, -24319580, 7733547, 12796905, -6335822 }, + { -8759414, -10817836, -25418864, 10783769, -30615557, -9746811, -28253339, 3647836, 3222231, -11160462 }, + }, + { + { 18606113, 1693100, -25448386, -15170272, 4112353, 10045021, 23603893, -2048234, -7550776, 2484985 }, + { 9255317, -3131197, -12156162, -1004256, 13098013, -9214866, 16377220, -2102812, -19802075, -3034702 }, + { -22729289, 7496160, -5742199, 11329249, 19991973, -3347502, -31718148, 9936966, -30097688, -10618797 }, + }, + { + { 21878590, -5001297, 4338336, 13643897, -3036865, 13160960, 19708896, 5415497, -7360503, -4109293 }, + { 27736861, 10103576, 12500508, 8502413, -3413016, -9633558, 10436918, -1550276, -23659143, -8132100 }, + { 19492550, -12104365, -29681976, -852630, -3208171, 12403437, 30066266, 8367329, 13243957, 8709688 }, + }, + }, + { + { + { 12015105, 2801261, 28198131, 10151021, 24818120, -4743133, -11194191, -5645734, 5150968, 7274186 }, + { 2831366, -12492146, 1478975, 6122054, 23825128, -12733586, 31097299, 6083058, 31021603, -9793610 }, + { -2529932, -2229646, 445613, 10720828, -13849527, -11505937, -23507731, 16354465, 15067285, -14147707 }, + }, + { + { 7840942, 14037873, -33364863, 15934016, -728213, -3642706, 21403988, 1057586, -19379462, -12403220 }, + { 915865, -16469274, 15608285, -8789130, -24357026, 6060030, -17371319, 8410997, -7220461, 16527025 }, + { 32922597, -556987, 20336074, -16184568, 10903705, -5384487, 16957574, 52992, 23834301, 6588044 }, + }, + { + { 32752030, 11232950, 3381995, -8714866, 22652988, -10744103, 17159699, 16689107, -20314580, -1305992 }, + { -4689649, 9166776, -25710296, -10847306, 11576752, 12733943, 7924251, -2752281, 1976123, -7249027 }, + { 21251222, 16309901, -2983015, -6783122, 30810597, 12967303, 156041, -3371252, 12331345, -8237197 }, + }, + { + { 8651614, -4477032, -16085636, -4996994, 13002507, 2950805, 29054427, -5106970, 10008136, -4667901 }, + { 31486080, 15114593, -14261250, 12951354, 14369431, -7387845, 16347321, -13662089, 8684155, -10532952 }, + { 19443825, 11385320, 24468943, -9659068, -23919258, 2187569, -26263207, -6086921, 31316348, 14219878 }, + }, + { + { -28594490, 1193785, 32245219, 11392485, 31092169, 15722801, 27146014, 6992409, 29126555, 9207390 }, + { 32382935, 1110093, 18477781, 11028262, -27411763, -7548111, -4980517, 10843782, -7957600, -14435730 }, + { 2814918, 7836403, 27519878, -7868156, -20894015, -11553689, -21494559, 8550130, 28346258, 1994730 }, + }, + { + { -19578299, 8085545, -14000519, -3948622, 2785838, -16231307, -19516951, 7174894, 22628102, 8115180 }, + { -30405132, 955511, -11133838, -15078069, -32447087, -13278079, -25651578, 3317160, -9943017, 930272 }, + { -15303681, -6833769, 28856490, 1357446, 23421993, 1057177, 24091212, -1388970, -22765376, -10650715 }, + }, + { + { -22751231, -5303997, -12907607, -12768866, -15811511, -7797053, -14839018, -16554220, -1867018, 8398970 }, + { -31969310, 2106403, -4736360, 1362501, 12813763, 16200670, 22981545, -6291273, 18009408, -15772772 }, + { -17220923, -9545221, -27784654, 14166835, 29815394, 7444469, 29551787, -3727419, 19288549, 1325865 }, + }, + { + { 15100157, -15835752, -23923978, -1005098, -26450192, 15509408, 12376730, -3479146, 33166107, -8042750 }, + { 20909231, 13023121, -9209752, 16251778, -5778415, -8094914, 12412151, 10018715, 2213263, -13878373 }, + { 32529814, -11074689, 30361439, -16689753, -9135940, 1513226, 22922121, 6382134, -5766928, 8371348 }, + }, + }, + { + { + { 9923462, 11271500, 12616794, 3544722, -29998368, -1721626, 12891687, -8193132, -26442943, 10486144 }, + { -22597207, -7012665, 8587003, -8257861, 4084309, -12970062, 361726, 2610596, -23921530, -11455195 }, + { 5408411, -1136691, -4969122, 10561668, 24145918, 14240566, 31319731, -4235541, 19985175, -3436086 }, + }, + { + { -13994457, 16616821, 14549246, 3341099, 32155958, 13648976, -17577068, 8849297, 65030, 8370684 }, + { -8320926, -12049626, 31204563, 5839400, -20627288, -1057277, -19442942, 6922164, 12743482, -9800518 }, + { -2361371, 12678785, 28815050, 4759974, -23893047, 4884717, 23783145, 11038569, 18800704, 255233 }, + }, + { + { -5269658, -1773886, 13957886, 7990715, 23132995, 728773, 13393847, 9066957, 19258688, -14753793 }, + { -2936654, -10827535, -10432089, 14516793, -3640786, 4372541, -31934921, 2209390, -1524053, 2055794 }, + { 580882, 16705327, 5468415, -2683018, -30926419, -14696000, -7203346, -8994389, -30021019, 7394435 }, + }, + { + { 23838809, 1822728, -15738443, 15242727, 8318092, -3733104, -21672180, -3492205, -4821741, 14799921 }, + { 13345610, 9759151, 3371034, -16137791, 16353039, 8577942, 31129804, 13496856, -9056018, 7402518 }, + { 2286874, -4435931, -20042458, -2008336, -13696227, 5038122, 11006906, -15760352, 8205061, 1607563 }, + }, + { + { 14414086, -8002132, 3331830, -3208217, 22249151, -5594188, 18364661, -2906958, 30019587, -9029278 }, + { -27688051, 1585953, -10775053, 931069, -29120221, -11002319, -14410829, 12029093, 9944378, 8024 }, + { 4368715, -3709630, 29874200, -15022983, -20230386, -11410704, -16114594, -999085, -8142388, 5640030 }, + }, + { + { 10299610, 13746483, 11661824, 16234854, 7630238, 5998374, 9809887, -16694564, 15219798, -14327783 }, + { 27425505, -5719081, 3055006, 10660664, 23458024, 595578, -15398605, -1173195, -18342183, 9742717 }, + { 6744077, 2427284, 26042789, 2720740, -847906, 1118974, 32324614, 7406442, 12420155, 1994844 }, + }, + { + { 14012521, -5024720, -18384453, -9578469, -26485342, -3936439, -13033478, -10909803, 24319929, -6446333 }, + { 16412690, -4507367, 10772641, 15929391, -17068788, -4658621, 10555945, -10484049, -30102368, -4739048 }, + { 22397382, -7767684, -9293161, -12792868, 17166287, -9755136, -27333065, 6199366, 21880021, -12250760 }, + }, + { + { -4283307, 5368523, -31117018, 8163389, -30323063, 3209128, 16557151, 8890729, 8840445, 4957760 }, + { -15447727, 709327, -6919446, -10870178, -29777922, 6522332, -21720181, 12130072, -14796503, 5005757 }, + { -2114751, -14308128, 23019042, 15765735, -25269683, 6002752, 10183197, -13239326, -16395286, -2176112 }, + }, + }, + { + { + { -19025756, 1632005, 13466291, -7995100, -23640451, 16573537, -32013908, -3057104, 22208662, 2000468 }, + { 3065073, -1412761, -25598674, -361432, -17683065, -5703415, -8164212, 11248527, -3691214, -7414184 }, + { 10379208, -6045554, 8877319, 1473647, -29291284, -12507580, 16690915, 2553332, -3132688, 16400289 }, + }, + { + { 15716668, 1254266, -18472690, 7446274, -8448918, 6344164, -22097271, -7285580, 26894937, 9132066 }, + { 24158887, 12938817, 11085297, -8177598, -28063478, -4457083, -30576463, 64452, -6817084, -2692882 }, + { 13488534, 7794716, 22236231, 5989356, 25426474, -12578208, 2350710, -3418511, -4688006, 2364226 }, + }, + { + { 16335052, 9132434, 25640582, 6678888, 1725628, 8517937, -11807024, -11697457, 15445875, -7798101 }, + { 29004207, -7867081, 28661402, -640412, -12794003, -7943086, 31863255, -4135540, -278050, -15759279 }, + { -6122061, -14866665, -28614905, 14569919, -10857999, -3591829, 10343412, -6976290, -29828287, -10815811 }, + }, + { + { 27081650, 3463984, 14099042, -4517604, 1616303, -6205604, 29542636, 15372179, 17293797, 960709 }, + { 20263915, 11434237, -5765435, 11236810, 13505955, -10857102, -16111345, 6493122, -19384511, 7639714 }, + { -2830798, -14839232, 25403038, -8215196, -8317012, -16173699, 18006287, -16043750, 29994677, -15808121 }, + }, + { + { 9769828, 5202651, -24157398, -13631392, -28051003, -11561624, -24613141, -13860782, -31184575, 709464 }, + { 12286395, 13076066, -21775189, -1176622, -25003198, 4057652, -32018128, -8890874, 16102007, 13205847 }, + { 13733362, 5599946, 10557076, 3195751, -5557991, 8536970, -25540170, 8525972, 10151379, 10394400 }, + }, + { + { 4024660, -16137551, 22436262, 12276534, -9099015, -2686099, 19698229, 11743039, -33302334, 8934414 }, + { -15879800, -4525240, -8580747, -2934061, 14634845, -698278, -9449077, 3137094, -11536886, 11721158 }, + { 17555939, -5013938, 8268606, 2331751, -22738815, 9761013, 9319229, 8835153, -9205489, -1280045 }, + }, + { + { -461409, -7830014, 20614118, 16688288, -7514766, -4807119, 22300304, 505429, 6108462, -6183415 }, + { -5070281, 12367917, -30663534, 3234473, 32617080, -8422642, 29880583, -13483331, -26898490, -7867459 }, + { -31975283, 5726539, 26934134, 10237677, -3173717, -605053, 24199304, 3795095, 7592688, -14992079 }, + }, + { + { 21594432, -14964228, 17466408, -4077222, 32537084, 2739898, 6407723, 12018833, -28256052, 4298412 }, + { -20650503, -11961496, -27236275, 570498, 3767144, -1717540, 13891942, -1569194, 13717174, 10805743 }, + { -14676630, -15644296, 15287174, 11927123, 24177847, -8175568, -796431, 14860609, -26938930, -5863836 }, + }, + }, + { + { + { 12962541, 5311799, -10060768, 11658280, 18855286, -7954201, 13286263, -12808704, -4381056, 9882022 }, + { 18512079, 11319350, -20123124, 15090309, 18818594, 5271736, -22727904, 3666879, -23967430, -3299429 }, + { -6789020, -3146043, 16192429, 13241070, 15898607, -14206114, -10084880, -6661110, -2403099, 5276065 }, + }, + { + { 30169808, -5317648, 26306206, -11750859, 27814964, 7069267, 7152851, 3684982, 1449224, 13082861 }, + { 10342826, 3098505, 2119311, 193222, 25702612, 12233820, 23697382, 15056736, -21016438, -8202000 }, + { -33150110, 3261608, 22745853, 7948688, 19370557, -15177665, -26171976, 6482814, -10300080, -11060101 }, + }, + { + { 32869458, -5408545, 25609743, 15678670, -10687769, -15471071, 26112421, 2521008, -22664288, 6904815 }, + { 29506923, 4457497, 3377935, -9796444, -30510046, 12935080, 1561737, 3841096, -29003639, -6657642 }, + { 10340844, -6630377, -18656632, -2278430, 12621151, -13339055, 30878497, -11824370, -25584551, 5181966 }, + }, + { + { 25940115, -12658025, 17324188, -10307374, -8671468, 15029094, 24396252, -16450922, -2322852, -12388574 }, + { -21765684, 9916823, -1300409, 4079498, -1028346, 11909559, 1782390, 12641087, 20603771, -6561742 }, + { -18882287, -11673380, 24849422, 11501709, 13161720, -4768874, 1925523, 11914390, 4662781, 7820689 }, + }, + { + { 12241050, -425982, 8132691, 9393934, 32846760, -1599620, 29749456, 12172924, 16136752, 15264020 }, + { -10349955, -14680563, -8211979, 2330220, -17662549, -14545780, 10658213, 6671822, 19012087, 3772772 }, + { 3753511, -3421066, 10617074, 2028709, 14841030, -6721664, 28718732, -15762884, 20527771, 12988982 }, + }, + { + { -14822485, -5797269, -3707987, 12689773, -898983, -10914866, -24183046, -10564943, 3299665, -12424953 }, + { -16777703, -15253301, -9642417, 4978983, 3308785, 8755439, 6943197, 6461331, -25583147, 8991218 }, + { -17226263, 1816362, -1673288, -6086439, 31783888, -8175991, -32948145, 7417950, -30242287, 1507265 }, + }, + { + { 29692663, 6829891, -10498800, 4334896, 20945975, -11906496, -28887608, 8209391, 14606362, -10647073 }, + { -3481570, 8707081, 32188102, 5672294, 22096700, 1711240, -33020695, 9761487, 4170404, -2085325 }, + { -11587470, 14855945, -4127778, -1531857, -26649089, 15084046, 22186522, 16002000, -14276837, -8400798 }, + }, + { + { -4811456, 13761029, -31703877, -2483919, -3312471, 7869047, -7113572, -9620092, 13240845, 10965870 }, + { -7742563, -8256762, -14768334, -13656260, -23232383, 12387166, 4498947, 14147411, 29514390, 4302863 }, + { -13413405, -12407859, 20757302, -13801832, 14785143, 8976368, -5061276, -2144373, 17846988, -13971927 }, + }, + }, + { + { + { -2244452, -754728, -4597030, -1066309, -6247172, 1455299, -21647728, -9214789, -5222701, 12650267 }, + { -9906797, -16070310, 21134160, 12198166, -27064575, 708126, 387813, 13770293, -19134326, 10958663 }, + { 22470984, 12369526, 23446014, -5441109, -21520802, -9698723, -11772496, -11574455, -25083830, 4271862 }, + }, + { + { -25169565, -10053642, -19909332, 15361595, -5984358, 2159192, 75375, -4278529, -32526221, 8469673 }, + { 15854970, 4148314, -8893890, 7259002, 11666551, 13824734, -30531198, 2697372, 24154791, -9460943 }, + { 15446137, -15806644, 29759747, 14019369, 30811221, -9610191, -31582008, 12840104, 24913809, 9815020 }, + }, + { + { -4709286, -5614269, -31841498, -12288893, -14443537, 10799414, -9103676, 13438769, 18735128, 9466238 }, + { 11933045, 9281483, 5081055, -5183824, -2628162, -4905629, -7727821, -10896103, -22728655, 16199064 }, + { 14576810, 379472, -26786533, -8317236, -29426508, -10812974, -102766, 1876699, 30801119, 2164795 }, + }, + { + { 15995086, 3199873, 13672555, 13712240, -19378835, -4647646, -13081610, -15496269, -13492807, 1268052 }, + { -10290614, -3659039, -3286592, 10948818, 23037027, 3794475, -3470338, -12600221, -17055369, 3565904 }, + { 29210088, -9419337, -5919792, -4952785, 10834811, -13327726, -16512102, -10820713, -27162222, -14030531 }, + }, + { + { -13161890, 15508588, 16663704, -8156150, -28349942, 9019123, -29183421, -3769423, 2244111, -14001979 }, + { -5152875, -3800936, -9306475, -6071583, 16243069, 14684434, -25673088, -16180800, 13491506, 4641841 }, + { 10813417, 643330, -19188515, -728916, 30292062, -16600078, 27548447, -7721242, 14476989, -12767431 }, + }, + { + { 10292079, 9984945, 6481436, 8279905, -7251514, 7032743, 27282937, -1644259, -27912810, 12651324 }, + { -31185513, -813383, 22271204, 11835308, 10201545, 15351028, 17099662, 3988035, 21721536, -3148940 }, + { 10202177, -6545839, -31373232, -9574638, -32150642, -8119683, -12906320, 3852694, 13216206, 14842320 }, + }, + { + { -15815640, -10601066, -6538952, -7258995, -6984659, -6581778, -31500847, 13765824, -27434397, 9900184 }, + { 14465505, -13833331, -32133984, -14738873, -27443187, 12990492, 33046193, 15796406, -7051866, -8040114 }, + { 30924417, -8279620, 6359016, -12816335, 16508377, 9071735, -25488601, 15413635, 9524356, -7018878 }, + }, + { + { 12274201, -13175547, 32627641, -1785326, 6736625, 13267305, 5237659, -5109483, 15663516, 4035784 }, + { -2951309, 8903985, 17349946, 601635, -16432815, -4612556, -13732739, -15889334, -22258478, 4659091 }, + { -16916263, -4952973, -30393711, -15158821, 20774812, 15897498, 5736189, 15026997, -2178256, -13455585 }, + }, + }, + { + { + { -8858980, -2219056, 28571666, -10155518, -474467, -10105698, -3801496, 278095, 23440562, -290208 }, + { 10226241, -5928702, 15139956, 120818, -14867693, 5218603, 32937275, 11551483, -16571960, -7442864 }, + { 17932739, -12437276, -24039557, 10749060, 11316803, 7535897, 22503767, 5561594, -3646624, 3898661 }, + }, + { + { 7749907, -969567, -16339731, -16464, -25018111, 15122143, -1573531, 7152530, 21831162, 1245233 }, + { 26958459, -14658026, 4314586, 8346991, -5677764, 11960072, -32589295, -620035, -30402091, -16716212 }, + { -12165896, 9166947, 33491384, 13673479, 29787085, 13096535, 6280834, 14587357, -22338025, 13987525 }, + }, + { + { -24349909, 7778775, 21116000, 15572597, -4833266, -5357778, -4300898, -5124639, -7469781, -2858068 }, + { 9681908, -6737123, -31951644, 13591838, -6883821, 386950, 31622781, 6439245, -14581012, 4091397 }, + { -8426427, 1470727, -28109679, -1596990, 3978627, -5123623, -19622683, 12092163, 29077877, -14741988 }, + }, + { + { 5269168, -6859726, -13230211, -8020715, 25932563, 1763552, -5606110, -5505881, -20017847, 2357889 }, + { 32264008, -15407652, -5387735, -1160093, -2091322, -3946900, 23104804, -12869908, 5727338, 189038 }, + { 14609123, -8954470, -6000566, -16622781, -14577387, -7743898, -26745169, 10942115, -25888931, -14884697 }, + }, + { + { 20513500, 5557931, -15604613, 7829531, 26413943, -2019404, -21378968, 7471781, 13913677, -5137875 }, + { -25574376, 11967826, 29233242, 12948236, -6754465, 4713227, -8940970, 14059180, 12878652, 8511905 }, + { -25656801, 3393631, -2955415, -7075526, -2250709, 9366908, -30223418, 6812974, 5568676, -3127656 }, + }, + { + { 11630004, 12144454, 2116339, 13606037, 27378885, 15676917, -17408753, -13504373, -14395196, 8070818 }, + { 27117696, -10007378, -31282771, -5570088, 1127282, 12772488, -29845906, 10483306, -11552749, -1028714 }, + { 10637467, -5688064, 5674781, 1072708, -26343588, -6982302, -1683975, 9177853, -27493162, 15431203 }, + }, + { + { 20525145, 10892566, -12742472, 12779443, -29493034, 16150075, -28240519, 14943142, -15056790, -7935931 }, + { -30024462, 5626926, -551567, -9981087, 753598, 11981191, 25244767, -3239766, -3356550, 9594024 }, + { -23752644, 2636870, -5163910, -10103818, 585134, 7877383, 11345683, -6492290, 13352335, -10977084 }, + }, + { + { -1931799, -5407458, 3304649, -12884869, 17015806, -4877091, -29783850, -7752482, -13215537, -319204 }, + { 20239939, 6607058, 6203985, 3483793, -18386976, -779229, -20723742, 15077870, -22750759, 14523817 }, + { 27406042, -6041657, 27423596, -4497394, 4996214, 10002360, -28842031, -4545494, -30172742, -4805667 }, + }, + }, + { + { + { 11374242, 12660715, 17861383, -12540833, 10935568, 1099227, -13886076, -9091740, -27727044, 11358504 }, + { -12730809, 10311867, 1510375, 10778093, -2119455, -9145702, 32676003, 11149336, -26123651, 4985768 }, + { -19096303, 341147, -6197485, -239033, 15756973, -8796662, -983043, 13794114, -19414307, -15621255 }, + }, + { + { 6490081, 11940286, 25495923, -7726360, 8668373, -8751316, 3367603, 6970005, -1691065, -9004790 }, + { 1656497, 13457317, 15370807, 6364910, 13605745, 8362338, -19174622, -5475723, -16796596, -5031438 }, + { -22273315, -13524424, -64685, -4334223, -18605636, -10921968, -20571065, -7007978, -99853, -10237333 }, + }, + { + { 17747465, 10039260, 19368299, -4050591, -20630635, -16041286, 31992683, -15857976, -29260363, -5511971 }, + { 31932027, -4986141, -19612382, 16366580, 22023614, 88450, 11371999, -3744247, 4882242, -10626905 }, + { 29796507, 37186, 19818052, 10115756, -11829032, 3352736, 18551198, 3272828, -5190932, -4162409 }, + }, + { + { 12501286, 4044383, -8612957, -13392385, -32430052, 5136599, -19230378, -3529697, 330070, -3659409 }, + { 6384877, 2899513, 17807477, 7663917, -2358888, 12363165, 25366522, -8573892, -271295, 12071499 }, + { -8365515, -4042521, 25133448, -4517355, -6211027, 2265927, -32769618, 1936675, -5159697, 3829363 }, + }, + { + { 28425966, -5835433, -577090, -4697198, -14217555, 6870930, 7921550, -6567787, 26333140, 14267664 }, + { -11067219, 11871231, 27385719, -10559544, -4585914, -11189312, 10004786, -8709488, -21761224, 8930324 }, + { -21197785, -16396035, 25654216, -1725397, 12282012, 11008919, 1541940, 4757911, -26491501, -16408940 }, + }, + { + { 13537262, -7759490, -20604840, 10961927, -5922820, -13218065, -13156584, 6217254, -15943699, 13814990 }, + { -17422573, 15157790, 18705543, 29619, 24409717, -260476, 27361681, 9257833, -1956526, -1776914 }, + { -25045300, -10191966, 15366585, 15166509, -13105086, 8423556, -29171540, 12361135, -18685978, 4578290 }, + }, + { + { 24579768, 3711570, 1342322, -11180126, -27005135, 14124956, -22544529, 14074919, 21964432, 8235257 }, + { -6528613, -2411497, 9442966, -5925588, 12025640, -1487420, -2981514, -1669206, 13006806, 2355433 }, + { -16304899, -13605259, -6632427, -5142349, 16974359, -10911083, 27202044, 1719366, 1141648, -12796236 }, + }, + { + { -12863944, -13219986, -8318266, -11018091, -6810145, -4843894, 13475066, -3133972, 32674895, 13715045 }, + { 11423335, -5468059, 32344216, 8962751, 24989809, 9241752, -13265253, 16086212, -28740881, -15642093 }, + { -1409668, 12530728, -6368726, 10847387, 19531186, -14132160, -11709148, 7791794, -27245943, 4383347 }, + }, + }, + { + { + { -28970898, 5271447, -1266009, -9736989, -12455236, 16732599, -4862407, -4906449, 27193557, 6245191 }, + { -15193956, 5362278, -1783893, 2695834, 4960227, 12840725, 23061898, 3260492, 22510453, 8577507 }, + { -12632451, 11257346, -32692994, 13548177, -721004, 10879011, 31168030, 13952092, -29571492, -3635906 }, + }, + { + { 3877321, -9572739, 32416692, 5405324, -11004407, -13656635, 3759769, 11935320, 5611860, 8164018 }, + { -16275802, 14667797, 15906460, 12155291, -22111149, -9039718, 32003002, -8832289, 5773085, -8422109 }, + { -23788118, -8254300, 1950875, 8937633, 18686727, 16459170, -905725, 12376320, 31632953, 190926 }, + }, + { + { -24593607, -16138885, -8423991, 13378746, 14162407, 6901328, -8288749, 4508564, -25341555, -3627528 }, + { 8884438, -5884009, 6023974, 10104341, -6881569, -4941533, 18722941, -14786005, -1672488, 827625 }, + { -32720583, -16289296, -32503547, 7101210, 13354605, 2659080, -1800575, -14108036, -24878478, 1541286 }, + }, + { + { 2901347, -1117687, 3880376, -10059388, -17620940, -3612781, -21802117, -3567481, 20456845, -1885033 }, + { 27019610, 12299467, -13658288, -1603234, -12861660, -4861471, -19540150, -5016058, 29439641, 15138866 }, + { 21536104, -6626420, -32447818, -10690208, -22408077, 5175814, -5420040, -16361163, 7779328, 109896 }, + }, + { + { 30279744, 14648750, -8044871, 6425558, 13639621, -743509, 28698390, 12180118, 23177719, -554075 }, + { 26572847, 3405927, -31701700, 12890905, -19265668, 5335866, -6493768, 2378492, 4439158, -13279347 }, + { -22716706, 3489070, -9225266, -332753, 18875722, -1140095, 14819434, -12731527, -17717757, -5461437 }, + }, + { + { -5056483, 16566551, 15953661, 3767752, -10436499, 15627060, -820954, 2177225, 8550082, -15114165 }, + { -18473302, 16596775, -381660, 15663611, 22860960, 15585581, -27844109, -3582739, -23260460, -8428588 }, + { -32480551, 15707275, -8205912, -5652081, 29464558, 2713815, -22725137, 15860482, -21902570, 1494193 }, + }, + { + { -19562091, -14087393, -25583872, -9299552, 13127842, 759709, 21923482, 16529112, 8742704, 12967017 }, + { -28464899, 1553205, 32536856, -10473729, -24691605, -406174, -8914625, -2933896, -29903758, 15553883 }, + { 21877909, 3230008, 9881174, 10539357, -4797115, 2841332, 11543572, 14513274, 19375923, -12647961 }, + }, + { + { 8832269, -14495485, 13253511, 5137575, 5037871, 4078777, 24880818, -6222716, 2862653, 9455043 }, + { 29306751, 5123106, 20245049, -14149889, 9592566, 8447059, -2077124, -2990080, 15511449, 4789663 }, + { -20679756, 7004547, 8824831, -9434977, -4045704, -3750736, -5754762, 108893, 23513200, 16652362 }, + }, + }, + { + { + { -33256173, 4144782, -4476029, -6579123, 10770039, -7155542, -6650416, -12936300, -18319198, 10212860 }, + { 2756081, 8598110, 7383731, -6859892, 22312759, -1105012, 21179801, 2600940, -9988298, -12506466 }, + { -24645692, 13317462, -30449259, -15653928, 21365574, -10869657, 11344424, 864440, -2499677, -16710063 }, + }, + { + { -26432803, 6148329, -17184412, -14474154, 18782929, -275997, -22561534, 211300, 2719757, 4940997 }, + { -1323882, 3911313, -6948744, 14759765, -30027150, 7851207, 21690126, 8518463, 26699843, 5276295 }, + { -13149873, -6429067, 9396249, 365013, 24703301, -10488939, 1321586, 149635, -15452774, 7159369 }, + }, + { + { 9987780, -3404759, 17507962, 9505530, 9731535, -2165514, 22356009, 8312176, 22477218, -8403385 }, + { 18155857, -16504990, 19744716, 9006923, 15154154, -10538976, 24256460, -4864995, -22548173, 9334109 }, + { 2986088, -4911893, 10776628, -3473844, 10620590, -7083203, -21413845, 14253545, -22587149, 536906 }, + }, + { + { 4377756, 8115836, 24567078, 15495314, 11625074, 13064599, 7390551, 10589625, 10838060, -15420424 }, + { -19342404, 867880, 9277171, -3218459, -14431572, -1986443, 19295826, -15796950, 6378260, 699185 }, + { 7895026, 4057113, -7081772, -13077756, -17886831, -323126, -716039, 15693155, -5045064, -13373962 }, + }, + { + { -7737563, -5869402, -14566319, -7406919, 11385654, 13201616, 31730678, -10962840, -3918636, -9669325 }, + { 10188286, -15770834, -7336361, 13427543, 22223443, 14896287, 30743455, 7116568, -21786507, 5427593 }, + { 696102, 13206899, 27047647, -10632082, 15285305, -9853179, 10798490, -4578720, 19236243, 12477404 }, + }, + { + { -11229439, 11243796, -17054270, -8040865, -788228, -8167967, -3897669, 11180504, -23169516, 7733644 }, + { 17800790, -14036179, -27000429, -11766671, 23887827, 3149671, 23466177, -10538171, 10322027, 15313801 }, + { 26246234, 11968874, 32263343, -5468728, 6830755, -13323031, -15794704, -101982, -24449242, 10890804 }, + }, + { + { -31365647, 10271363, -12660625, -6267268, 16690207, -13062544, -14982212, 16484931, 25180797, -5334884 }, + { -586574, 10376444, -32586414, -11286356, 19801893, 10997610, 2276632, 9482883, 316878, 13820577 }, + { -9882808, -4510367, -2115506, 16457136, -11100081, 11674996, 30756178, -7515054, 30696930, -3712849 }, + }, + { + { 32988917, -9603412, 12499366, 7910787, -10617257, -11931514, -7342816, -9985397, -32349517, 7392473 }, + { -8855661, 15927861, 9866406, -3649411, -2396914, -16655781, -30409476, -9134995, 25112947, -2926644 }, + { -2504044, -436966, 25621774, -5678772, 15085042, -5479877, -24884878, -13526194, 5537438, -13914319 }, + }, + }, + { + { + { -11225584, 2320285, -9584280, 10149187, -33444663, 5808648, -14876251, -1729667, 31234590, 6090599 }, + { -9633316, 116426, 26083934, 2897444, -6364437, -2688086, 609721, 15878753, -6970405, -9034768 }, + { -27757857, 247744, -15194774, -9002551, 23288161, -10011936, -23869595, 6503646, 20650474, 1804084 }, + }, + { + { -27589786, 15456424, 8972517, 8469608, 15640622, 4439847, 3121995, -10329713, 27842616, -202328 }, + { -15306973, 2839644, 22530074, 10026331, 4602058, 5048462, 28248656, 5031932, -11375082, 12714369 }, + { 20807691, -7270825, 29286141, 11421711, -27876523, -13868230, -21227475, 1035546, -19733229, 12796920 }, + }, + { + { 12076899, -14301286, -8785001, -11848922, -25012791, 16400684, -17591495, -12899438, 3480665, -15182815 }, + { -32361549, 5457597, 28548107, 7833186, 7303070, -11953545, -24363064, -15921875, -33374054, 2771025 }, + { -21389266, 421932, 26597266, 6860826, 22486084, -6737172, -17137485, -4210226, -24552282, 15673397 }, + }, + { + { -20184622, 2338216, 19788685, -9620956, -4001265, -8740893, -20271184, 4733254, 3727144, -12934448 }, + { 6120119, 814863, -11794402, -622716, 6812205, -15747771, 2019594, 7975683, 31123697, -10958981 }, + { 30069250, -11435332, 30434654, 2958439, 18399564, -976289, 12296869, 9204260, -16432438, 9648165 }, + }, + { + { 32705432, -1550977, 30705658, 7451065, -11805606, 9631813, 3305266, 5248604, -26008332, -11377501 }, + { 17219865, 2375039, -31570947, -5575615, -19459679, 9219903, 294711, 15298639, 2662509, -16297073 }, + { -1172927, -7558695, -4366770, -4287744, -21346413, -8434326, 32087529, -1222777, 32247248, -14389861 }, + }, + { + { 14312628, 1221556, 17395390, -8700143, -4945741, -8684635, -28197744, -9637817, -16027623, -13378845 }, + { -1428825, -9678990, -9235681, 6549687, -7383069, -468664, 23046502, 9803137, 17597934, 2346211 }, + { 18510800, 15337574, 26171504, 981392, -22241552, 7827556, -23491134, -11323352, 3059833, -11782870 }, + }, + { + { 10141598, 6082907, 17829293, -1947643, 9830092, 13613136, -25556636, -5544586, -33502212, 3592096 }, + { 33114168, -15889352, -26525686, -13343397, 33076705, 8716171, 1151462, 1521897, -982665, -6837803 }, + { -32939165, -4255815, 23947181, -324178, -33072974, -12305637, -16637686, 3891704, 26353178, 693168 }, + }, + { + { 30374239, 1595580, -16884039, 13186931, 4600344, 406904, 9585294, -400668, 31375464, 14369965 }, + { -14370654, -7772529, 1510301, 6434173, -18784789, -6262728, 32732230, -13108839, 17901441, 16011505 }, + { 18171223, -11934626, -12500402, 15197122, -11038147, -15230035, -19172240, -16046376, 8764035, 12309598 }, + }, + }, + { + { + { 5975908, -5243188, -19459362, -9681747, -11541277, 14015782, -23665757, 1228319, 17544096, -10593782 }, + { 5811932, -1715293, 3442887, -2269310, -18367348, -8359541, -18044043, -15410127, -5565381, 12348900 }, + { -31399660, 11407555, 25755363, 6891399, -3256938, 14872274, -24849353, 8141295, -10632534, -585479 }, + }, + { + { -12675304, 694026, -5076145, 13300344, 14015258, -14451394, -9698672, -11329050, 30944593, 1130208 }, + { 8247766, -6710942, -26562381, -7709309, -14401939, -14648910, 4652152, 2488540, 23550156, -271232 }, + { 17294316, -3788438, 7026748, 15626851, 22990044, 113481, 2267737, -5908146, -408818, -137719 }, + }, + { + { 16091085, -16253926, 18599252, 7340678, 2137637, -1221657, -3364161, 14550936, 3260525, -7166271 }, + { -4910104, -13332887, 18550887, 10864893, -16459325, -7291596, -23028869, -13204905, -12748722, 2701326 }, + { -8574695, 16099415, 4629974, -16340524, -20786213, -6005432, -10018363, 9276971, 11329923, 1862132 }, + }, + { + { 14763076, -15903608, -30918270, 3689867, 3511892, 10313526, -21951088, 12219231, -9037963, -940300 }, + { 8894987, -3446094, 6150753, 3013931, 301220, 15693451, -31981216, -2909717, -15438168, 11595570 }, + { 15214962, 3537601, -26238722, -14058872, 4418657, -15230761, 13947276, 10730794, -13489462, -4363670 }, + }, + { + { -2538306, 7682793, 32759013, 263109, -29984731, -7955452, -22332124, -10188635, 977108, 699994 }, + { -12466472, 4195084, -9211532, 550904, -15565337, 12917920, 19118110, -439841, -30534533, -14337913 }, + { 31788461, -14507657, 4799989, 7372237, 8808585, -14747943, 9408237, -10051775, 12493932, -5409317 }, + }, + { + { -25680606, 5260744, -19235809, -6284470, -3695942, 16566087, 27218280, 2607121, 29375955, 6024730 }, + { 842132, -2794693, -4763381, -8722815, 26332018, -12405641, 11831880, 6985184, -9940361, 2854096 }, + { -4847262, -7969331, 2516242, -5847713, 9695691, -7221186, 16512645, 960770, 12121869, 16648078 }, + }, + { + { -15218652, 14667096, -13336229, 2013717, 30598287, -464137, -31504922, -7882064, 20237806, 2838411 }, + { -19288047, 4453152, 15298546, -16178388, 22115043, -15972604, 12544294, -13470457, 1068881, -12499905 }, + { -9558883, -16518835, 33238498, 13506958, 30505848, -1114596, -8486907, -2630053, 12521378, 4845654 }, + }, + { + { -28198521, 10744108, -2958380, 10199664, 7759311, -13088600, 3409348, -873400, -6482306, -12885870 }, + { -23561822, 6230156, -20382013, 10655314, -24040585, -11621172, 10477734, -1240216, -3113227, 13974498 }, + { 12966261, 15550616, -32038948, -1615346, 21025980, -629444, 5642325, 7188737, 18895762, 12629579 }, + }, + }, + { + { + { 14741879, -14946887, 22177208, -11721237, 1279741, 8058600, 11758140, 789443, 32195181, 3895677 }, + { 10758205, 15755439, -4509950, 9243698, -4879422, 6879879, -2204575, -3566119, -8982069, 4429647 }, + { -2453894, 15725973, -20436342, -10410672, -5803908, -11040220, -7135870, -11642895, 18047436, -15281743 }, + }, + { + { -25173001, -11307165, 29759956, 11776784, -22262383, -15820455, 10993114, -12850837, -17620701, -9408468 }, + { 21987233, 700364, -24505048, 14972008, -7774265, -5718395, 32155026, 2581431, -29958985, 8773375 }, + { -25568350, 454463, -13211935, 16126715, 25240068, 8594567, 20656846, 12017935, -7874389, -13920155 }, + }, + { + { 6028182, 6263078, -31011806, -11301710, -818919, 2461772, -31841174, -5468042, -1721788, -2776725 }, + { -12278994, 16624277, 987579, -5922598, 32908203, 1248608, 7719845, -4166698, 28408820, 6816612 }, + { -10358094, -8237829, 19549651, -12169222, 22082623, 16147817, 20613181, 13982702, -10339570, 5067943 }, + }, + { + { -30505967, -3821767, 12074681, 13582412, -19877972, 2443951, -19719286, 12746132, 5331210, -10105944 }, + { 30528811, 3601899, -1957090, 4619785, -27361822, -15436388, 24180793, -12570394, 27679908, -1648928 }, + { 9402404, -13957065, 32834043, 10838634, -26580150, -13237195, 26653274, -8685565, 22611444, -12715406 }, + }, + { + { 22190590, 1118029, 22736441, 15130463, -30460692, -5991321, 19189625, -4648942, 4854859, 6622139 }, + { -8310738, -2953450, -8262579, -3388049, -10401731, -271929, 13424426, -3567227, 26404409, 13001963 }, + { -31241838, -15415700, -2994250, 8939346, 11562230, -12840670, -26064365, -11621720, -15405155, 11020693 }, + }, + { + { 1866042, -7949489, -7898649, -10301010, 12483315, 13477547, 3175636, -12424163, 28761762, 1406734 }, + { -448555, -1777666, 13018551, 3194501, -9580420, -11161737, 24760585, -4347088, 25577411, -13378680 }, + { -24290378, 4759345, -690653, -1852816, 2066747, 10693769, -29595790, 9884936, -9368926, 4745410 }, + }, + { + { -9141284, 6049714, -19531061, -4341411, -31260798, 9944276, -15462008, -11311852, 10931924, -11931931 }, + { -16561513, 14112680, -8012645, 4817318, -8040464, -11414606, -22853429, 10856641, -20470770, 13434654 }, + { 22759489, -10073434, -16766264, -1871422, 13637442, -10168091, 1765144, -12654326, 28445307, -5364710 }, + }, + { + { 29875063, 12493613, 2795536, -3786330, 1710620, 15181182, -10195717, -8788675, 9074234, 1167180 }, + { -26205683, 11014233, -9842651, -2635485, -26908120, 7532294, -18716888, -9535498, 3843903, 9367684 }, + { -10969595, -6403711, 9591134, 9582310, 11349256, 108879, 16235123, 8601684, -139197, 4242895 }, + }, + }, + { + { + { 22092954, -13191123, -2042793, -11968512, 32186753, -11517388, -6574341, 2470660, -27417366, 16625501 }, + { -11057722, 3042016, 13770083, -9257922, 584236, -544855, -7770857, 2602725, -27351616, 14247413 }, + { 6314175, -10264892, -32772502, 15957557, -10157730, 168750, -8618807, 14290061, 27108877, -1180880 }, + }, + { + { -8586597, -7170966, 13241782, 10960156, -32991015, -13794596, 33547976, -11058889, -27148451, 981874 }, + { 22833440, 9293594, -32649448, -13618667, -9136966, 14756819, -22928859, -13970780, -10479804, -16197962 }, + { -7768587, 3326786, -28111797, 10783824, 19178761, 14905060, 22680049, 13906969, -15933690, 3797899 }, + }, + { + { 21721356, -4212746, -12206123, 9310182, -3882239, -13653110, 23740224, -2709232, 20491983, -8042152 }, + { 9209270, -15135055, -13256557, -6167798, -731016, 15289673, 25947805, 15286587, 30997318, -6703063 }, + { 7392032, 16618386, 23946583, -8039892, -13265164, -1533858, -14197445, -2321576, 17649998, -250080 }, + }, + { + { -9301088, -14193827, 30609526, -3049543, -25175069, -1283752, -15241566, -9525724, -2233253, 7662146 }, + { -17558673, 1763594, -33114336, 15908610, -30040870, -12174295, 7335080, -8472199, -3174674, 3440183 }, + { -19889700, -5977008, -24111293, -9688870, 10799743, -16571957, 40450, -4431835, 4862400, 1133 }, + }, + { + { -32856209, -7873957, -5422389, 14860950, -16319031, 7956142, 7258061, 311861, -30594991, -7379421 }, + { -3773428, -1565936, 28985340, 7499440, 24445838, 9325937, 29727763, 16527196, 18278453, 15405622 }, + { -4381906, 8508652, -19898366, -3674424, -5984453, 15149970, -13313598, 843523, -21875062, 13626197 }, + }, + { + { 2281448, -13487055, -10915418, -2609910, 1879358, 16164207, -10783882, 3953792, 13340839, 15928663 }, + { 31727126, -7179855, -18437503, -8283652, 2875793, -16390330, -25269894, -7014826, -23452306, 5964753 }, + { 4100420, -5959452, -17179337, 6017714, -18705837, 12227141, -26684835, 11344144, 2538215, -7570755 }, + }, + { + { -9433605, 6123113, 11159803, -2156608, 30016280, 14966241, -20474983, 1485421, -629256, -15958862 }, + { -26804558, 4260919, 11851389, 9658551, -32017107, 16367492, -20205425, -13191288, 11659922, -11115118 }, + { 26180396, 10015009, -30844224, -8581293, 5418197, 9480663, 2231568, -10170080, 33100372, -1306171 }, + }, + { + { 15121113, -5201871, -10389905, 15427821, -27509937, -15992507, 21670947, 4486675, -5931810, -14466380 }, + { 16166486, -9483733, -11104130, 6023908, -31926798, -1364923, 2340060, -16254968, -10735770, -10039824 }, + { 28042865, -3557089, -12126526, 12259706, -3717498, -6945899, 6766453, -8689599, 18036436, 5803270 }, + }, + }, + { + { + { -817581, 6763912, 11803561, 1585585, 10958447, -2671165, 23855391, 4598332, -6159431, -14117438 }, + { -31031306, -14256194, 17332029, -2383520, 31312682, -5967183, 696309, 50292, -20095739, 11763584 }, + { -594563, -2514283, -32234153, 12643980, 12650761, 14811489, 665117, -12613632, -19773211, -10713562 }, + }, + { + { 30464590, -11262872, -4127476, -12734478, 19835327, -7105613, -24396175, 2075773, -17020157, 992471 }, + { 18357185, -6994433, 7766382, 16342475, -29324918, 411174, 14578841, 8080033, -11574335, -10601610 }, + { 19598397, 10334610, 12555054, 2555664, 18821899, -10339780, 21873263, 16014234, 26224780, 16452269 }, + }, + { + { -30223925, 5145196, 5944548, 16385966, 3976735, 2009897, -11377804, -7618186, -20533829, 3698650 }, + { 14187449, 3448569, -10636236, -10810935, -22663880, -3433596, 7268410, -10890444, 27394301, 12015369 }, + { 19695761, 16087646, 28032085, 12999827, 6817792, 11427614, 20244189, -1312777, -13259127, -3402461 }, + }, + { + { 30860103, 12735208, -1888245, -4699734, -16974906, 2256940, -8166013, 12298312, -8550524, -10393462 }, + { -5719826, -11245325, -1910649, 15569035, 26642876, -7587760, -5789354, -15118654, -4976164, 12651793 }, + { -2848395, 9953421, 11531313, -5282879, 26895123, -12697089, -13118820, -16517902, 9768698, -2533218 }, + }, + { + { -24719459, 1894651, -287698, -4704085, 15348719, -8156530, 32767513, 12765450, 4940095, 10678226 }, + { 18860224, 15980149, -18987240, -1562570, -26233012, -11071856, -7843882, 13944024, -24372348, 16582019 }, + { -15504260, 4970268, -29893044, 4175593, -20993212, -2199756, -11704054, 15444560, -11003761, 7989037 }, + }, + { + { 31490452, 5568061, -2412803, 2182383, -32336847, 4531686, -32078269, 6200206, -19686113, -14800171 }, + { -17308668, -15879940, -31522777, -2831, -32887382, 16375549, 8680158, -16371713, 28550068, -6857132 }, + { -28126887, -5688091, 16837845, -1820458, -6850681, 12700016, -30039981, 4364038, 1155602, 5988841 }, + }, + { + { 21890435, -13272907, -12624011, 12154349, -7831873, 15300496, 23148983, -4470481, 24618407, 8283181 }, + { -33136107, -10512751, 9975416, 6841041, -31559793, 16356536, 3070187, -7025928, 1466169, 10740210 }, + { -1509399, -15488185, -13503385, -10655916, 32799044, 909394, -13938903, -5779719, -32164649, -15327040 }, + }, + { + { 3960823, -14267803, -28026090, -15918051, -19404858, 13146868, 15567327, 951507, -3260321, -573935 }, + { 24740841, 5052253, -30094131, 8961361, 25877428, 6165135, -24368180, 14397372, -7380369, -6144105 }, + { -28888365, 3510803, -28103278, -1158478, -11238128, -10631454, -15441463, -14453128, -1625486, -6494814 }, + }, + }, + { + { + { 793299, -9230478, 8836302, -6235707, -27360908, -2369593, 33152843, -4885251, -9906200, -621852 }, + { 5666233, 525582, 20782575, -8038419, -24538499, 14657740, 16099374, 1468826, -6171428, -15186581 }, + { -4859255, -3779343, -2917758, -6748019, 7778750, 11688288, -30404353, -9871238, -1558923, -9863646 }, + }, + { + { 10896332, -7719704, 824275, 472601, -19460308, 3009587, 25248958, 14783338, -30581476, -15757844 }, + { 10566929, 12612572, -31944212, 11118703, -12633376, 12362879, 21752402, 8822496, 24003793, 14264025 }, + { 27713862, -7355973, -11008240, 9227530, 27050101, 2504721, 23886875, -13117525, 13958495, -5732453 }, + }, + { + { -23481610, 4867226, -27247128, 3900521, 29838369, -8212291, -31889399, -10041781, 7340521, -15410068 }, + { 4646514, -8011124, -22766023, -11532654, 23184553, 8566613, 31366726, -1381061, -15066784, -10375192 }, + { -17270517, 12723032, -16993061, 14878794, 21619651, -6197576, 27584817, 3093888, -8843694, 3849921 }, + }, + { + { -9064912, 2103172, 25561640, -15125738, -5239824, 9582958, 32477045, -9017955, 5002294, -15550259 }, + { -12057553, -11177906, 21115585, -13365155, 8808712, -12030708, 16489530, 13378448, -25845716, 12741426 }, + { -5946367, 10645103, -30911586, 15390284, -3286982, -7118677, 24306472, 15852464, 28834118, -7646072 }, + }, + { + { -17335748, -9107057, -24531279, 9434953, -8472084, -583362, -13090771, 455841, 20461858, 5491305 }, + { 13669248, -16095482, -12481974, -10203039, -14569770, -11893198, -24995986, 11293807, -28588204, -9421832 }, + { 28497928, 6272777, -33022994, 14470570, 8906179, -1225630, 18504674, -14165166, 29867745, -8795943 }, + }, + { + { -16207023, 13517196, -27799630, -13697798, 24009064, -6373891, -6367600, -13175392, 22853429, -4012011 }, + { 24191378, 16712145, -13931797, 15217831, 14542237, 1646131, 18603514, -11037887, 12876623, -2112447 }, + { 17902668, 4518229, -411702, -2829247, 26878217, 5258055, -12860753, 608397, 16031844, 3723494 }, + }, + { + { -28632773, 12763728, -20446446, 7577504, 33001348, -13017745, 17558842, -7872890, 23896954, -4314245 }, + { -20005381, -12011952, 31520464, 605201, 2543521, 5991821, -2945064, 7229064, -9919646, -8826859 }, + { 28816045, 298879, -28165016, -15920938, 19000928, -1665890, -12680833, -2949325, -18051778, -2082915 }, + }, + { + { 16000882, -344896, 3493092, -11447198, -29504595, -13159789, 12577740, 16041268, -19715240, 7847707 }, + { 10151868, 10572098, 27312476, 7922682, 14825339, 4723128, -32855931, -6519018, -10020567, 3852848 }, + { -11430470, 15697596, -21121557, -4420647, 5386314, 15063598, 16514493, -15932110, 29330899, -15076224 }, + }, + }, + { + { + { -25499735, -4378794, -15222908, -6901211, 16615731, 2051784, 3303702, 15490, -27548796, 12314391 }, + { 15683520, -6003043, 18109120, -9980648, 15337968, -5997823, -16717435, 15921866, 16103996, -3731215 }, + { -23169824, -10781249, 13588192, -1628807, -3798557, -1074929, -19273607, 5402699, -29815713, -9841101 }, + }, + { + { 23190676, 2384583, -32714340, 3462154, -29903655, -1529132, -11266856, 8911517, -25205859, 2739713 }, + { 21374101, -3554250, -33524649, 9874411, 15377179, 11831242, -33529904, 6134907, 4931255, 11987849 }, + { -7732, -2978858, -16223486, 7277597, 105524, -322051, -31480539, 13861388, -30076310, 10117930 }, + }, + { + { -29501170, -10744872, -26163768, 13051539, -25625564, 5089643, -6325503, 6704079, 12890019, 15728940 }, + { -21972360, -11771379, -951059, -4418840, 14704840, 2695116, 903376, -10428139, 12885167, 8311031 }, + { -17516482, 5352194, 10384213, -13811658, 7506451, 13453191, 26423267, 4384730, 1888765, -5435404 }, + }, + { + { -25817338, -3107312, -13494599, -3182506, 30896459, -13921729, -32251644, -12707869, -19464434, -3340243 }, + { -23607977, -2665774, -526091, 4651136, 5765089, 4618330, 6092245, 14845197, 17151279, -9854116 }, + { -24830458, -12733720, -15165978, 10367250, -29530908, -265356, 22825805, -7087279, -16866484, 16176525 }, + }, + { + { -23583256, 6564961, 20063689, 3798228, -4740178, 7359225, 2006182, -10363426, -28746253, -10197509 }, + { -10626600, -4486402, -13320562, -5125317, 3432136, -6393229, 23632037, -1940610, 32808310, 1099883 }, + { 15030977, 5768825, -27451236, -2887299, -6427378, -15361371, -15277896, -6809350, 2051441, -15225865 }, + }, + { + { -3362323, -7239372, 7517890, 9824992, 23555850, 295369, 5148398, -14154188, -22686354, 16633660 }, + { 4577086, -16752288, 13249841, -15304328, 19958763, -14537274, 18559670, -10759549, 8402478, -9864273 }, + { -28406330, -1051581, -26790155, -907698, -17212414, -11030789, 9453451, -14980072, 17983010, 9967138 }, + }, + { + { -25762494, 6524722, 26585488, 9969270, 24709298, 1220360, -1677990, 7806337, 17507396, 3651560 }, + { -10420457, -4118111, 14584639, 15971087, -15768321, 8861010, 26556809, -5574557, -18553322, -11357135 }, + { 2839101, 14284142, 4029895, 3472686, 14402957, 12689363, -26642121, 8459447, -5605463, -7621941 }, + }, + { + { -4839289, -3535444, 9744961, 2871048, 25113978, 3187018, -25110813, -849066, 17258084, -7977739 }, + { 18164541, -10595176, -17154882, -1542417, 19237078, -9745295, 23357533, -15217008, 26908270, 12150756 }, + { -30264870, -7647865, 5112249, -7036672, -1499807, -6974257, 43168, -5537701, -32302074, 16215819 }, + }, + }, + { + { + { -6898905, 9824394, -12304779, -4401089, -31397141, -6276835, 32574489, 12532905, -7503072, -8675347 }, + { -27343522, -16515468, -27151524, -10722951, 946346, 16291093, 254968, 7168080, 21676107, -1943028 }, + { 21260961, -8424752, -16831886, -11920822, -23677961, 3968121, -3651949, -6215466, -3556191, -7913075 }, + }, + { + { 16544754, 13250366, -16804428, 15546242, -4583003, 12757258, -2462308, -8680336, -18907032, -9662799 }, + { -2415239, -15577728, 18312303, 4964443, -15272530, -12653564, 26820651, 16690659, 25459437, -4564609 }, + { -25144690, 11425020, 28423002, -11020557, -6144921, -15826224, 9142795, -2391602, -6432418, -1644817 }, + }, + { + { -23104652, 6253476, 16964147, -3768872, -25113972, -12296437, -27457225, -16344658, 6335692, 7249989 }, + { -30333227, 13979675, 7503222, -12368314, -11956721, -4621693, -30272269, 2682242, 25993170, -12478523 }, + { 4364628, 5930691, 32304656, -10044554, -8054781, 15091131, 22857016, -10598955, 31820368, 15075278 }, + }, + { + { 31879134, -8918693, 17258761, 90626, -8041836, -4917709, 24162788, -9650886, -17970238, 12833045 }, + { 19073683, 14851414, -24403169, -11860168, 7625278, 11091125, -19619190, 2074449, -9413939, 14905377 }, + { 24483667, -11935567, -2518866, -11547418, -1553130, 15355506, -25282080, 9253129, 27628530, -7555480 }, + }, + { + { 17597607, 8340603, 19355617, 552187, 26198470, -3176583, 4593324, -9157582, -14110875, 15297016 }, + { 510886, 14337390, -31785257, 16638632, 6328095, 2713355, -20217417, -11864220, 8683221, 2921426 }, + { 18606791, 11874196, 27155355, -5281482, -24031742, 6265446, -25178240, -1278924, 4674690, 13890525 }, + }, + { + { 13609624, 13069022, -27372361, -13055908, 24360586, 9592974, 14977157, 9835105, 4389687, 288396 }, + { 9922506, -519394, 13613107, 5883594, -18758345, -434263, -12304062, 8317628, 23388070, 16052080 }, + { 12720016, 11937594, -31970060, -5028689, 26900120, 8561328, -20155687, -11632979, -14754271, -10812892 }, + }, + { + { 15961858, 14150409, 26716931, -665832, -22794328, 13603569, 11829573, 7467844, -28822128, 929275 }, + { 11038231, -11582396, -27310482, -7316562, -10498527, -16307831, -23479533, -9371869, -21393143, 2465074 }, + { 20017163, -4323226, 27915242, 1529148, 12396362, 15675764, 13817261, -9658066, 2463391, -4622140 }, + }, + { + { -16358878, -12663911, -12065183, 4996454, -1256422, 1073572, 9583558, 12851107, 4003896, 12673717 }, + { -1731589, -15155870, -3262930, 16143082, 19294135, 13385325, 14741514, -9103726, 7903886, 2348101 }, + { 24536016, -16515207, 12715592, -3862155, 1511293, 10047386, -3842346, -7129159, -28377538, 10048127 }, + }, + }, + { + { + { -12622226, -6204820, 30718825, 2591312, -10617028, 12192840, 18873298, -7297090, -32297756, 15221632 }, + { -26478122, -11103864, 11546244, -1852483, 9180880, 7656409, -21343950, 2095755, 29769758, 6593415 }, + { -31994208, -2907461, 4176912, 3264766, 12538965, -868111, 26312345, -6118678, 30958054, 8292160 }, + }, + { + { 31429822, -13959116, 29173532, 15632448, 12174511, -2760094, 32808831, 3977186, 26143136, -3148876 }, + { 22648901, 1402143, -22799984, 13746059, 7936347, 365344, -8668633, -1674433, -3758243, -2304625 }, + { -15491917, 8012313, -2514730, -12702462, -23965846, -10254029, -1612713, -1535569, -16664475, 8194478 }, + }, + { + { 27338066, -7507420, -7414224, 10140405, -19026427, -6589889, 27277191, 8855376, 28572286, 3005164 }, + { 26287124, 4821776, 25476601, -4145903, -3764513, -15788984, -18008582, 1182479, -26094821, -13079595 }, + { -7171154, 3178080, 23970071, 6201893, -17195577, -4489192, -21876275, -13982627, 32208683, -1198248 }, + }, + { + { -16657702, 2817643, -10286362, 14811298, 6024667, 13349505, -27315504, -10497842, -27672585, -11539858 }, + { 15941029, -9405932, -21367050, 8062055, 31876073, -238629, -15278393, -1444429, 15397331, -4130193 }, + { 8934485, -13485467, -23286397, -13423241, -32446090, 14047986, 31170398, -1441021, -27505566, 15087184 }, + }, + { + { -18357243, -2156491, 24524913, -16677868, 15520427, -6360776, -15502406, 11461896, 16788528, -5868942 }, + { -1947386, 16013773, 21750665, 3714552, -17401782, -16055433, -3770287, -10323320, 31322514, -11615635 }, + { 21426655, -5650218, -13648287, -5347537, -28812189, -4920970, -18275391, -14621414, 13040862, -12112948 }, + }, + { + { 11293895, 12478086, -27136401, 15083750, -29307421, 14748872, 14555558, -13417103, 1613711, 4896935 }, + { -25894883, 15323294, -8489791, -8057900, 25967126, -13425460, 2825960, -4897045, -23971776, -11267415 }, + { -15924766, -5229880, -17443532, 6410664, 3622847, 10243618, 20615400, 12405433, -23753030, -8436416 }, + }, + { + { -7091295, 12556208, -20191352, 9025187, -17072479, 4333801, 4378436, 2432030, 23097949, -566018 }, + { 4565804, -16025654, 20084412, -7842817, 1724999, 189254, 24767264, 10103221, -18512313, 2424778 }, + { 366633, -11976806, 8173090, -6890119, 30788634, 5745705, -7168678, 1344109, -3642553, 12412659 }, + }, + { + { -24001791, 7690286, 14929416, -168257, -32210835, -13412986, 24162697, -15326504, -3141501, 11179385 }, + { 18289522, -14724954, 8056945, 16430056, -21729724, 7842514, -6001441, -1486897, -18684645, -11443503 }, + { 476239, 6601091, -6152790, -9723375, 17503545, -4863900, 27672959, 13403813, 11052904, 5219329 }, + }, + }, + { + { + { 20678546, -8375738, -32671898, 8849123, -5009758, 14574752, 31186971, -3973730, 9014762, -8579056 }, + { -13644050, -10350239, -15962508, 5075808, -1514661, -11534600, -33102500, 9160280, 8473550, -3256838 }, + { 24900749, 14435722, 17209120, -15292541, -22592275, 9878983, -7689309, -16335821, -24568481, 11788948 }, + }, + { + { -3118155, -11395194, -13802089, 14797441, 9652448, -6845904, -20037437, 10410733, -24568470, -1458691 }, + { -15659161, 16736706, -22467150, 10215878, -9097177, 7563911, 11871841, -12505194, -18513325, 8464118 }, + { -23400612, 8348507, -14585951, -861714, -3950205, -6373419, 14325289, 8628612, 33313881, -8370517 }, + }, + { + { -20186973, -4967935, 22367356, 5271547, -1097117, -4788838, -24805667, -10236854, -8940735, -5818269 }, + { -6948785, -1795212, -32625683, -16021179, 32635414, -7374245, 15989197, -12838188, 28358192, -4253904 }, + { -23561781, -2799059, -32351682, -1661963, -9147719, 10429267, -16637684, 4072016, -5351664, 5596589 }, + }, + { + { -28236598, -3390048, 12312896, 6213178, 3117142, 16078565, 29266239, 2557221, 1768301, 15373193 }, + { -7243358, -3246960, -4593467, -7553353, -127927, -912245, -1090902, -4504991, -24660491, 3442910 }, + { -30210571, 5124043, 14181784, 8197961, 18964734, -11939093, 22597931, 7176455, -18585478, 13365930 }, + }, + { + { -7877390, -1499958, 8324673, 4690079, 6261860, 890446, 24538107, -8570186, -9689599, -3031667 }, + { 25008904, -10771599, -4305031, -9638010, 16265036, 15721635, 683793, -11823784, 15723479, -15163481 }, + { -9660625, 12374379, -27006999, -7026148, -7724114, -12314514, 11879682, 5400171, 519526, -1235876 }, + }, + { + { 22258397, -16332233, -7869817, 14613016, -22520255, -2950923, -20353881, 7315967, 16648397, 7605640 }, + { -8081308, -8464597, -8223311, 9719710, 19259459, -15348212, 23994942, -5281555, -9468848, 4763278 }, + { -21699244, 9220969, -15730624, 1084137, -25476107, -2852390, 31088447, -7764523, -11356529, 728112 }, + }, + { + { 26047220, -11751471, -6900323, -16521798, 24092068, 9158119, -4273545, -12555558, -29365436, -5498272 }, + { 17510331, -322857, 5854289, 8403524, 17133918, -3112612, -28111007, 12327945, 10750447, 10014012 }, + { -10312768, 3936952, 9156313, -8897683, 16498692, -994647, -27481051, -666732, 3424691, 7540221 }, + }, + { + { 30322361, -6964110, 11361005, -4143317, 7433304, 4989748, -7071422, -16317219, -9244265, 15258046 }, + { 13054562, -2779497, 19155474, 469045, -12482797, 4566042, 5631406, 2711395, 1062915, -5136345 }, + { -19240248, -11254599, -29509029, -7499965, -5835763, 13005411, -6066489, 12194497, 32960380, 1459310 }, + }, + }, + { + { + { 19852034, 7027924, 23669353, 10020366, 8586503, -6657907, 394197, -6101885, 18638003, -11174937 }, + { 31395534, 15098109, 26581030, 8030562, -16527914, -5007134, 9012486, -7584354, -6643087, -5442636 }, + { -9192165, -2347377, -1997099, 4529534, 25766844, 607986, -13222, 9677543, -32294889, -6456008 }, + }, + { + { -2444496, -149937, 29348902, 8186665, 1873760, 12489863, -30934579, -7839692, -7852844, -8138429 }, + { -15236356, -15433509, 7766470, 746860, 26346930, -10221762, -27333451, 10754588, -9431476, 5203576 }, + { 31834314, 14135496, -770007, 5159118, 20917671, -16768096, -7467973, -7337524, 31809243, 7347066 }, + }, + { + { -9606723, -11874240, 20414459, 13033986, 13716524, -11691881, 19797970, -12211255, 15192876, -2087490 }, + { -12663563, -2181719, 1168162, -3804809, 26747877, -14138091, 10609330, 12694420, 33473243, -13382104 }, + { 33184999, 11180355, 15832085, -11385430, -1633671, 225884, 15089336, -11023903, -6135662, 14480053 }, + }, + { + { 31308717, -5619998, 31030840, -1897099, 15674547, -6582883, 5496208, 13685227, 27595050, 8737275 }, + { -20318852, -15150239, 10933843, -16178022, 8335352, -7546022, -31008351, -12610604, 26498114, 66511 }, + { 22644454, -8761729, -16671776, 4884562, -3105614, -13559366, 30540766, -4286747, -13327787, -7515095 }, + }, + { + { -28017847, 9834845, 18617207, -2681312, -3401956, -13307506, 8205540, 13585437, -17127465, 15115439 }, + { 23711543, -672915, 31206561, -8362711, 6164647, -9709987, -33535882, -1426096, 8236921, 16492939 }, + { -23910559, -13515526, -26299483, -4503841, 25005590, -7687270, 19574902, 10071562, 6708380, -6222424 }, + }, + { + { 2101391, -4930054, 19702731, 2367575, -15427167, 1047675, 5301017, 9328700, 29955601, -11678310 }, + { 3096359, 9271816, -21620864, -15521844, -14847996, -7592937, -25892142, -12635595, -9917575, 6216608 }, + { -32615849, 338663, -25195611, 2510422, -29213566, -13820213, 24822830, -6146567, -26767480, 7525079 }, + }, + { + { -23066649, -13985623, 16133487, -7896178, -3389565, 778788, -910336, -2782495, -19386633, 11994101 }, + { 21691500, -13624626, -641331, -14367021, 3285881, -3483596, -25064666, 9718258, -7477437, 13381418 }, + { 18445390, -4202236, 14979846, 11622458, -1727110, -3582980, 23111648, -6375247, 28535282, 15779576 }, + }, + { + { 30098053, 3089662, -9234387, 16662135, -21306940, 11308411, -14068454, 12021730, 9955285, -16303356 }, + { 9734894, -14576830, -7473633, -9138735, 2060392, 11313496, -18426029, 9924399, 20194861, 13380996 }, + { -26378102, -7965207, -22167821, 15789297, -18055342, -6168792, -1984914, 15707771, 26342023, 10146099 }, + }, + }, + { + { + { -26016874, -219943, 21339191, -41388, 19745256, -2878700, -29637280, 2227040, 21612326, -545728 }, + { -13077387, 1184228, 23562814, -5970442, -20351244, -6348714, 25764461, 12243797, -20856566, 11649658 }, + { -10031494, 11262626, 27384172, 2271902, 26947504, -15997771, 39944, 6114064, 33514190, 2333242 }, + }, + { + { -21433588, -12421821, 8119782, 7219913, -21830522, -9016134, -6679750, -12670638, 24350578, -13450001 }, + { -4116307, -11271533, -23886186, 4843615, -30088339, 690623, -31536088, -10406836, 8317860, 12352766 }, + { 18200138, -14475911, -33087759, -2696619, -23702521, -9102511, -23552096, -2287550, 20712163, 6719373 }, + }, + { + { 26656208, 6075253, -7858556, 1886072, -28344043, 4262326, 11117530, -3763210, 26224235, -3297458 }, + { -17168938, -14854097, -3395676, -16369877, -19954045, 14050420, 21728352, 9493610, 18620611, -16428628 }, + { -13323321, 13325349, 11432106, 5964811, 18609221, 6062965, -5269471, -9725556, -30701573, -16479657 }, + }, + { + { -23860538, -11233159, 26961357, 1640861, -32413112, -16737940, 12248509, -5240639, 13735342, 1934062 }, + { 25089769, 6742589, 17081145, -13406266, 21909293, -16067981, -15136294, -3765346, -21277997, 5473616 }, + { 31883677, -7961101, 1083432, -11572403, 22828471, 13290673, -7125085, 12469656, 29111212, -5451014 }, + }, + { + { 24244947, -15050407, -26262976, 2791540, -14997599, 16666678, 24367466, 6388839, -10295587, 452383 }, + { -25640782, -3417841, 5217916, 16224624, 19987036, -4082269, -24236251, -5915248, 15766062, 8407814 }, + { -20406999, 13990231, 15495425, 16395525, 5377168, 15166495, -8917023, -4388953, -8067909, 2276718 }, + }, + { + { 30157918, 12924066, -17712050, 9245753, 19895028, 3368142, -23827587, 5096219, 22740376, -7303417 }, + { 2041139, -14256350, 7783687, 13876377, -25946985, -13352459, 24051124, 13742383, -15637599, 13295222 }, + { 33338237, -8505733, 12532113, 7977527, 9106186, -1715251, -17720195, -4612972, -4451357, -14669444 }, + }, + { + { -20045281, 5454097, -14346548, 6447146, 28862071, 1883651, -2469266, -4141880, 7770569, 9620597 }, + { 23208068, 7979712, 33071466, 8149229, 1758231, -10834995, 30945528, -1694323, -33502340, -14767970 }, + { 1439958, -16270480, -1079989, -793782, 4625402, 10647766, -5043801, 1220118, 30494170, -11440799 }, + }, + { + { -5037580, -13028295, -2970559, -3061767, 15640974, -6701666, -26739026, 926050, -1684339, -13333647 }, + { 13908495, -3549272, 30919928, -6273825, -21521863, 7989039, 9021034, 9078865, 3353509, 4033511 }, + { -29663431, -15113610, 32259991, -344482, 24295849, -12912123, 23161163, 8839127, 27485041, 7356032 }, + }, + }, + { + { + { 9661027, 705443, 11980065, -5370154, -1628543, 14661173, -6346142, 2625015, 28431036, -16771834 }, + { -23839233, -8311415, -25945511, 7480958, -17681669, -8354183, -22545972, 14150565, 15970762, 4099461 }, + { 29262576, 16756590, 26350592, -8793563, 8529671, -11208050, 13617293, -9937143, 11465739, 8317062 }, + }, + { + { -25493081, -6962928, 32500200, -9419051, -23038724, -2302222, 14898637, 3848455, 20969334, -5157516 }, + { -20384450, -14347713, -18336405, 13884722, -33039454, 2842114, -21610826, -3649888, 11177095, 14989547 }, + { -24496721, -11716016, 16959896, 2278463, 12066309, 10137771, 13515641, 2581286, -28487508, 9930240 }, + }, + { + { -17751622, -2097826, 16544300, -13009300, -15914807, -14949081, 18345767, -13403753, 16291481, -5314038 }, + { -33229194, 2553288, 32678213, 9875984, 8534129, 6889387, -9676774, 6957617, 4368891, 9788741 }, + { 16660756, 7281060, -10830758, 12911820, 20108584, -8101676, -21722536, -8613148, 16250552, -11111103 }, + }, + { + { -19765507, 2390526, -16551031, 14161980, 1905286, 6414907, 4689584, 10604807, -30190403, 4782747 }, + { -1354539, 14736941, -7367442, -13292886, 7710542, -14155590, -9981571, 4383045, 22546403, 437323 }, + { 31665577, -12180464, -16186830, 1491339, -18368625, 3294682, 27343084, 2786261, -30633590, -14097016 }, + }, + { + { -14467279, -683715, -33374107, 7448552, 19294360, 14334329, -19690631, 2355319, -19284671, -6114373 }, + { 15121312, -15796162, 6377020, -6031361, -10798111, -12957845, 18952177, 15496498, -29380133, 11754228 }, + { -2637277, -13483075, 8488727, -14303896, 12728761, -1622493, 7141596, 11724556, 22761615, -10134141 }, + }, + { + { 16918416, 11729663, -18083579, 3022987, -31015732, -13339659, -28741185, -12227393, 32851222, 11717399 }, + { 11166634, 7338049, -6722523, 4531520, -29468672, -7302055, 31474879, 3483633, -1193175, -4030831 }, + { -185635, 9921305, 31456609, -13536438, -12013818, 13348923, 33142652, 6546660, -19985279, -3948376 }, + }, + { + { -32460596, 11266712, -11197107, -7899103, 31703694, 3855903, -8537131, -12833048, -30772034, -15486313 }, + { -18006477, 12709068, 3991746, -6479188, -21491523, -10550425, -31135347, -16049879, 10928917, 3011958 }, + { -6957757, -15594337, 31696059, 334240, 29576716, 14796075, -30831056, -12805180, 18008031, 10258577 }, + }, + { + { -22448644, 15655569, 7018479, -4410003, -30314266, -1201591, -1853465, 1367120, 25127874, 6671743 }, + { 29701166, -14373934, -10878120, 9279288, -17568, 13127210, 21382910, 11042292, 25838796, 4642684 }, + { -20430234, 14955537, -24126347, 8124619, -5369288, -5990470, 30468147, -13900640, 18423289, 4177476 }, + }, + }, }; diff --git a/src/ed25519/sc.c b/src/ed25519/sc.c index 3364de4..ee54d99 100644 --- a/src/ed25519/sc.c +++ b/src/ed25519/sc.c @@ -2,24 +2,24 @@ #include "sc.h" static uint64_t load_3(const unsigned char *in) { - uint64_t result; + uint64_t result; - result = in[0]; - result |= shlu64(in[1], 8); - result |= shlu64(in[2], 16); + result = in[0]; + result |= shlu64(in[1], 8); + result |= shlu64(in[2], 16); - return result; + return result; } static uint64_t load_4(const unsigned char *in) { - uint64_t result; + uint64_t result; - result = in[0]; - result |= shlu64(in[1], 8); - result |= shlu64(in[2], 16); - result |= shlu64(in[3], 24); - - return result; + result = in[0]; + result |= shlu64(in[1], 8); + result |= shlu64(in[2], 16); + result |= shlu64(in[3], 24); + + return result; } /* @@ -33,305 +33,305 @@ Output: */ void sc_reduce(unsigned char *s) { - int64_t s0 = 2097151 & load_3(s); - int64_t s1 = 2097151 & (load_4(s + 2) >> 5); - int64_t s2 = 2097151 & (load_3(s + 5) >> 2); - int64_t s3 = 2097151 & (load_4(s + 7) >> 7); - int64_t s4 = 2097151 & (load_4(s + 10) >> 4); - int64_t s5 = 2097151 & (load_3(s + 13) >> 1); - int64_t s6 = 2097151 & (load_4(s + 15) >> 6); - int64_t s7 = 2097151 & (load_3(s + 18) >> 3); - int64_t s8 = 2097151 & load_3(s + 21); - int64_t s9 = 2097151 & (load_4(s + 23) >> 5); - int64_t s10 = 2097151 & (load_3(s + 26) >> 2); - int64_t s11 = 2097151 & (load_4(s + 28) >> 7); - int64_t s12 = 2097151 & (load_4(s + 31) >> 4); - int64_t s13 = 2097151 & (load_3(s + 34) >> 1); - int64_t s14 = 2097151 & (load_4(s + 36) >> 6); - int64_t s15 = 2097151 & (load_3(s + 39) >> 3); - int64_t s16 = 2097151 & load_3(s + 42); - int64_t s17 = 2097151 & (load_4(s + 44) >> 5); - int64_t s18 = 2097151 & (load_3(s + 47) >> 2); - int64_t s19 = 2097151 & (load_4(s + 49) >> 7); - int64_t s20 = 2097151 & (load_4(s + 52) >> 4); - int64_t s21 = 2097151 & (load_3(s + 55) >> 1); - int64_t s22 = 2097151 & (load_4(s + 57) >> 6); - int64_t s23 = (load_4(s + 60) >> 3); - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - int64_t carry10; - int64_t carry11; - int64_t carry12; - int64_t carry13; - int64_t carry14; - int64_t carry15; - int64_t carry16; + int64_t s0 = 2097151 & load_3(s); + int64_t s1 = 2097151 & (load_4(s + 2) >> 5); + int64_t s2 = 2097151 & (load_3(s + 5) >> 2); + int64_t s3 = 2097151 & (load_4(s + 7) >> 7); + int64_t s4 = 2097151 & (load_4(s + 10) >> 4); + int64_t s5 = 2097151 & (load_3(s + 13) >> 1); + int64_t s6 = 2097151 & (load_4(s + 15) >> 6); + int64_t s7 = 2097151 & (load_3(s + 18) >> 3); + int64_t s8 = 2097151 & load_3(s + 21); + int64_t s9 = 2097151 & (load_4(s + 23) >> 5); + int64_t s10 = 2097151 & (load_3(s + 26) >> 2); + int64_t s11 = 2097151 & (load_4(s + 28) >> 7); + int64_t s12 = 2097151 & (load_4(s + 31) >> 4); + int64_t s13 = 2097151 & (load_3(s + 34) >> 1); + int64_t s14 = 2097151 & (load_4(s + 36) >> 6); + int64_t s15 = 2097151 & (load_3(s + 39) >> 3); + int64_t s16 = 2097151 & load_3(s + 42); + int64_t s17 = 2097151 & (load_4(s + 44) >> 5); + int64_t s18 = 2097151 & (load_3(s + 47) >> 2); + int64_t s19 = 2097151 & (load_4(s + 49) >> 7); + int64_t s20 = 2097151 & (load_4(s + 52) >> 4); + int64_t s21 = 2097151 & (load_3(s + 55) >> 1); + int64_t s22 = 2097151 & (load_4(s + 57) >> 6); + int64_t s23 = (load_4(s + 60) >> 3); + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + int64_t carry10; + int64_t carry11; + int64_t carry12; + int64_t carry13; + int64_t carry14; + int64_t carry15; + int64_t carry16; - s11 += s23 * 666643; - s12 += s23 * 470296; - s13 += s23 * 654183; - s14 -= s23 * 997805; - s15 += s23 * 136657; - s16 -= s23 * 683901; - s10 += s22 * 666643; - s11 += s22 * 470296; - s12 += s22 * 654183; - s13 -= s22 * 997805; - s14 += s22 * 136657; - s15 -= s22 * 683901; - s9 += s21 * 666643; - s10 += s21 * 470296; - s11 += s21 * 654183; - s12 -= s21 * 997805; - s13 += s21 * 136657; - s14 -= s21 * 683901; - s8 += s20 * 666643; - s9 += s20 * 470296; - s10 += s20 * 654183; - s11 -= s20 * 997805; - s12 += s20 * 136657; - s13 -= s20 * 683901; - s7 += s19 * 666643; - s8 += s19 * 470296; - s9 += s19 * 654183; - s10 -= s19 * 997805; - s11 += s19 * 136657; - s12 -= s19 * 683901; - s6 += s18 * 666643; - s7 += s18 * 470296; - s8 += s18 * 654183; - s9 -= s18 * 997805; - s10 += s18 * 136657; - s11 -= s18 * 683901; - carry6 = (s6 + (1 << 20)) >> 21; - s7 += carry6; - s6 -= shl64(carry6, 21); - carry8 = (s8 + (1 << 20)) >> 21; - s9 += carry8; - s8 -= shl64(carry8, 21); - carry10 = (s10 + (1 << 20)) >> 21; - s11 += carry10; - s10 -= shl64(carry10, 21); - carry12 = (s12 + (1 << 20)) >> 21; - s13 += carry12; - s12 -= shl64(carry12, 21); - carry14 = (s14 + (1 << 20)) >> 21; - s15 += carry14; - s14 -= shl64(carry14, 21); - carry16 = (s16 + (1 << 20)) >> 21; - s17 += carry16; - s16 -= shl64(carry16, 21); - carry7 = (s7 + (1 << 20)) >> 21; - s8 += carry7; - s7 -= shl64(carry7, 21); - carry9 = (s9 + (1 << 20)) >> 21; - s10 += carry9; - s9 -= shl64(carry9, 21); - carry11 = (s11 + (1 << 20)) >> 21; - s12 += carry11; - s11 -= shl64(carry11, 21); - carry13 = (s13 + (1 << 20)) >> 21; - s14 += carry13; - s13 -= shl64(carry13, 21); - carry15 = (s15 + (1 << 20)) >> 21; - s16 += carry15; - s15 -= shl64(carry15, 21); - s5 += s17 * 666643; - s6 += s17 * 470296; - s7 += s17 * 654183; - s8 -= s17 * 997805; - s9 += s17 * 136657; - s10 -= s17 * 683901; - s4 += s16 * 666643; - s5 += s16 * 470296; - s6 += s16 * 654183; - s7 -= s16 * 997805; - s8 += s16 * 136657; - s9 -= s16 * 683901; - s3 += s15 * 666643; - s4 += s15 * 470296; - s5 += s15 * 654183; - s6 -= s15 * 997805; - s7 += s15 * 136657; - s8 -= s15 * 683901; - s2 += s14 * 666643; - s3 += s14 * 470296; - s4 += s14 * 654183; - s5 -= s14 * 997805; - s6 += s14 * 136657; - s7 -= s14 * 683901; - s1 += s13 * 666643; - s2 += s13 * 470296; - s3 += s13 * 654183; - s4 -= s13 * 997805; - s5 += s13 * 136657; - s6 -= s13 * 683901; - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - s12 = 0; - carry0 = (s0 + (1 << 20)) >> 21; - s1 += carry0; - s0 -= shl64(carry0, 21); - carry2 = (s2 + (1 << 20)) >> 21; - s3 += carry2; - s2 -= shl64(carry2, 21); - carry4 = (s4 + (1 << 20)) >> 21; - s5 += carry4; - s4 -= shl64(carry4, 21); - carry6 = (s6 + (1 << 20)) >> 21; - s7 += carry6; - s6 -= shl64(carry6, 21); - carry8 = (s8 + (1 << 20)) >> 21; - s9 += carry8; - s8 -= shl64(carry8, 21); - carry10 = (s10 + (1 << 20)) >> 21; - s11 += carry10; - s10 -= shl64(carry10, 21); - carry1 = (s1 + (1 << 20)) >> 21; - s2 += carry1; - s1 -= shl64(carry1, 21); - carry3 = (s3 + (1 << 20)) >> 21; - s4 += carry3; - s3 -= shl64(carry3, 21); - carry5 = (s5 + (1 << 20)) >> 21; - s6 += carry5; - s5 -= shl64(carry5, 21); - carry7 = (s7 + (1 << 20)) >> 21; - s8 += carry7; - s7 -= shl64(carry7, 21); - carry9 = (s9 + (1 << 20)) >> 21; - s10 += carry9; - s9 -= shl64(carry9, 21); - carry11 = (s11 + (1 << 20)) >> 21; - s12 += carry11; - s11 -= shl64(carry11, 21); - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - s12 = 0; - carry0 = s0 >> 21; - s1 += carry0; - s0 -= shl64(carry0, 21); - carry1 = s1 >> 21; - s2 += carry1; - s1 -= shl64(carry1, 21); - carry2 = s2 >> 21; - s3 += carry2; - s2 -= shl64(carry2, 21); - carry3 = s3 >> 21; - s4 += carry3; - s3 -= shl64(carry3, 21); - carry4 = s4 >> 21; - s5 += carry4; - s4 -= shl64(carry4, 21); - carry5 = s5 >> 21; - s6 += carry5; - s5 -= shl64(carry5, 21); - carry6 = s6 >> 21; - s7 += carry6; - s6 -= shl64(carry6, 21); - carry7 = s7 >> 21; - s8 += carry7; - s7 -= shl64(carry7, 21); - carry8 = s8 >> 21; - s9 += carry8; - s8 -= shl64(carry8, 21); - carry9 = s9 >> 21; - s10 += carry9; - s9 -= shl64(carry9, 21); - carry10 = s10 >> 21; - s11 += carry10; - s10 -= shl64(carry10, 21); - carry11 = s11 >> 21; - s12 += carry11; - s11 -= shl64(carry11, 21); - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - carry0 = s0 >> 21; - s1 += carry0; - s0 -= shl64(carry0, 21); - carry1 = s1 >> 21; - s2 += carry1; - s1 -= shl64(carry1, 21); - carry2 = s2 >> 21; - s3 += carry2; - s2 -= shl64(carry2, 21); - carry3 = s3 >> 21; - s4 += carry3; - s3 -= shl64(carry3, 21); - carry4 = s4 >> 21; - s5 += carry4; - s4 -= shl64(carry4, 21); - carry5 = s5 >> 21; - s6 += carry5; - s5 -= shl64(carry5, 21); - carry6 = s6 >> 21; - s7 += carry6; - s6 -= shl64(carry6, 21); - carry7 = s7 >> 21; - s8 += carry7; - s7 -= shl64(carry7, 21); - carry8 = s8 >> 21; - s9 += carry8; - s8 -= shl64(carry8, 21); - carry9 = s9 >> 21; - s10 += carry9; - s9 -= shl64(carry9, 21); - carry10 = s10 >> 21; - s11 += carry10; - s10 -= shl64(carry10, 21); + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= shl64(carry6, 21); + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= shl64(carry8, 21); + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= shl64(carry10, 21); + carry12 = (s12 + (1 << 20)) >> 21; + s13 += carry12; + s12 -= shl64(carry12, 21); + carry14 = (s14 + (1 << 20)) >> 21; + s15 += carry14; + s14 -= shl64(carry14, 21); + carry16 = (s16 + (1 << 20)) >> 21; + s17 += carry16; + s16 -= shl64(carry16, 21); + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= shl64(carry7, 21); + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= shl64(carry9, 21); + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= shl64(carry11, 21); + carry13 = (s13 + (1 << 20)) >> 21; + s14 += carry13; + s13 -= shl64(carry13, 21); + carry15 = (s15 + (1 << 20)) >> 21; + s16 += carry15; + s15 -= shl64(carry15, 21); + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + carry0 = (s0 + (1 << 20)) >> 21; + s1 += carry0; + s0 -= shl64(carry0, 21); + carry2 = (s2 + (1 << 20)) >> 21; + s3 += carry2; + s2 -= shl64(carry2, 21); + carry4 = (s4 + (1 << 20)) >> 21; + s5 += carry4; + s4 -= shl64(carry4, 21); + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= shl64(carry6, 21); + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= shl64(carry8, 21); + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= shl64(carry10, 21); + carry1 = (s1 + (1 << 20)) >> 21; + s2 += carry1; + s1 -= shl64(carry1, 21); + carry3 = (s3 + (1 << 20)) >> 21; + s4 += carry3; + s3 -= shl64(carry3, 21); + carry5 = (s5 + (1 << 20)) >> 21; + s6 += carry5; + s5 -= shl64(carry5, 21); + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= shl64(carry7, 21); + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= shl64(carry9, 21); + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= shl64(carry11, 21); + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + carry0 = s0 >> 21; + s1 += carry0; + s0 -= shl64(carry0, 21); + carry1 = s1 >> 21; + s2 += carry1; + s1 -= shl64(carry1, 21); + carry2 = s2 >> 21; + s3 += carry2; + s2 -= shl64(carry2, 21); + carry3 = s3 >> 21; + s4 += carry3; + s3 -= shl64(carry3, 21); + carry4 = s4 >> 21; + s5 += carry4; + s4 -= shl64(carry4, 21); + carry5 = s5 >> 21; + s6 += carry5; + s5 -= shl64(carry5, 21); + carry6 = s6 >> 21; + s7 += carry6; + s6 -= shl64(carry6, 21); + carry7 = s7 >> 21; + s8 += carry7; + s7 -= shl64(carry7, 21); + carry8 = s8 >> 21; + s9 += carry8; + s8 -= shl64(carry8, 21); + carry9 = s9 >> 21; + s10 += carry9; + s9 -= shl64(carry9, 21); + carry10 = s10 >> 21; + s11 += carry10; + s10 -= shl64(carry10, 21); + carry11 = s11 >> 21; + s12 += carry11; + s11 -= shl64(carry11, 21); + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + carry0 = s0 >> 21; + s1 += carry0; + s0 -= shl64(carry0, 21); + carry1 = s1 >> 21; + s2 += carry1; + s1 -= shl64(carry1, 21); + carry2 = s2 >> 21; + s3 += carry2; + s2 -= shl64(carry2, 21); + carry3 = s3 >> 21; + s4 += carry3; + s3 -= shl64(carry3, 21); + carry4 = s4 >> 21; + s5 += carry4; + s4 -= shl64(carry4, 21); + carry5 = s5 >> 21; + s6 += carry5; + s5 -= shl64(carry5, 21); + carry6 = s6 >> 21; + s7 += carry6; + s6 -= shl64(carry6, 21); + carry7 = s7 >> 21; + s8 += carry7; + s7 -= shl64(carry7, 21); + carry8 = s8 >> 21; + s9 += carry8; + s8 -= shl64(carry8, 21); + carry9 = s9 >> 21; + s10 += carry9; + s9 -= shl64(carry9, 21); + carry10 = s10 >> 21; + s11 += carry10; + s10 -= shl64(carry10, 21); - s[0] = (unsigned char) (s0 >> 0); - s[1] = (unsigned char) (s0 >> 8); - s[2] = (unsigned char) ((s0 >> 16) | shl64(s1, 5)); - s[3] = (unsigned char) (s1 >> 3); - s[4] = (unsigned char) (s1 >> 11); - s[5] = (unsigned char) ((s1 >> 19) | shl64(s2, 2)); - s[6] = (unsigned char) (s2 >> 6); - s[7] = (unsigned char) ((s2 >> 14) | shl64(s3, 7)); - s[8] = (unsigned char) (s3 >> 1); - s[9] = (unsigned char) (s3 >> 9); - s[10] = (unsigned char) ((s3 >> 17) | shl64(s4, 4)); - s[11] = (unsigned char) (s4 >> 4); - s[12] = (unsigned char) (s4 >> 12); - s[13] = (unsigned char) ((s4 >> 20) | shl64(s5, 1)); - s[14] = (unsigned char) (s5 >> 7); - s[15] = (unsigned char) ((s5 >> 15) | shl64(s6, 6)); - s[16] = (unsigned char) (s6 >> 2); - s[17] = (unsigned char) (s6 >> 10); - s[18] = (unsigned char) ((s6 >> 18) | shl64(s7, 3)); - s[19] = (unsigned char) (s7 >> 5); - s[20] = (unsigned char) (s7 >> 13); - s[21] = (unsigned char) (s8 >> 0); - s[22] = (unsigned char) (s8 >> 8); - s[23] = (unsigned char) ((s8 >> 16) | shl64(s9, 5)); - s[24] = (unsigned char) (s9 >> 3); - s[25] = (unsigned char) (s9 >> 11); - s[26] = (unsigned char) ((s9 >> 19) | shl64(s10, 2)); - s[27] = (unsigned char) (s10 >> 6); - s[28] = (unsigned char) ((s10 >> 14) | shl64(s11, 7)); - s[29] = (unsigned char) (s11 >> 1); - s[30] = (unsigned char) (s11 >> 9); - s[31] = (unsigned char) (s11 >> 17); + s[0] = (unsigned char)(s0 >> 0); + s[1] = (unsigned char)(s0 >> 8); + s[2] = (unsigned char)((s0 >> 16) | shl64(s1, 5)); + s[3] = (unsigned char)(s1 >> 3); + s[4] = (unsigned char)(s1 >> 11); + s[5] = (unsigned char)((s1 >> 19) | shl64(s2, 2)); + s[6] = (unsigned char)(s2 >> 6); + s[7] = (unsigned char)((s2 >> 14) | shl64(s3, 7)); + s[8] = (unsigned char)(s3 >> 1); + s[9] = (unsigned char)(s3 >> 9); + s[10] = (unsigned char)((s3 >> 17) | shl64(s4, 4)); + s[11] = (unsigned char)(s4 >> 4); + s[12] = (unsigned char)(s4 >> 12); + s[13] = (unsigned char)((s4 >> 20) | shl64(s5, 1)); + s[14] = (unsigned char)(s5 >> 7); + s[15] = (unsigned char)((s5 >> 15) | shl64(s6, 6)); + s[16] = (unsigned char)(s6 >> 2); + s[17] = (unsigned char)(s6 >> 10); + s[18] = (unsigned char)((s6 >> 18) | shl64(s7, 3)); + s[19] = (unsigned char)(s7 >> 5); + s[20] = (unsigned char)(s7 >> 13); + s[21] = (unsigned char)(s8 >> 0); + s[22] = (unsigned char)(s8 >> 8); + s[23] = (unsigned char)((s8 >> 16) | shl64(s9, 5)); + s[24] = (unsigned char)(s9 >> 3); + s[25] = (unsigned char)(s9 >> 11); + s[26] = (unsigned char)((s9 >> 19) | shl64(s10, 2)); + s[27] = (unsigned char)(s10 >> 6); + s[28] = (unsigned char)((s10 >> 14) | shl64(s11, 7)); + s[29] = (unsigned char)(s11 >> 1); + s[30] = (unsigned char)(s11 >> 9); + s[31] = (unsigned char)(s11 >> 17); } @@ -348,438 +348,438 @@ Output: */ void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, const unsigned char *c) { - int64_t a0 = 2097151 & load_3(a); - int64_t a1 = 2097151 & (load_4(a + 2) >> 5); - int64_t a2 = 2097151 & (load_3(a + 5) >> 2); - int64_t a3 = 2097151 & (load_4(a + 7) >> 7); - int64_t a4 = 2097151 & (load_4(a + 10) >> 4); - int64_t a5 = 2097151 & (load_3(a + 13) >> 1); - int64_t a6 = 2097151 & (load_4(a + 15) >> 6); - int64_t a7 = 2097151 & (load_3(a + 18) >> 3); - int64_t a8 = 2097151 & load_3(a + 21); - int64_t a9 = 2097151 & (load_4(a + 23) >> 5); - int64_t a10 = 2097151 & (load_3(a + 26) >> 2); - int64_t a11 = (load_4(a + 28) >> 7); - int64_t b0 = 2097151 & load_3(b); - int64_t b1 = 2097151 & (load_4(b + 2) >> 5); - int64_t b2 = 2097151 & (load_3(b + 5) >> 2); - int64_t b3 = 2097151 & (load_4(b + 7) >> 7); - int64_t b4 = 2097151 & (load_4(b + 10) >> 4); - int64_t b5 = 2097151 & (load_3(b + 13) >> 1); - int64_t b6 = 2097151 & (load_4(b + 15) >> 6); - int64_t b7 = 2097151 & (load_3(b + 18) >> 3); - int64_t b8 = 2097151 & load_3(b + 21); - int64_t b9 = 2097151 & (load_4(b + 23) >> 5); - int64_t b10 = 2097151 & (load_3(b + 26) >> 2); - int64_t b11 = (load_4(b + 28) >> 7); - int64_t c0 = 2097151 & load_3(c); - int64_t c1 = 2097151 & (load_4(c + 2) >> 5); - int64_t c2 = 2097151 & (load_3(c + 5) >> 2); - int64_t c3 = 2097151 & (load_4(c + 7) >> 7); - int64_t c4 = 2097151 & (load_4(c + 10) >> 4); - int64_t c5 = 2097151 & (load_3(c + 13) >> 1); - int64_t c6 = 2097151 & (load_4(c + 15) >> 6); - int64_t c7 = 2097151 & (load_3(c + 18) >> 3); - int64_t c8 = 2097151 & load_3(c + 21); - int64_t c9 = 2097151 & (load_4(c + 23) >> 5); - int64_t c10 = 2097151 & (load_3(c + 26) >> 2); - int64_t c11 = (load_4(c + 28) >> 7); - int64_t s0; - int64_t s1; - int64_t s2; - int64_t s3; - int64_t s4; - int64_t s5; - int64_t s6; - int64_t s7; - int64_t s8; - int64_t s9; - int64_t s10; - int64_t s11; - int64_t s12; - int64_t s13; - int64_t s14; - int64_t s15; - int64_t s16; - int64_t s17; - int64_t s18; - int64_t s19; - int64_t s20; - int64_t s21; - int64_t s22; - int64_t s23; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - int64_t carry10; - int64_t carry11; - int64_t carry12; - int64_t carry13; - int64_t carry14; - int64_t carry15; - int64_t carry16; - int64_t carry17; - int64_t carry18; - int64_t carry19; - int64_t carry20; - int64_t carry21; - int64_t carry22; + int64_t a0 = 2097151 & load_3(a); + int64_t a1 = 2097151 & (load_4(a + 2) >> 5); + int64_t a2 = 2097151 & (load_3(a + 5) >> 2); + int64_t a3 = 2097151 & (load_4(a + 7) >> 7); + int64_t a4 = 2097151 & (load_4(a + 10) >> 4); + int64_t a5 = 2097151 & (load_3(a + 13) >> 1); + int64_t a6 = 2097151 & (load_4(a + 15) >> 6); + int64_t a7 = 2097151 & (load_3(a + 18) >> 3); + int64_t a8 = 2097151 & load_3(a + 21); + int64_t a9 = 2097151 & (load_4(a + 23) >> 5); + int64_t a10 = 2097151 & (load_3(a + 26) >> 2); + int64_t a11 = (load_4(a + 28) >> 7); + int64_t b0 = 2097151 & load_3(b); + int64_t b1 = 2097151 & (load_4(b + 2) >> 5); + int64_t b2 = 2097151 & (load_3(b + 5) >> 2); + int64_t b3 = 2097151 & (load_4(b + 7) >> 7); + int64_t b4 = 2097151 & (load_4(b + 10) >> 4); + int64_t b5 = 2097151 & (load_3(b + 13) >> 1); + int64_t b6 = 2097151 & (load_4(b + 15) >> 6); + int64_t b7 = 2097151 & (load_3(b + 18) >> 3); + int64_t b8 = 2097151 & load_3(b + 21); + int64_t b9 = 2097151 & (load_4(b + 23) >> 5); + int64_t b10 = 2097151 & (load_3(b + 26) >> 2); + int64_t b11 = (load_4(b + 28) >> 7); + int64_t c0 = 2097151 & load_3(c); + int64_t c1 = 2097151 & (load_4(c + 2) >> 5); + int64_t c2 = 2097151 & (load_3(c + 5) >> 2); + int64_t c3 = 2097151 & (load_4(c + 7) >> 7); + int64_t c4 = 2097151 & (load_4(c + 10) >> 4); + int64_t c5 = 2097151 & (load_3(c + 13) >> 1); + int64_t c6 = 2097151 & (load_4(c + 15) >> 6); + int64_t c7 = 2097151 & (load_3(c + 18) >> 3); + int64_t c8 = 2097151 & load_3(c + 21); + int64_t c9 = 2097151 & (load_4(c + 23) >> 5); + int64_t c10 = 2097151 & (load_3(c + 26) >> 2); + int64_t c11 = (load_4(c + 28) >> 7); + int64_t s0; + int64_t s1; + int64_t s2; + int64_t s3; + int64_t s4; + int64_t s5; + int64_t s6; + int64_t s7; + int64_t s8; + int64_t s9; + int64_t s10; + int64_t s11; + int64_t s12; + int64_t s13; + int64_t s14; + int64_t s15; + int64_t s16; + int64_t s17; + int64_t s18; + int64_t s19; + int64_t s20; + int64_t s21; + int64_t s22; + int64_t s23; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + int64_t carry10; + int64_t carry11; + int64_t carry12; + int64_t carry13; + int64_t carry14; + int64_t carry15; + int64_t carry16; + int64_t carry17; + int64_t carry18; + int64_t carry19; + int64_t carry20; + int64_t carry21; + int64_t carry22; + + s0 = c0 + a0 * b0; + s1 = c1 + a0 * b1 + a1 * b0; + s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0; + s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0; + s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0; + s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0; + s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0; + s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + a6 * b1 + a7 * b0; + s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + a6 * b2 + a7 * b1 + a8 * b0; + s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0; + s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0; + s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0; + s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 + a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1; + s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 + a9 * b4 + a10 * b3 + a11 * b2; + s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 + a10 * b4 + a11 * b3; + s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 + a11 * b4; + s16 = a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5; + s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6; + s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7; + s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8; + s20 = a9 * b11 + a10 * b10 + a11 * b9; + s21 = a10 * b11 + a11 * b10; + s22 = a11 * b11; + s23 = 0; + carry0 = (s0 + (1 << 20)) >> 21; + s1 += carry0; + s0 -= shl64(carry0, 21); + carry2 = (s2 + (1 << 20)) >> 21; + s3 += carry2; + s2 -= shl64(carry2, 21); + carry4 = (s4 + (1 << 20)) >> 21; + s5 += carry4; + s4 -= shl64(carry4, 21); + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= shl64(carry6, 21); + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= shl64(carry8, 21); + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= shl64(carry10, 21); + carry12 = (s12 + (1 << 20)) >> 21; + s13 += carry12; + s12 -= shl64(carry12, 21); + carry14 = (s14 + (1 << 20)) >> 21; + s15 += carry14; + s14 -= shl64(carry14, 21); + carry16 = (s16 + (1 << 20)) >> 21; + s17 += carry16; + s16 -= shl64(carry16, 21); + carry18 = (s18 + (1 << 20)) >> 21; + s19 += carry18; + s18 -= shl64(carry18, 21); + carry20 = (s20 + (1 << 20)) >> 21; + s21 += carry20; + s20 -= shl64(carry20, 21); + carry22 = (s22 + (1 << 20)) >> 21; + s23 += carry22; + s22 -= shl64(carry22, 21); + carry1 = (s1 + (1 << 20)) >> 21; + s2 += carry1; + s1 -= shl64(carry1, 21); + carry3 = (s3 + (1 << 20)) >> 21; + s4 += carry3; + s3 -= shl64(carry3, 21); + carry5 = (s5 + (1 << 20)) >> 21; + s6 += carry5; + s5 -= shl64(carry5, 21); + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= shl64(carry7, 21); + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= shl64(carry9, 21); + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= shl64(carry11, 21); + carry13 = (s13 + (1 << 20)) >> 21; + s14 += carry13; + s13 -= shl64(carry13, 21); + carry15 = (s15 + (1 << 20)) >> 21; + s16 += carry15; + s15 -= shl64(carry15, 21); + carry17 = (s17 + (1 << 20)) >> 21; + s18 += carry17; + s17 -= shl64(carry17, 21); + carry19 = (s19 + (1 << 20)) >> 21; + s20 += carry19; + s19 -= shl64(carry19, 21); + carry21 = (s21 + (1 << 20)) >> 21; + s22 += carry21; + s21 -= shl64(carry21, 21); + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= shl64(carry6, 21); + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= shl64(carry8, 21); + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= shl64(carry10, 21); + carry12 = (s12 + (1 << 20)) >> 21; + s13 += carry12; + s12 -= shl64(carry12, 21); + carry14 = (s14 + (1 << 20)) >> 21; + s15 += carry14; + s14 -= shl64(carry14, 21); + carry16 = (s16 + (1 << 20)) >> 21; + s17 += carry16; + s16 -= shl64(carry16, 21); + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= shl64(carry7, 21); + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= shl64(carry9, 21); + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= shl64(carry11, 21); + carry13 = (s13 + (1 << 20)) >> 21; + s14 += carry13; + s13 -= shl64(carry13, 21); + carry15 = (s15 + (1 << 20)) >> 21; + s16 += carry15; + s15 -= shl64(carry15, 21); + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + carry0 = (s0 + (1 << 20)) >> 21; + s1 += carry0; + s0 -= shl64(carry0, 21); + carry2 = (s2 + (1 << 20)) >> 21; + s3 += carry2; + s2 -= shl64(carry2, 21); + carry4 = (s4 + (1 << 20)) >> 21; + s5 += carry4; + s4 -= shl64(carry4, 21); + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= shl64(carry6, 21); + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= shl64(carry8, 21); + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= shl64(carry10, 21); + carry1 = (s1 + (1 << 20)) >> 21; + s2 += carry1; + s1 -= shl64(carry1, 21); + carry3 = (s3 + (1 << 20)) >> 21; + s4 += carry3; + s3 -= shl64(carry3, 21); + carry5 = (s5 + (1 << 20)) >> 21; + s6 += carry5; + s5 -= shl64(carry5, 21); + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= shl64(carry7, 21); + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= shl64(carry9, 21); + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= shl64(carry11, 21); + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + carry0 = s0 >> 21; + s1 += carry0; + s0 -= shl64(carry0, 21); + carry1 = s1 >> 21; + s2 += carry1; + s1 -= shl64(carry1, 21); + carry2 = s2 >> 21; + s3 += carry2; + s2 -= shl64(carry2, 21); + carry3 = s3 >> 21; + s4 += carry3; + s3 -= shl64(carry3, 21); + carry4 = s4 >> 21; + s5 += carry4; + s4 -= shl64(carry4, 21); + carry5 = s5 >> 21; + s6 += carry5; + s5 -= shl64(carry5, 21); + carry6 = s6 >> 21; + s7 += carry6; + s6 -= shl64(carry6, 21); + carry7 = s7 >> 21; + s8 += carry7; + s7 -= shl64(carry7, 21); + carry8 = s8 >> 21; + s9 += carry8; + s8 -= shl64(carry8, 21); + carry9 = s9 >> 21; + s10 += carry9; + s9 -= shl64(carry9, 21); + carry10 = s10 >> 21; + s11 += carry10; + s10 -= shl64(carry10, 21); + carry11 = s11 >> 21; + s12 += carry11; + s11 -= shl64(carry11, 21); + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + carry0 = s0 >> 21; + s1 += carry0; + s0 -= shl64(carry0, 21); + carry1 = s1 >> 21; + s2 += carry1; + s1 -= shl64(carry1, 21); + carry2 = s2 >> 21; + s3 += carry2; + s2 -= shl64(carry2, 21); + carry3 = s3 >> 21; + s4 += carry3; + s3 -= shl64(carry3, 21); + carry4 = s4 >> 21; + s5 += carry4; + s4 -= shl64(carry4, 21); + carry5 = s5 >> 21; + s6 += carry5; + s5 -= shl64(carry5, 21); + carry6 = s6 >> 21; + s7 += carry6; + s6 -= shl64(carry6, 21); + carry7 = s7 >> 21; + s8 += carry7; + s7 -= shl64(carry7, 21); + carry8 = s8 >> 21; + s9 += carry8; + s8 -= shl64(carry8, 21); + carry9 = s9 >> 21; + s10 += carry9; + s9 -= shl64(carry9, 21); + carry10 = s10 >> 21; + s11 += carry10; + s10 -= shl64(carry10, 21); - s0 = c0 + a0 * b0; - s1 = c1 + a0 * b1 + a1 * b0; - s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0; - s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0; - s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0; - s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0; - s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0; - s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + a6 * b1 + a7 * b0; - s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + a6 * b2 + a7 * b1 + a8 * b0; - s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0; - s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0; - s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0; - s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 + a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1; - s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 + a9 * b4 + a10 * b3 + a11 * b2; - s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 + a10 * b4 + a11 * b3; - s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 + a11 * b4; - s16 = a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5; - s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6; - s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7; - s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8; - s20 = a9 * b11 + a10 * b10 + a11 * b9; - s21 = a10 * b11 + a11 * b10; - s22 = a11 * b11; - s23 = 0; - carry0 = (s0 + (1 << 20)) >> 21; - s1 += carry0; - s0 -= shl64(carry0, 21); - carry2 = (s2 + (1 << 20)) >> 21; - s3 += carry2; - s2 -= shl64(carry2, 21); - carry4 = (s4 + (1 << 20)) >> 21; - s5 += carry4; - s4 -= shl64(carry4, 21); - carry6 = (s6 + (1 << 20)) >> 21; - s7 += carry6; - s6 -= shl64(carry6, 21); - carry8 = (s8 + (1 << 20)) >> 21; - s9 += carry8; - s8 -= shl64(carry8, 21); - carry10 = (s10 + (1 << 20)) >> 21; - s11 += carry10; - s10 -= shl64(carry10, 21); - carry12 = (s12 + (1 << 20)) >> 21; - s13 += carry12; - s12 -= shl64(carry12, 21); - carry14 = (s14 + (1 << 20)) >> 21; - s15 += carry14; - s14 -= shl64(carry14, 21); - carry16 = (s16 + (1 << 20)) >> 21; - s17 += carry16; - s16 -= shl64(carry16, 21); - carry18 = (s18 + (1 << 20)) >> 21; - s19 += carry18; - s18 -= shl64(carry18, 21); - carry20 = (s20 + (1 << 20)) >> 21; - s21 += carry20; - s20 -= shl64(carry20, 21); - carry22 = (s22 + (1 << 20)) >> 21; - s23 += carry22; - s22 -= shl64(carry22, 21); - carry1 = (s1 + (1 << 20)) >> 21; - s2 += carry1; - s1 -= shl64(carry1, 21); - carry3 = (s3 + (1 << 20)) >> 21; - s4 += carry3; - s3 -= shl64(carry3, 21); - carry5 = (s5 + (1 << 20)) >> 21; - s6 += carry5; - s5 -= shl64(carry5, 21); - carry7 = (s7 + (1 << 20)) >> 21; - s8 += carry7; - s7 -= shl64(carry7, 21); - carry9 = (s9 + (1 << 20)) >> 21; - s10 += carry9; - s9 -= shl64(carry9, 21); - carry11 = (s11 + (1 << 20)) >> 21; - s12 += carry11; - s11 -= shl64(carry11, 21); - carry13 = (s13 + (1 << 20)) >> 21; - s14 += carry13; - s13 -= shl64(carry13, 21); - carry15 = (s15 + (1 << 20)) >> 21; - s16 += carry15; - s15 -= shl64(carry15, 21); - carry17 = (s17 + (1 << 20)) >> 21; - s18 += carry17; - s17 -= shl64(carry17, 21); - carry19 = (s19 + (1 << 20)) >> 21; - s20 += carry19; - s19 -= shl64(carry19, 21); - carry21 = (s21 + (1 << 20)) >> 21; - s22 += carry21; - s21 -= shl64(carry21, 21); - s11 += s23 * 666643; - s12 += s23 * 470296; - s13 += s23 * 654183; - s14 -= s23 * 997805; - s15 += s23 * 136657; - s16 -= s23 * 683901; - s10 += s22 * 666643; - s11 += s22 * 470296; - s12 += s22 * 654183; - s13 -= s22 * 997805; - s14 += s22 * 136657; - s15 -= s22 * 683901; - s9 += s21 * 666643; - s10 += s21 * 470296; - s11 += s21 * 654183; - s12 -= s21 * 997805; - s13 += s21 * 136657; - s14 -= s21 * 683901; - s8 += s20 * 666643; - s9 += s20 * 470296; - s10 += s20 * 654183; - s11 -= s20 * 997805; - s12 += s20 * 136657; - s13 -= s20 * 683901; - s7 += s19 * 666643; - s8 += s19 * 470296; - s9 += s19 * 654183; - s10 -= s19 * 997805; - s11 += s19 * 136657; - s12 -= s19 * 683901; - s6 += s18 * 666643; - s7 += s18 * 470296; - s8 += s18 * 654183; - s9 -= s18 * 997805; - s10 += s18 * 136657; - s11 -= s18 * 683901; - carry6 = (s6 + (1 << 20)) >> 21; - s7 += carry6; - s6 -= shl64(carry6, 21); - carry8 = (s8 + (1 << 20)) >> 21; - s9 += carry8; - s8 -= shl64(carry8, 21); - carry10 = (s10 + (1 << 20)) >> 21; - s11 += carry10; - s10 -= shl64(carry10, 21); - carry12 = (s12 + (1 << 20)) >> 21; - s13 += carry12; - s12 -= shl64(carry12, 21); - carry14 = (s14 + (1 << 20)) >> 21; - s15 += carry14; - s14 -= shl64(carry14, 21); - carry16 = (s16 + (1 << 20)) >> 21; - s17 += carry16; - s16 -= shl64(carry16, 21); - carry7 = (s7 + (1 << 20)) >> 21; - s8 += carry7; - s7 -= shl64(carry7, 21); - carry9 = (s9 + (1 << 20)) >> 21; - s10 += carry9; - s9 -= shl64(carry9, 21); - carry11 = (s11 + (1 << 20)) >> 21; - s12 += carry11; - s11 -= shl64(carry11, 21); - carry13 = (s13 + (1 << 20)) >> 21; - s14 += carry13; - s13 -= shl64(carry13, 21); - carry15 = (s15 + (1 << 20)) >> 21; - s16 += carry15; - s15 -= shl64(carry15, 21); - s5 += s17 * 666643; - s6 += s17 * 470296; - s7 += s17 * 654183; - s8 -= s17 * 997805; - s9 += s17 * 136657; - s10 -= s17 * 683901; - s4 += s16 * 666643; - s5 += s16 * 470296; - s6 += s16 * 654183; - s7 -= s16 * 997805; - s8 += s16 * 136657; - s9 -= s16 * 683901; - s3 += s15 * 666643; - s4 += s15 * 470296; - s5 += s15 * 654183; - s6 -= s15 * 997805; - s7 += s15 * 136657; - s8 -= s15 * 683901; - s2 += s14 * 666643; - s3 += s14 * 470296; - s4 += s14 * 654183; - s5 -= s14 * 997805; - s6 += s14 * 136657; - s7 -= s14 * 683901; - s1 += s13 * 666643; - s2 += s13 * 470296; - s3 += s13 * 654183; - s4 -= s13 * 997805; - s5 += s13 * 136657; - s6 -= s13 * 683901; - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - s12 = 0; - carry0 = (s0 + (1 << 20)) >> 21; - s1 += carry0; - s0 -= shl64(carry0, 21); - carry2 = (s2 + (1 << 20)) >> 21; - s3 += carry2; - s2 -= shl64(carry2, 21); - carry4 = (s4 + (1 << 20)) >> 21; - s5 += carry4; - s4 -= shl64(carry4, 21); - carry6 = (s6 + (1 << 20)) >> 21; - s7 += carry6; - s6 -= shl64(carry6, 21); - carry8 = (s8 + (1 << 20)) >> 21; - s9 += carry8; - s8 -= shl64(carry8, 21); - carry10 = (s10 + (1 << 20)) >> 21; - s11 += carry10; - s10 -= shl64(carry10, 21); - carry1 = (s1 + (1 << 20)) >> 21; - s2 += carry1; - s1 -= shl64(carry1, 21); - carry3 = (s3 + (1 << 20)) >> 21; - s4 += carry3; - s3 -= shl64(carry3, 21); - carry5 = (s5 + (1 << 20)) >> 21; - s6 += carry5; - s5 -= shl64(carry5, 21); - carry7 = (s7 + (1 << 20)) >> 21; - s8 += carry7; - s7 -= shl64(carry7, 21); - carry9 = (s9 + (1 << 20)) >> 21; - s10 += carry9; - s9 -= shl64(carry9, 21); - carry11 = (s11 + (1 << 20)) >> 21; - s12 += carry11; - s11 -= shl64(carry11, 21); - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - s12 = 0; - carry0 = s0 >> 21; - s1 += carry0; - s0 -= shl64(carry0, 21); - carry1 = s1 >> 21; - s2 += carry1; - s1 -= shl64(carry1, 21); - carry2 = s2 >> 21; - s3 += carry2; - s2 -= shl64(carry2, 21); - carry3 = s3 >> 21; - s4 += carry3; - s3 -= shl64(carry3, 21); - carry4 = s4 >> 21; - s5 += carry4; - s4 -= shl64(carry4, 21); - carry5 = s5 >> 21; - s6 += carry5; - s5 -= shl64(carry5, 21); - carry6 = s6 >> 21; - s7 += carry6; - s6 -= shl64(carry6, 21); - carry7 = s7 >> 21; - s8 += carry7; - s7 -= shl64(carry7, 21); - carry8 = s8 >> 21; - s9 += carry8; - s8 -= shl64(carry8, 21); - carry9 = s9 >> 21; - s10 += carry9; - s9 -= shl64(carry9, 21); - carry10 = s10 >> 21; - s11 += carry10; - s10 -= shl64(carry10, 21); - carry11 = s11 >> 21; - s12 += carry11; - s11 -= shl64(carry11, 21); - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - carry0 = s0 >> 21; - s1 += carry0; - s0 -= shl64(carry0, 21); - carry1 = s1 >> 21; - s2 += carry1; - s1 -= shl64(carry1, 21); - carry2 = s2 >> 21; - s3 += carry2; - s2 -= shl64(carry2, 21); - carry3 = s3 >> 21; - s4 += carry3; - s3 -= shl64(carry3, 21); - carry4 = s4 >> 21; - s5 += carry4; - s4 -= shl64(carry4, 21); - carry5 = s5 >> 21; - s6 += carry5; - s5 -= shl64(carry5, 21); - carry6 = s6 >> 21; - s7 += carry6; - s6 -= shl64(carry6, 21); - carry7 = s7 >> 21; - s8 += carry7; - s7 -= shl64(carry7, 21); - carry8 = s8 >> 21; - s9 += carry8; - s8 -= shl64(carry8, 21); - carry9 = s9 >> 21; - s10 += carry9; - s9 -= shl64(carry9, 21); - carry10 = s10 >> 21; - s11 += carry10; - s10 -= shl64(carry10, 21); - - s[0] = (unsigned char) (s0 >> 0); - s[1] = (unsigned char) (s0 >> 8); - s[2] = (unsigned char) ((s0 >> 16) | shl64(s1, 5)); - s[3] = (unsigned char) (s1 >> 3); - s[4] = (unsigned char) (s1 >> 11); - s[5] = (unsigned char) ((s1 >> 19) | shl64(s2, 2)); - s[6] = (unsigned char) (s2 >> 6); - s[7] = (unsigned char) ((s2 >> 14) | shl64(s3, 7)); - s[8] = (unsigned char) (s3 >> 1); - s[9] = (unsigned char) (s3 >> 9); - s[10] = (unsigned char) ((s3 >> 17) | shl64(s4, 4)); - s[11] = (unsigned char) (s4 >> 4); - s[12] = (unsigned char) (s4 >> 12); - s[13] = (unsigned char) ((s4 >> 20) | shl64(s5, 1)); - s[14] = (unsigned char) (s5 >> 7); - s[15] = (unsigned char) ((s5 >> 15) | shl64(s6, 6)); - s[16] = (unsigned char) (s6 >> 2); - s[17] = (unsigned char) (s6 >> 10); - s[18] = (unsigned char) ((s6 >> 18) | shl64(s7, 3)); - s[19] = (unsigned char) (s7 >> 5); - s[20] = (unsigned char) (s7 >> 13); - s[21] = (unsigned char) (s8 >> 0); - s[22] = (unsigned char) (s8 >> 8); - s[23] = (unsigned char) ((s8 >> 16) | shl64(s9, 5)); - s[24] = (unsigned char) (s9 >> 3); - s[25] = (unsigned char) (s9 >> 11); - s[26] = (unsigned char) ((s9 >> 19) | shl64(s10, 2)); - s[27] = (unsigned char) (s10 >> 6); - s[28] = (unsigned char) ((s10 >> 14) | shl64(s11, 7)); - s[29] = (unsigned char) (s11 >> 1); - s[30] = (unsigned char) (s11 >> 9); - s[31] = (unsigned char) (s11 >> 17); + s[0] = (unsigned char)(s0 >> 0); + s[1] = (unsigned char)(s0 >> 8); + s[2] = (unsigned char)((s0 >> 16) | shl64(s1, 5)); + s[3] = (unsigned char)(s1 >> 3); + s[4] = (unsigned char)(s1 >> 11); + s[5] = (unsigned char)((s1 >> 19) | shl64(s2, 2)); + s[6] = (unsigned char)(s2 >> 6); + s[7] = (unsigned char)((s2 >> 14) | shl64(s3, 7)); + s[8] = (unsigned char)(s3 >> 1); + s[9] = (unsigned char)(s3 >> 9); + s[10] = (unsigned char)((s3 >> 17) | shl64(s4, 4)); + s[11] = (unsigned char)(s4 >> 4); + s[12] = (unsigned char)(s4 >> 12); + s[13] = (unsigned char)((s4 >> 20) | shl64(s5, 1)); + s[14] = (unsigned char)(s5 >> 7); + s[15] = (unsigned char)((s5 >> 15) | shl64(s6, 6)); + s[16] = (unsigned char)(s6 >> 2); + s[17] = (unsigned char)(s6 >> 10); + s[18] = (unsigned char)((s6 >> 18) | shl64(s7, 3)); + s[19] = (unsigned char)(s7 >> 5); + s[20] = (unsigned char)(s7 >> 13); + s[21] = (unsigned char)(s8 >> 0); + s[22] = (unsigned char)(s8 >> 8); + s[23] = (unsigned char)((s8 >> 16) | shl64(s9, 5)); + s[24] = (unsigned char)(s9 >> 3); + s[25] = (unsigned char)(s9 >> 11); + s[26] = (unsigned char)((s9 >> 19) | shl64(s10, 2)); + s[27] = (unsigned char)(s10 >> 6); + s[28] = (unsigned char)((s10 >> 14) | shl64(s11, 7)); + s[29] = (unsigned char)(s11 >> 1); + s[30] = (unsigned char)(s11 >> 9); + s[31] = (unsigned char)(s11 >> 17); } diff --git a/src/ed25519/sha512.c b/src/ed25519/sha512.c index e1db1e5..13dc843 100644 --- a/src/ed25519/sha512.c +++ b/src/ed25519/sha512.c @@ -14,65 +14,65 @@ /* the K array */ static const uint64_t K[80] = { - UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd), - UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc), - UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019), - UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118), - UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe), - UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2), - UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1), - UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694), - UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3), - UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65), - UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483), - UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5), - UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210), - UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4), - UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725), - UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70), - UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926), - UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df), - UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8), - UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b), - UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001), - UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30), - UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910), - UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8), - UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53), - UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8), - UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb), - UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3), - UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60), - UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec), - UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9), - UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b), - UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207), - UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178), - UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6), - UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b), - UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493), - UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c), - UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a), - UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817) + UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd), + UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc), + UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019), + UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118), + UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe), + UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2), + UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1), + UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694), + UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3), + UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65), + UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483), + UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5), + UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210), + UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4), + UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725), + UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70), + UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926), + UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df), + UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8), + UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b), + UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001), + UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30), + UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910), + UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8), + UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53), + UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8), + UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb), + UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3), + UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60), + UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec), + UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9), + UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b), + UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207), + UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178), + UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6), + UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b), + UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493), + UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c), + UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a), + UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817) }; /* Various logical functions */ #define ROR64c(x, y) \ - ( ((((x)&UINT64_C(0xFFFFFFFFFFFFFFFF))>>((uint64_t)(y)&UINT64_C(63))) | \ - ((x)<<((uint64_t)(64-((y)&UINT64_C(63)))))) & UINT64_C(0xFFFFFFFFFFFFFFFF)) + ( ((((x)&UINT64_C(0xFFFFFFFFFFFFFFFF))>>((uint64_t)(y)&UINT64_C(63))) | \ + ((x)<<((uint64_t)(64-((y)&UINT64_C(63)))))) & UINT64_C(0xFFFFFFFFFFFFFFFF)) #define STORE64H(x, y) \ - { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ - (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ - (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ - (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } + { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } #define LOAD64H(x, y) \ - { x = (((uint64_t)((y)[0] & 255))<<56)|(((uint64_t)((y)[1] & 255))<<48) | \ - (((uint64_t)((y)[2] & 255))<<40)|(((uint64_t)((y)[3] & 255))<<32) | \ - (((uint64_t)((y)[4] & 255))<<24)|(((uint64_t)((y)[5] & 255))<<16) | \ - (((uint64_t)((y)[6] & 255))<<8)|(((uint64_t)((y)[7] & 255))); } + { x = (((uint64_t)((y)[0] & 255))<<56)|(((uint64_t)((y)[1] & 255))<<48) | \ + (((uint64_t)((y)[2] & 255))<<40)|(((uint64_t)((y)[3] & 255))<<32) | \ + (((uint64_t)((y)[4] & 255))<<24)|(((uint64_t)((y)[5] & 255))<<16) | \ + (((uint64_t)((y)[6] & 255))<<8)|(((uint64_t)((y)[7] & 255))); } #define Ch(x,y,z) (z ^ (x & (y ^ z))) @@ -84,58 +84,57 @@ static const uint64_t K[80] = { #define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7)) #define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6)) #ifndef MIN - #define MIN(x, y) ( ((x)<(y))?(x):(y) ) +#define MIN(x, y) ( ((x)<(y))?(x):(y) ) #endif /* compress 1024-bits */ -static int sha512_compress(sha512_context *md, const unsigned char *buf) -{ - uint64_t S[8], W[80], t0, t1; - int i; - - /* copy state into S */ - for (i = 0; i < 8; i++) { - S[i] = md->state[i]; - } - - /* copy the state into 1024-bits into W[0..15] */ - for (i = 0; i < 16; i++) { - LOAD64H(W[i], buf + (8*i)); - } - - /* fill W[16..79] */ - for (i = 16; i < 80; i++) { - W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; - } - -/* Compress */ - #define RND(a,b,c,d,e,f,g,h,i) \ - t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ - t1 = Sigma0(a) + Maj(a, b, c);\ - d += t0; \ - h = t0 + t1; - - for (i = 0; i < 80; i += 8) { - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7); - } - - #undef RND - - - - /* feedback */ - for (i = 0; i < 8; i++) { - md->state[i] = md->state[i] + S[i]; - } - - return 0; +static int sha512_compress(sha512_context *md, const unsigned char *buf) { + uint64_t S[8], W[80], t0, t1; + int i; + + /* copy state into S */ + for(i = 0; i < 8; i++) { + S[i] = md->state[i]; + } + + /* copy the state into 1024-bits into W[0..15] */ + for(i = 0; i < 16; i++) { + LOAD64H(W[i], buf + (8 * i)); + } + + /* fill W[16..79] */ + for(i = 16; i < 80; i++) { + W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; + } + + /* Compress */ +#define RND(a,b,c,d,e,f,g,h,i) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c);\ + d += t0; \ + h = t0 + t1; + + for(i = 0; i < 80; i += 8) { + RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i + 0); + RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], i + 1); + RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], i + 2); + RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], i + 3); + RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], i + 4); + RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], i + 5); + RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], i + 6); + RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], i + 7); + } + +#undef RND + + + + /* feedback */ + for(i = 0; i < 8; i++) { + md->state[i] = md->state[i] + S[i]; + } + + return 0; } @@ -144,21 +143,23 @@ static int sha512_compress(sha512_context *md, const unsigned char *buf) @param md The hash state you wish to initialize @return 0 if successful */ -int sha512_init(sha512_context * md) { - if (md == NULL) return 1; - - md->curlen = 0; - md->length = 0; - md->state[0] = UINT64_C(0x6a09e667f3bcc908); - md->state[1] = UINT64_C(0xbb67ae8584caa73b); - md->state[2] = UINT64_C(0x3c6ef372fe94f82b); - md->state[3] = UINT64_C(0xa54ff53a5f1d36f1); - md->state[4] = UINT64_C(0x510e527fade682d1); - md->state[5] = UINT64_C(0x9b05688c2b3e6c1f); - md->state[6] = UINT64_C(0x1f83d9abfb41bd6b); - md->state[7] = UINT64_C(0x5be0cd19137e2179); - - return 0; +int sha512_init(sha512_context *md) { + if(md == NULL) { + return 1; + } + + md->curlen = 0; + md->length = 0; + md->state[0] = UINT64_C(0x6a09e667f3bcc908); + md->state[1] = UINT64_C(0xbb67ae8584caa73b); + md->state[2] = UINT64_C(0x3c6ef372fe94f82b); + md->state[3] = UINT64_C(0xa54ff53a5f1d36f1); + md->state[4] = UINT64_C(0x510e527fade682d1); + md->state[5] = UINT64_C(0x9b05688c2b3e6c1f); + md->state[6] = UINT64_C(0x1f83d9abfb41bd6b); + md->state[7] = UINT64_C(0x5be0cd19137e2179); + + return 0; } /** @@ -168,46 +169,57 @@ int sha512_init(sha512_context * md) { @param inlen The length of the data (octets) @return 0 if successful */ -int sha512_update(sha512_context *md, const void *vin, size_t inlen) -{ - const unsigned char *in = vin; - size_t n; - size_t i; - int err; - if (md == NULL) return 1; - if (in == NULL) return 1; - if (md->curlen > sizeof(md->buf)) { - return 1; - } - while (inlen > 0) { - if (md->curlen == 0 && inlen >= 128) { - if ((err = sha512_compress (md, in)) != 0) { - return err; - } - md->length += 128 * 8; - in += 128; - inlen -= 128; - } else { - n = MIN(inlen, (128 - md->curlen)); - - for (i = 0; i < n; i++) { - md->buf[i + md->curlen] = in[i]; - } - - - md->curlen += n; - in += n; - inlen -= n; - if (md->curlen == 128) { - if ((err = sha512_compress (md, md->buf)) != 0) { - return err; - } - md->length += 8*128; - md->curlen = 0; - } - } - } - return 0; +int sha512_update(sha512_context *md, const void *vin, size_t inlen) { + const unsigned char *in = vin; + size_t n; + size_t i; + int err; + + if(md == NULL) { + return 1; + } + + if(in == NULL) { + return 1; + } + + if(md->curlen > sizeof(md->buf)) { + return 1; + } + + while(inlen > 0) { + if(md->curlen == 0 && inlen >= 128) { + if((err = sha512_compress(md, in)) != 0) { + return err; + } + + md->length += 128 * 8; + in += 128; + inlen -= 128; + } else { + n = MIN(inlen, (128 - md->curlen)); + + for(i = 0; i < n; i++) { + md->buf[i + md->curlen] = in[i]; + } + + + md->curlen += n; + in += n; + inlen -= n; + + if(md->curlen == 128) { + if((err = sha512_compress(md, md->buf)) != 0) { + return err; + } + + md->length += 8 * 128; + md->curlen = 0; + } + } + } + + return 0; } /** @@ -216,62 +228,76 @@ int sha512_update(sha512_context *md, const void *vin, size_t inlen) @param out [out] The destination of the hash (64 bytes) @return 0 if successful */ -int sha512_final(sha512_context * md, void *vout) -{ - int i; - unsigned char *out = vout; - - if (md == NULL) return 1; - if (out == NULL) return 1; - - if (md->curlen >= sizeof(md->buf)) { - return 1; - } - - /* increase the length of the message */ - md->length += md->curlen * UINT64_C(8); - - /* append the '1' bit */ - md->buf[md->curlen++] = (unsigned char)0x80; - - /* if the length is currently above 112 bytes we append zeros - * then compress. Then we can fall back to padding zeros and length - * encoding like normal. - */ - if (md->curlen > 112) { - while (md->curlen < 128) { - md->buf[md->curlen++] = (unsigned char)0; - } - sha512_compress(md, md->buf); - md->curlen = 0; - } - - /* pad upto 120 bytes of zeroes - * note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash - * > 2^64 bits of data... :-) - */ - while (md->curlen < 120) { - md->buf[md->curlen++] = (unsigned char)0; - } - - /* store length */ - STORE64H(md->length, md->buf+120); - sha512_compress(md, md->buf); - - /* copy output */ - for (i = 0; i < 8; i++) { - STORE64H(md->state[i], out+(8*i)); - } - - return 0; +int sha512_final(sha512_context *md, void *vout) { + int i; + unsigned char *out = vout; + + if(md == NULL) { + return 1; + } + + if(out == NULL) { + return 1; + } + + if(md->curlen >= sizeof(md->buf)) { + return 1; + } + + /* increase the length of the message */ + md->length += md->curlen * UINT64_C(8); + + /* append the '1' bit */ + md->buf[md->curlen++] = (unsigned char)0x80; + + /* if the length is currently above 112 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if(md->curlen > 112) { + while(md->curlen < 128) { + md->buf[md->curlen++] = (unsigned char)0; + } + + sha512_compress(md, md->buf); + md->curlen = 0; + } + + /* pad upto 120 bytes of zeroes + * note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash + * > 2^64 bits of data... :-) + */ + while(md->curlen < 120) { + md->buf[md->curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64H(md->length, md->buf + 120); + sha512_compress(md, md->buf); + + /* copy output */ + for(i = 0; i < 8; i++) { + STORE64H(md->state[i], out + (8 * i)); + } + + return 0; } -int sha512(const void *message, size_t message_len, void *out) -{ - sha512_context ctx; - int ret; - if ((ret = sha512_init(&ctx))) return ret; - if ((ret = sha512_update(&ctx, message, message_len))) return ret; - if ((ret = sha512_final(&ctx, out))) return ret; - return 0; +int sha512(const void *message, size_t message_len, void *out) { + sha512_context ctx; + int ret; + + if((ret = sha512_init(&ctx))) { + return ret; + } + + if((ret = sha512_update(&ctx, message, message_len))) { + return ret; + } + + if((ret = sha512_final(&ctx, out))) { + return ret; + } + + return 0; } diff --git a/src/ed25519/sha512.h b/src/ed25519/sha512.h index e23f8db..95461ce 100644 --- a/src/ed25519/sha512.h +++ b/src/ed25519/sha512.h @@ -7,15 +7,15 @@ /* state */ typedef struct sha512_context_ { - uint64_t length, state[8]; - size_t curlen; - unsigned char buf[128]; + uint64_t length, state[8]; + size_t curlen; + unsigned char buf[128]; } sha512_context; -int sha512_init(sha512_context * md); -int sha512_final(sha512_context * md, void *out); -int sha512_update(sha512_context * md, const void *in, size_t inlen); +int sha512_init(sha512_context *md); +int sha512_final(sha512_context *md, void *out); +int sha512_update(sha512_context *md, const void *in, size_t inlen); int sha512(const void *message, size_t message_len, void *out); #endif diff --git a/src/ed25519/sign.c b/src/ed25519/sign.c index 199a839..0c4eea9 100644 --- a/src/ed25519/sign.c +++ b/src/ed25519/sign.c @@ -5,27 +5,27 @@ void ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key, const unsigned char *private_key) { - sha512_context hash; - unsigned char hram[64]; - unsigned char r[64]; - ge_p3 R; + sha512_context hash; + unsigned char hram[64]; + unsigned char r[64]; + ge_p3 R; - sha512_init(&hash); - sha512_update(&hash, private_key + 32, 32); - sha512_update(&hash, message, message_len); - sha512_final(&hash, r); + sha512_init(&hash); + sha512_update(&hash, private_key + 32, 32); + sha512_update(&hash, message, message_len); + sha512_final(&hash, r); - sc_reduce(r); - ge_scalarmult_base(&R, r); - ge_p3_tobytes(signature, &R); + sc_reduce(r); + ge_scalarmult_base(&R, r); + ge_p3_tobytes(signature, &R); - sha512_init(&hash); - sha512_update(&hash, signature, 32); - sha512_update(&hash, public_key, 32); - sha512_update(&hash, message, message_len); - sha512_final(&hash, hram); + sha512_init(&hash); + sha512_update(&hash, signature, 32); + sha512_update(&hash, public_key, 32); + sha512_update(&hash, message, message_len); + sha512_final(&hash, hram); - sc_reduce(hram); - sc_muladd(signature + 32, hram, private_key, r); + sc_reduce(hram); + sc_muladd(signature + 32, hram, private_key, r); } diff --git a/src/ed25519/verify.c b/src/ed25519/verify.c index 32f988e..415e94f 100644 --- a/src/ed25519/verify.c +++ b/src/ed25519/verify.c @@ -4,74 +4,74 @@ #include "sc.h" static int consttime_equal(const unsigned char *x, const unsigned char *y) { - unsigned char r = 0; + unsigned char r = 0; - r = x[0] ^ y[0]; - #define F(i) r |= x[i] ^ y[i] - F(1); - F(2); - F(3); - F(4); - F(5); - F(6); - F(7); - F(8); - F(9); - F(10); - F(11); - F(12); - F(13); - F(14); - F(15); - F(16); - F(17); - F(18); - F(19); - F(20); - F(21); - F(22); - F(23); - F(24); - F(25); - F(26); - F(27); - F(28); - F(29); - F(30); - F(31); - #undef F + r = x[0] ^ y[0]; +#define F(i) r |= x[i] ^ y[i] + F(1); + F(2); + F(3); + F(4); + F(5); + F(6); + F(7); + F(8); + F(9); + F(10); + F(11); + F(12); + F(13); + F(14); + F(15); + F(16); + F(17); + F(18); + F(19); + F(20); + F(21); + F(22); + F(23); + F(24); + F(25); + F(26); + F(27); + F(28); + F(29); + F(30); + F(31); +#undef F - return !r; + return !r; } int ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key) { - unsigned char h[64]; - unsigned char checker[32]; - sha512_context hash; - ge_p3 A; - ge_p2 R; + unsigned char h[64]; + unsigned char checker[32]; + sha512_context hash; + ge_p3 A; + ge_p2 R; - if (signature[63] & 224) { - return 0; - } + if(signature[63] & 224) { + return 0; + } - if (ge_frombytes_negate_vartime(&A, public_key) != 0) { - return 0; - } + if(ge_frombytes_negate_vartime(&A, public_key) != 0) { + return 0; + } - sha512_init(&hash); - sha512_update(&hash, signature, 32); - sha512_update(&hash, public_key, 32); - sha512_update(&hash, message, message_len); - sha512_final(&hash, h); - - sc_reduce(h); - ge_double_scalarmult_vartime(&R, h, &A, signature + 32); - ge_tobytes(checker, &R); + sha512_init(&hash); + sha512_update(&hash, signature, 32); + sha512_update(&hash, public_key, 32); + sha512_update(&hash, message, message_len); + sha512_final(&hash, h); - if (!consttime_equal(checker, signature)) { - return 0; - } + sc_reduce(h); + ge_double_scalarmult_vartime(&R, h, &A, signature + 32); + ge_tobytes(checker, &R); - return 1; + if(!consttime_equal(checker, signature)) { + return 0; + } + + return 1; } diff --git a/src/edge.c b/src/edge.c index 0e35cd1..5491d8a 100644 --- a/src/edge.c +++ b/src/edge.c @@ -40,13 +40,15 @@ static int edge_weight_compare(const edge_t *a, const edge_t *b) { result = a->weight - b->weight; - if(result) + if(result) { return result; + } result = strcmp(a->from->name, b->from->name); - if(result) + if(result) { return result; + } return strcmp(a->to->name, b->to->name); } @@ -86,13 +88,15 @@ void edge_add(edge_t *e) { e->reverse = lookup_edge(e->to, e->from); - if(e->reverse) + if(e->reverse) { e->reverse->reverse = e; + } } void edge_del(edge_t *e) { - if(e->reverse) + if(e->reverse) { e->reverse->reverse = NULL; + } splay_delete(edge_weight_tree, e); splay_delete(e->from->edge_tree, e); @@ -111,11 +115,11 @@ bool dump_edges(connection_t *c) { for splay_each(node_t, n, node_tree) { for splay_each(edge_t, e, n->edge_tree) { char *address = sockaddr2hostname(&e->address); - char* local_address = sockaddr2hostname(&e->local_address); + char *local_address = sockaddr2hostname(&e->local_address); send_request(c, "%d %d %s %s %s %s %x %d", - CONTROL, REQ_DUMP_EDGES, - e->from->name, e->to->name, address, - local_address, e->options, e->weight); + CONTROL, REQ_DUMP_EDGES, + e->from->name, e->to->name, address, + local_address, e->options, e->weight); free(address); free(local_address); } diff --git a/src/edge.h b/src/edge.h index 274e5d9..687c8ec 100644 --- a/src/edge.h +++ b/src/edge.h @@ -43,9 +43,9 @@ extern splay_tree_t *edge_weight_tree; /* Tree with all known edges sor extern void init_edges(void); extern void exit_edges(void); -extern edge_t *new_edge(void) __attribute__ ((__malloc__)); +extern edge_t *new_edge(void) __attribute__((__malloc__)); extern void free_edge(edge_t *); -extern splay_tree_t *new_edge_tree(void) __attribute__ ((__malloc__)); +extern splay_tree_t *new_edge_tree(void) __attribute__((__malloc__)); extern void free_edge_tree(splay_tree_t *); extern void edge_add(edge_t *); extern void edge_del(edge_t *); diff --git a/src/ethernet.h b/src/ethernet.h index 6ee2d38..8bfbd71 100644 --- a/src/ethernet.h +++ b/src/ethernet.h @@ -63,7 +63,7 @@ struct ether_header { uint8_t ether_dhost[ETH_ALEN]; uint8_t ether_shost[ETH_ALEN]; uint16_t ether_type; -} __attribute__ ((__gcc_struct__, __packed__)); +} __attribute__((__gcc_struct__, __packed__)); #endif #ifndef HAVE_STRUCT_ARPHDR @@ -73,7 +73,7 @@ struct arphdr { uint8_t ar_hln; uint8_t ar_pln; uint16_t ar_op; -} __attribute__ ((__gcc_struct__, __packed__)); +} __attribute__((__gcc_struct__, __packed__)); #define ARPOP_REQUEST 1 #define ARPOP_REPLY 2 @@ -91,7 +91,7 @@ struct ether_arp { uint8_t arp_spa[4]; uint8_t arp_tha[ETH_ALEN]; uint8_t arp_tpa[4]; -} __attribute__ ((__gcc_struct__, __packed__)); +} __attribute__((__gcc_struct__, __packed__)); #define arp_hrd ea_hdr.ar_hrd #define arp_pro ea_hdr.ar_pro #define arp_hln ea_hdr.ar_hln diff --git a/src/event.c b/src/event.c index d981f75..5edd3a6 100644 --- a/src/event.c +++ b/src/event.c @@ -48,18 +48,31 @@ static int io_compare(const io_t *a, const io_t *b) { static int timeout_compare(const timeout_t *a, const timeout_t *b) { struct timeval diff; timersub(&a->tv, &b->tv, &diff); - if(diff.tv_sec < 0) + + if(diff.tv_sec < 0) { return -1; - if(diff.tv_sec > 0) + } + + if(diff.tv_sec > 0) { return 1; - if(diff.tv_usec < 0) + } + + if(diff.tv_usec < 0) { return -1; - if(diff.tv_usec > 0) + } + + if(diff.tv_usec > 0) { return 1; - if(a < b) + } + + if(a < b) { return -1; - if(a > b) + } + + if(a > b) { return 1; + } + return 0; } @@ -67,16 +80,21 @@ static splay_tree_t io_tree = {.compare = (splay_compare_t)io_compare}; static splay_tree_t timeout_tree = {.compare = (splay_compare_t)timeout_compare}; void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags) { - if(io->cb) + if(io->cb) { return; + } io->fd = fd; #ifdef HAVE_MINGW - if (io->fd != -1) { + + if(io->fd != -1) { io->event = WSACreateEvent(); - if (io->event == WSA_INVALID_EVENT) + + if(io->event == WSA_INVALID_EVENT) { abort(); + } } + event_count++; #endif io->cb = cb; @@ -85,8 +103,9 @@ void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags) { io_set(io, flags); - if(!splay_insert_node(&io_tree, &io->node)) + if(!splay_insert_node(&io_tree, &io->node)) { abort(); + } } #ifdef HAVE_MINGW @@ -97,41 +116,60 @@ void io_add_event(io_t *io, io_cb_t cb, void *data, WSAEVENT event) { #endif void io_set(io_t *io, int flags) { - if (flags == io->flags) + if(flags == io->flags) { return; + } + io->flags = flags; - if (io->fd == -1) + + if(io->fd == -1) { return; + } #ifndef HAVE_MINGW - if(flags & IO_READ) + + if(flags & IO_READ) { FD_SET(io->fd, &readfds); - else + } else { FD_CLR(io->fd, &readfds); + } - if(flags & IO_WRITE) + if(flags & IO_WRITE) { FD_SET(io->fd, &writefds); - else + } else { FD_CLR(io->fd, &writefds); + } + #else long events = 0; - if (flags & IO_WRITE) + + if(flags & IO_WRITE) { events |= WRITE_EVENTS; - if (flags & IO_READ) + } + + if(flags & IO_READ) { events |= READ_EVENTS; - if (WSAEventSelect(io->fd, io->event, events) != 0) + } + + if(WSAEventSelect(io->fd, io->event, events) != 0) { abort(); + } + #endif } void io_del(io_t *io) { - if(!io->cb) + if(!io->cb) { return; + } io_set(io, 0); #ifdef HAVE_MINGW - if (io->fd != -1 && WSACloseEvent(io->event) == FALSE) + + if(io->fd != -1 && WSACloseEvent(io->event) == FALSE) { abort(); + } + event_count--; #endif @@ -148,25 +186,31 @@ void timeout_add(timeout_t *timeout, timeout_cb_t cb, void *data, struct timeval } void timeout_set(timeout_t *timeout, struct timeval *tv) { - if(timerisset(&timeout->tv)) + if(timerisset(&timeout->tv)) { splay_unlink_node(&timeout_tree, &timeout->node); + } - if(!now.tv_sec) + if(!now.tv_sec) { gettimeofday(&now, NULL); + } timeradd(&now, tv, &timeout->tv); - if(!splay_insert_node(&timeout_tree, &timeout->node)) + if(!splay_insert_node(&timeout_tree, &timeout->node)) { abort(); + } } void timeout_del(timeout_t *timeout) { - if(!timeout->cb) + if(!timeout->cb) { return; + } splay_unlink_node(&timeout_tree, &timeout->node); timeout->cb = 0; - timeout->tv = (struct timeval){0, 0}; + timeout->tv = (struct timeval) { + 0, 0 + }; } #ifndef HAVE_MINGW @@ -185,40 +229,51 @@ static void signal_handler(int signum) { static void signalio_handler(void *data, int flags) { unsigned char signum; - if(read(pipefd[0], &signum, 1) != 1) + + if(read(pipefd[0], &signum, 1) != 1) { return; + } - signal_t *sig = splay_search(&signal_tree, &((signal_t){.signum = signum})); - if(sig) + signal_t *sig = splay_search(&signal_tree, &((signal_t) { + .signum = signum + })); + + if(sig) { sig->cb(sig->data); + } } static void pipe_init(void) { - if(!pipe(pipefd)) + if(!pipe(pipefd)) { io_add(&signalio, signalio_handler, NULL, pipefd[0], IO_READ); + } } void signal_add(signal_t *sig, signal_cb_t cb, void *data, int signum) { - if(sig->cb) + if(sig->cb) { return; + } sig->cb = cb; sig->data = data; sig->signum = signum; sig->node.data = sig; - if(pipefd[0] == -1) + if(pipefd[0] == -1) { pipe_init(); + } signal(sig->signum, signal_handler); - if(!splay_insert_node(&signal_tree, &sig->node)) + if(!splay_insert_node(&signal_tree, &sig->node)) { abort(); + } } void signal_del(signal_t *sig) { - if(!sig->cb) + if(!sig->cb) { return; + } signal(sig->signum, SIG_DFL); @@ -227,7 +282,7 @@ void signal_del(signal_t *sig) { } #endif -static struct timeval * get_time_remaining(struct timeval *diff) { +static struct timeval *get_time_remaining(struct timeval *diff) { gettimeofday(&now, NULL); struct timeval *tv = NULL; @@ -237,8 +292,10 @@ static struct timeval * get_time_remaining(struct timeval *diff) { if(diff->tv_sec < 0) { timeout->cb(timeout->data); - if(timercmp(&timeout->tv, &now, <)) + + if(timercmp(&timeout->tv, &now, <)) { timeout_del(timeout); + } } else { tv = diff; break; @@ -271,22 +328,25 @@ bool event_loop(void) { int n = select(fds, &readable, &writable, NULL, tv); if(n < 0) { - if(sockwouldblock(sockerrno)) + if(sockwouldblock(sockerrno)) { continue; - else + } else { return false; + } } - if(!n) + if(!n) { continue; + } for splay_each(io_t, io, &io_tree) { - if(FD_ISSET(io->fd, &writable)) + if(FD_ISSET(io->fd, &writable)) { io->cb(io->data, IO_WRITE); - else if(FD_ISSET(io->fd, &readable)) + } else if(FD_ISSET(io->fd, &readable)) { io->cb(io->data, IO_READ); - else + } else { continue; + } /* There are scenarios in which the callback will remove another io_t from the tree @@ -297,13 +357,15 @@ bool event_loop(void) { break; } } + #else - while (running) { + + while(running) { struct timeval diff; struct timeval *tv = get_time_remaining(&diff); DWORD timeout_ms = tv ? (tv->tv_sec * 1000 + tv->tv_usec / 1000 + 1) : WSA_INFINITE; - if (!event_count) { + if(!event_count) { Sleep(timeout_ms); continue; } @@ -318,19 +380,22 @@ bool event_loop(void) { Note that technically FD_CLOSE has the same problem, but it's okay because user code does not rely on this event being fired again if ignored. */ - io_t* writeable_io = NULL; + io_t *writeable_io = NULL; + for splay_each(io_t, io, &io_tree) - if (io->flags & IO_WRITE && send(io->fd, NULL, 0, 0) == 0) { + if(io->flags & IO_WRITE && send(io->fd, NULL, 0, 0) == 0) { writeable_io = io; break; } - if (writeable_io) { + + if(writeable_io) { writeable_io->cb(writeable_io->data, IO_WRITE); continue; } - WSAEVENT* events = xmalloc(event_count * sizeof(*events)); + WSAEVENT *events = xmalloc(event_count * sizeof(*events)); DWORD event_index = 0; + for splay_each(io_t, io, &io_tree) { events[event_index] = io->event; event_index++; @@ -339,26 +404,42 @@ bool event_loop(void) { DWORD result = WSAWaitForMultipleEvents(event_count, events, FALSE, timeout_ms, FALSE); WSAEVENT event; - if (result >= WSA_WAIT_EVENT_0 && result < WSA_WAIT_EVENT_0 + event_count) + + if(result >= WSA_WAIT_EVENT_0 && result < WSA_WAIT_EVENT_0 + event_count) { event = events[result - WSA_WAIT_EVENT_0]; + } + free(events); - if (result == WSA_WAIT_TIMEOUT) + + if(result == WSA_WAIT_TIMEOUT) { continue; - if (result < WSA_WAIT_EVENT_0 || result >= WSA_WAIT_EVENT_0 + event_count) + } + + if(result < WSA_WAIT_EVENT_0 || result >= WSA_WAIT_EVENT_0 + event_count) { return false; + } + + io_t *io = splay_search(&io_tree, &((io_t) { + .event = event + })); - io_t *io = splay_search(&io_tree, &((io_t){.event = event})); - if (!io) + if(!io) { abort(); + } - if (io->fd == -1) { + if(io->fd == -1) { io->cb(io->data, 0); } else { WSANETWORKEVENTS network_events; - if (WSAEnumNetworkEvents(io->fd, io->event, &network_events) != 0) + + if(WSAEnumNetworkEvents(io->fd, io->event, &network_events) != 0) { return false; - if (network_events.lNetworkEvents & READ_EVENTS) + } + + if(network_events.lNetworkEvents & READ_EVENTS) { io->cb(io->data, IO_READ); + } + /* The fd might be available for write too. However, if we already fired the read callback, that callback might have deleted the io (e.g. through terminate_connection()), so we can't fire the @@ -366,6 +447,7 @@ bool event_loop(void) { */ } } + #endif return true; diff --git a/src/event.h b/src/event.h index e7def91..7adaf85 100644 --- a/src/event.h +++ b/src/event.h @@ -58,7 +58,7 @@ extern struct timeval now; extern void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags); #ifdef HAVE_MINGW -extern void io_add_event(io_t *io, io_cb_t cb, void* data, WSAEVENT event); +extern void io_add_event(io_t *io, io_cb_t cb, void *data, WSAEVENT event); #endif extern void io_del(io_t *io); extern void io_set(io_t *io, int flags); diff --git a/src/fd_device.c b/src/fd_device.c index 67e0cb7..afe59bc 100644 --- a/src/fd_device.c +++ b/src/fd_device.c @@ -64,7 +64,7 @@ static void close_device(void) { } static inline uint16_t get_ip_ethertype(vpn_packet_t *packet) { - switch (DATA(packet)[ETH_HLEN] >> 4) { + switch(DATA(packet)[ETH_HLEN] >> 4) { case 4: return ETH_P_IP; @@ -85,12 +85,14 @@ static inline void set_etherheader(vpn_packet_t *packet, uint16_t ethertype) { static bool read_packet(vpn_packet_t *packet) { int lenin = read(device_fd, DATA(packet) + ETH_HLEN, MTU - ETH_HLEN); + if(lenin <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from fd/%d: %s!", device_fd, strerror(errno)); return false; } uint16_t ethertype = get_ip_ethertype(packet); + if(ethertype == ETH_P_MAX) { logger(DEBUG_TRAFFIC, LOG_ERR, "Unknown IP version while reading packet from fd/%d!", device_fd); return false; diff --git a/src/fsck.c b/src/fsck.c index 42f40f4..e17b46c 100644 --- a/src/fsck.c +++ b/src/fsck.c @@ -32,31 +32,43 @@ #include "utils.h" static bool ask_fix(void) { - if(force) + if(force) { return true; - if(!tty) + } + + if(!tty) { return false; + } + again: fprintf(stderr, "Fix y/n? "); char buf[1024]; + if(!fgets(buf, sizeof(buf), stdin)) { tty = false; return false; } - if(buf[0] == 'y' || buf[0] == 'Y') + + if(buf[0] == 'y' || buf[0] == 'Y') { return true; - if(buf[0] == 'n' || buf[0] == 'N') + } + + if(buf[0] == 'n' || buf[0] == 'N') { return false; + } + goto again; } static void print_tinc_cmd(const char *argv0, const char *format, ...) { - if(confbasegiven) + if(confbasegiven) { fprintf(stderr, "%s -c %s ", argv0, confbase); - else if(netname) + } else if(netname) { fprintf(stderr, "%s -n %s ", argv0, netname); - else + } else { fprintf(stderr, "%s ", argv0); + } + va_list va; va_start(va, format); vfprintf(stderr, format, va); @@ -67,13 +79,17 @@ static void print_tinc_cmd(const char *argv0, const char *format, ...) { static int strtailcmp(const char *str, const char *tail) { size_t slen = strlen(str); size_t tlen = strlen(tail); - if(tlen > slen) + + if(tlen > slen) { return -1; + } + return memcmp(str + slen - tlen, tail, tlen); } static void check_conffile(const char *fname, bool server) { FILE *f = fopen(fname, "r"); + if(!f) { fprintf(stderr, "ERROR: cannot read %s: %s\n", fname, strerror(errno)); return; @@ -88,8 +104,10 @@ static void check_conffile(const char *fname, bool server) { while(fgets(line, sizeof(line), f)) { if(skip) { - if(!strncmp(line, "-----END", 8)) + if(!strncmp(line, "-----END", 8)) { skip = false; + } + continue; } else { if(!strncmp(line, "-----BEGIN", 10)) { @@ -105,26 +123,32 @@ static void check_conffile(const char *fname, bool server) { lineno++; eol = line + strlen(line); - while(strchr("\t \r\n", *--eol)) + + while(strchr("\t \r\n", *--eol)) { *eol = '\0'; + } - if(!line[0] || line[0] == '#') + if(!line[0] || line[0] == '#') { continue; + } len = strcspn(value, "\t ="); value += len; value += strspn(value, "\t "); + if(*value == '=') { value++; value += strspn(value, "\t "); } + variable[len] = '\0'; bool found = false; for(int i = 0; variables[i].name; i++) { - if(strcasecmp(variables[i].name, variable)) + if(strcasecmp(variables[i].name, variable)) { continue; + } found = true; @@ -132,24 +156,29 @@ static void check_conffile(const char *fname, bool server) { fprintf(stderr, "WARNING: obsolete variable %s in %s line %d\n", variable, fname, lineno); } - if(i < maxvariables) + if(i < maxvariables) { count[i]++; + } } - if(!found) + if(!found) { fprintf(stderr, "WARNING: unknown variable %s in %s line %d\n", variable, fname, lineno); + } - if(!*value) + if(!*value) { fprintf(stderr, "ERROR: no value for variable %s in %s line %d\n", variable, fname, lineno); + } } for(int i = 0; variables[i].name && i < maxvariables; i++) { - if(count[i] > 1 && !(variables[i].type & VAR_MULTIPLE)) + if(count[i] > 1 && !(variables[i].type & VAR_MULTIPLE)) { fprintf(stderr, "WARNING: multiple instances of variable %s in %s\n", variables[i].name, fname); + } } - if(ferror(f)) + if(ferror(f)) { fprintf(stderr, "ERROR: while reading %s: %s\n", fname, strerror(errno)); + } fclose(f); } @@ -165,19 +194,23 @@ int fsck(const char *argv0) { if(access(tinc_conf, R_OK)) { fprintf(stderr, "ERROR: cannot read %s: %s\n", tinc_conf, strerror(errno)); + if(errno == ENOENT) { fprintf(stderr, "No tinc configuration found. Create a new one with:\n\n"); print_tinc_cmd(argv0, "init"); } else if(errno == EACCES) { - if(uid != 0) + if(uid != 0) { fprintf(stderr, "You are currently not running tinc as root. Use sudo?\n"); - else + } else { fprintf(stderr, "Check the permissions of each component of the path %s.\n", tinc_conf); + } } + return 1; } char *name = get_my_name(true); + if(!name) { fprintf(stderr, "ERROR: tinc cannot run without a valid Name.\n"); return 1; @@ -203,12 +236,15 @@ int fsck(const char *argv0) { } } else { FILE *f = fopen(fname, "r"); + if(!f) { fprintf(stderr, "ERROR: could not open %s: %s\n", fname, strerror(errno)); return 1; } + rsa_priv = rsa_read_pem_private_key(f); fclose(f); + if(!rsa_priv) { fprintf(stderr, "ERROR: No key or unusable key found in %s.\n", fname); fprintf(stderr, "You can generate a new RSA key with:\n\n"); @@ -217,19 +253,24 @@ int fsck(const char *argv0) { } #if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN) + if(st.st_mode & 077) { fprintf(stderr, "WARNING: unsafe file permissions on %s.\n", fname); + if(st.st_uid != uid) { fprintf(stderr, "You are not running %s as the same uid as %s.\n", argv0, fname); } else if(ask_fix()) { - if(chmod(fname, st.st_mode & ~077)) + if(chmod(fname, st.st_mode & ~077)) { fprintf(stderr, "ERROR: could not change permissions of %s: %s\n", fname, strerror(errno)); - else + } else { fprintf(stderr, "Fixed permissions of %s.\n", fname); + } } } + #endif } + #endif ecdsa_t *ecdsa_priv = NULL; @@ -244,12 +285,15 @@ int fsck(const char *argv0) { } } else { FILE *f = fopen(fname, "r"); + if(!f) { fprintf(stderr, "ERROR: could not open %s: %s\n", fname, strerror(errno)); return 1; } + ecdsa_priv = ecdsa_read_pem_private_key(f); fclose(f); + if(!ecdsa_priv) { fprintf(stderr, "ERROR: No key or unusable key found in %s.\n", fname); fprintf(stderr, "You can generate a new Ed25519 key with:\n\n"); @@ -258,24 +302,30 @@ int fsck(const char *argv0) { } #if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN) + if(st.st_mode & 077) { fprintf(stderr, "WARNING: unsafe file permissions on %s.\n", fname); + if(st.st_uid != uid) { fprintf(stderr, "You are not running %s as the same uid as %s.\n", argv0, fname); } else if(ask_fix()) { - if(chmod(fname, st.st_mode & ~077)) + if(chmod(fname, st.st_mode & ~077)) { fprintf(stderr, "ERROR: could not change permissions of %s: %s\n", fname, strerror(errno)); - else + } else { fprintf(stderr, "Fixed permissions of %s.\n", fname); + } } } + #endif } #ifdef DISABLE_LEGACY + if(!ecdsa_priv) { fprintf(stderr, "ERROR: No Ed25519 private key found.\n"); #else + if(!rsa_priv && !ecdsa_priv) { fprintf(stderr, "ERROR: Neither RSA or Ed25519 private key found.\n"); #endif @@ -288,8 +338,10 @@ int fsck(const char *argv0) { // TODO: use RSAPublicKeyFile variable if present. snprintf(fname, sizeof(fname), "%s/hosts/%s", confbase, name); - if(access(fname, R_OK)) + + if(access(fname, R_OK)) { fprintf(stderr, "WARNING: cannot read %s\n", fname); + } FILE *f; @@ -297,6 +349,7 @@ int fsck(const char *argv0) { rsa_t *rsa_pub = NULL; f = fopen(fname, "r"); + if(f) { rsa_pub = rsa_read_pem_public_key(f); fclose(f); @@ -305,13 +358,17 @@ int fsck(const char *argv0) { if(rsa_priv) { if(!rsa_pub) { fprintf(stderr, "WARNING: No (usable) public RSA key found.\n"); + if(ask_fix()) { FILE *f = fopen(fname, "a"); + if(f) { - if(rsa_write_pem_public_key(rsa_priv, f)) + if(rsa_write_pem_public_key(rsa_priv, f)) { fprintf(stderr, "Wrote RSA public key to %s.\n", fname); - else + } else { fprintf(stderr, "ERROR: could not write RSA public key to %s.\n", fname); + } + fclose(f); } else { fprintf(stderr, "ERROR: could not append to %s: %s\n", fname, strerror(errno)); @@ -320,56 +377,70 @@ int fsck(const char *argv0) { } else { // TODO: suggest remedies size_t len = rsa_size(rsa_priv); + if(len != rsa_size(rsa_pub)) { fprintf(stderr, "ERROR: public and private RSA keys do not match.\n"); return 1; } + char buf1[len], buf2[len], buf3[len]; randomize(buf1, sizeof(buf1)); buf1[0] &= 0x7f; memset(buf2, 0, sizeof(buf2)); memset(buf3, 0, sizeof(buf2)); + if(!rsa_public_encrypt(rsa_pub, buf1, sizeof(buf1), buf2)) { fprintf(stderr, "ERROR: public RSA key does not work.\n"); return 1; } + if(!rsa_private_decrypt(rsa_priv, buf2, sizeof(buf2), buf3)) { fprintf(stderr, "ERROR: private RSA key does not work.\n"); return 1; } + if(memcmp(buf1, buf3, sizeof(buf1))) { fprintf(stderr, "ERROR: public and private RSA keys do not match.\n"); return 1; } } } else { - if(rsa_pub) + if(rsa_pub) { fprintf(stderr, "WARNING: A public RSA key was found but no private key is known.\n"); + } } + #endif ecdsa_t *ecdsa_pub = NULL; f = fopen(fname, "r"); + if(f) { ecdsa_pub = get_pubkey(f); + if(!ecdsa_pub) { rewind(f); ecdsa_pub = ecdsa_read_pem_public_key(f); } + fclose(f); } if(ecdsa_priv) { if(!ecdsa_pub) { fprintf(stderr, "WARNING: No (usable) public Ed25519 key found.\n"); + if(ask_fix()) { FILE *f = fopen(fname, "a"); + if(f) { - if(ecdsa_write_pem_public_key(ecdsa_priv, f)) + if(ecdsa_write_pem_public_key(ecdsa_priv, f)) { fprintf(stderr, "Wrote Ed25519 public key to %s.\n", fname); - else + } else { fprintf(stderr, "ERROR: could not write Ed25519 public key to %s.\n", fname); + } + fclose(f); } else { fprintf(stderr, "ERROR: could not append to %s: %s\n", fname, strerror(errno)); @@ -378,119 +449,150 @@ int fsck(const char *argv0) { } else { // TODO: suggest remedies char *key1 = ecdsa_get_base64_public_key(ecdsa_pub); + if(!key1) { fprintf(stderr, "ERROR: public Ed25519 key does not work.\n"); return 1; } + char *key2 = ecdsa_get_base64_public_key(ecdsa_priv); + if(!key2) { free(key1); fprintf(stderr, "ERROR: private Ed25519 key does not work.\n"); return 1; } + int result = strcmp(key1, key2); free(key1); free(key2); + if(result) { fprintf(stderr, "ERROR: public and private Ed25519 keys do not match.\n"); return 1; } } } else { - if(ecdsa_pub) + if(ecdsa_pub) { fprintf(stderr, "WARNING: A public Ed25519 key was found but no private key is known.\n"); + } } // Check whether scripts are executable struct dirent *ent; DIR *dir = opendir(confbase); + if(!dir) { fprintf(stderr, "ERROR: cannot read directory %s: %s\n", confbase, strerror(errno)); return 1; } while((ent = readdir(dir))) { - if(strtailcmp(ent->d_name, "-up") && strtailcmp(ent->d_name, "-down")) + if(strtailcmp(ent->d_name, "-up") && strtailcmp(ent->d_name, "-down")) { continue; + } strncpy(fname, ent->d_name, sizeof(fname)); char *dash = strrchr(fname, '-'); - if(!dash) + + if(!dash) { continue; + } + *dash = 0; if(strcmp(fname, "tinc") && strcmp(fname, "host") && strcmp(fname, "subnet")) { static bool explained = false; fprintf(stderr, "WARNING: Unknown script %s" SLASH "%s found.\n", confbase, ent->d_name); + if(!explained) { fprintf(stderr, "The only scripts in %s executed by tinc are:\n", confbase); fprintf(stderr, "tinc-up, tinc-down, host-up, host-down, subnet-up and subnet-down.\n"); explained = true; } + continue; } snprintf(fname, sizeof(fname), "%s" SLASH "%s", confbase, ent->d_name); + if(access(fname, R_OK | X_OK)) { if(errno != EACCES) { fprintf(stderr, "ERROR: cannot access %s: %s\n", fname, strerror(errno)); continue; } + fprintf(stderr, "WARNING: cannot read and execute %s: %s\n", fname, strerror(errno)); + if(ask_fix()) { - if(chmod(fname, 0755)) + if(chmod(fname, 0755)) { fprintf(stderr, "ERROR: cannot change permissions on %s: %s\n", fname, strerror(errno)); + } } } } + closedir(dir); snprintf(dname, sizeof(dname), "%s" SLASH "hosts", confbase); dir = opendir(dname); + if(!dir) { fprintf(stderr, "ERROR: cannot read directory %s: %s\n", dname, strerror(errno)); return 1; } while((ent = readdir(dir))) { - if(strtailcmp(ent->d_name, "-up") && strtailcmp(ent->d_name, "-down")) + if(strtailcmp(ent->d_name, "-up") && strtailcmp(ent->d_name, "-down")) { continue; + } strncpy(fname, ent->d_name, sizeof(fname)); char *dash = strrchr(fname, '-'); - if(!dash) + + if(!dash) { continue; + } + *dash = 0; snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, ent->d_name); + if(access(fname, R_OK | X_OK)) { if(errno != EACCES) { fprintf(stderr, "ERROR: cannot access %s: %s\n", fname, strerror(errno)); continue; } + fprintf(stderr, "WARNING: cannot read and execute %s: %s\n", fname, strerror(errno)); + if(ask_fix()) { - if(chmod(fname, 0755)) + if(chmod(fname, 0755)) { fprintf(stderr, "ERROR: cannot change permissions on %s: %s\n", fname, strerror(errno)); + } } } } + closedir(dir); - + // Check for obsolete / unsafe / unknown configuration variables. check_conffile(tinc_conf, true); dir = opendir(dname); + if(dir) { while((ent = readdir(dir))) { - if(!check_id(ent->d_name)) + if(!check_id(ent->d_name)) { continue; + } snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, ent->d_name); check_conffile(fname, false); } + closedir(dir); } diff --git a/src/gcrypt/cipher.c b/src/gcrypt/cipher.c index b9b3224..1440f2e 100644 --- a/src/gcrypt/cipher.c +++ b/src/gcrypt/cipher.c @@ -55,7 +55,7 @@ static struct { static bool nametocipher(const char *name, int *algo, int *mode) { size_t i; - for(i = 0; i < sizeof(ciphertable) / sizeof *ciphertable; i++) { + for(i = 0; i < sizeof(ciphertable) / sizeof * ciphertable; i++) { if(ciphertable[i].name && !strcasecmp(name, ciphertable[i].name)) { *algo = ciphertable[i].algo; *mode = ciphertable[i].mode; @@ -69,7 +69,7 @@ static bool nametocipher(const char *name, int *algo, int *mode) { static bool nidtocipher(int nid, int *algo, int *mode) { size_t i; - for(i = 0; i < sizeof(ciphertable) / sizeof *ciphertable; i++) { + for(i = 0; i < sizeof(ciphertable) / sizeof * ciphertable; i++) { if(nid == ciphertable[i].nid) { *algo = ciphertable[i].algo; *mode = ciphertable[i].mode; @@ -83,7 +83,7 @@ static bool nidtocipher(int nid, int *algo, int *mode) { static bool ciphertonid(int algo, int mode, int *nid) { size_t i; - for(i = 0; i < sizeof(ciphertable) / sizeof *ciphertable; i++) { + for(i = 0; i < sizeof(ciphertable) / sizeof * ciphertable; i++) { if(algo == ciphertable[i].algo && mode == ciphertable[i].mode) { *nid = ciphertable[i].nid; return true; @@ -193,8 +193,9 @@ bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou uint8_t pad[cipher->blklen]; if(cipher->padding) { - if(!oneshot) + if(!oneshot) { return false; + } size_t reqlen = ((inlen + cipher->blklen) / cipher->blklen) * cipher->blklen; @@ -207,14 +208,16 @@ bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou inlen = reqlen - cipher->blklen; for(int i = 0; i < cipher->blklen; i++) - if(i < cipher->blklen - padbyte) + if(i < cipher->blklen - padbyte) { pad[i] = ((uint8_t *)indata)[inlen + i]; - else + } else { pad[i] = padbyte; + } } - if(oneshot) + if(oneshot) { gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen); + } if((err = gcry_cipher_encrypt(cipher->handle, outdata, *outlen, indata, inlen))) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: %s", gcry_strerror(err)); @@ -237,8 +240,9 @@ bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) { gcry_error_t err; - if(oneshot) + if(oneshot) { gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen); + } if((err = gcry_cipher_decrypt(cipher->handle, outdata, *outlen, indata, inlen))) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting: %s", gcry_strerror(err)); @@ -246,8 +250,9 @@ bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou } if(cipher->padding) { - if(!oneshot) + if(!oneshot) { return false; + } uint8_t padbyte = ((uint8_t *)outdata)[inlen - 1]; @@ -265,8 +270,9 @@ bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou } *outlen = origlen; - } else + } else { *outlen = inlen; + } return true; } diff --git a/src/gcrypt/digest.c b/src/gcrypt/digest.c index 60b9569..ac5dc74 100644 --- a/src/gcrypt/digest.c +++ b/src/gcrypt/digest.c @@ -37,7 +37,7 @@ static struct { static bool nametodigest(const char *name, int *algo) { int i; - for(i = 0; i < sizeof(digesttable) / sizeof *digesttable; i++) { + for(i = 0; i < sizeof(digesttable) / sizeof * digesttable; i++) { if(digesttable[i].name && !strcasecmp(name, digesttable[i].name)) { *algo = digesttable[i].algo; return true; @@ -50,7 +50,7 @@ static bool nametodigest(const char *name, int *algo) { static bool nidtodigest(int nid, int *algo) { int i; - for(i = 0; i < sizeof(digesttable) / sizeof *digesttable; i++) { + for(i = 0; i < sizeof(digesttable) / sizeof * digesttable; i++) { if(nid == digesttable[i].nid) { *algo = digesttable[i].algo; return true; @@ -63,7 +63,7 @@ static bool nidtodigest(int nid, int *algo) { static bool digesttonid(int algo, int *nid) { int i; - for(i = 0; i < sizeof(digesttable) / sizeof *digesttable; i++) { + for(i = 0; i < sizeof(digesttable) / sizeof * digesttable; i++) { if(algo == digesttable[i].algo) { *nid = digesttable[i].nid; return true; @@ -81,10 +81,11 @@ static bool digest_open(digest_t *digest, int algo, int maclength) { unsigned int len = gcry_md_get_algo_dlen(algo); - if(maclength > len || maclength < 0) + if(maclength > len || maclength < 0) { digest->maclength = len; - else + } else { digest->maclength = maclength; + } digest->algo = algo; digest->hmac = NULL; @@ -119,16 +120,21 @@ bool digest_open_sha1(digest_t *digest, int maclength) { } void digest_close(digest_t *digest) { - if(digest->hmac) + if(digest->hmac) { gcry_md_close(digest->hmac); + } + digest->hmac = NULL; } bool digest_set_key(digest_t *digest, const void *key, size_t len) { - if(!digest->hmac) + if(!digest->hmac) { gcry_md_open(&digest->hmac, digest->algo, GCRY_MD_FLAG_HMAC); - if(!digest->hmac) + } + + if(!digest->hmac) { return false; + } return !gcry_md_setkey(digest->hmac, key, len); } @@ -141,8 +147,11 @@ bool digest_create(digest_t *digest, const void *indata, size_t inlen, void *out gcry_md_reset(digest->hmac); gcry_md_write(digest->hmac, indata, inlen); tmpdata = gcry_md_read(digest->hmac, digest->algo); - if(!tmpdata) + + if(!tmpdata) { return false; + } + memcpy(outdata, tmpdata, digest->maclength); } else { char tmpdata[len]; diff --git a/src/gcrypt/prf.c b/src/gcrypt/prf.c index 1937f67..ce80f8c 100644 --- a/src/gcrypt/prf.c +++ b/src/gcrypt/prf.c @@ -23,8 +23,9 @@ #include "../ed25519/sha512.h" static void memxor(char *buf, char c, size_t len) { - for(size_t i = 0; i < len; i++) + for(size_t i = 0; i < len; i++) { buf[i] ^= c; + } } static const size_t mdlen = 64; @@ -38,30 +39,39 @@ static bool hmac_sha512(const char *key, size_t keylen, const char *msg, size_t memcpy(tmp, key, keylen); memset(tmp + keylen, 0, blklen - keylen); } else { - if(sha512(key, keylen, tmp) != 0) + if(sha512(key, keylen, tmp) != 0) { return false; + } + memset(tmp + mdlen, 0, blklen - mdlen); } - if(sha512_init(&md) != 0) + if(sha512_init(&md) != 0) { return false; + } // ipad memxor(tmp, 0x36, blklen); - if(sha512_update(&md, tmp, blklen) != 0) + + if(sha512_update(&md, tmp, blklen) != 0) { return false; + } // message - if(sha512_update(&md, msg, msglen) != 0) + if(sha512_update(&md, msg, msglen) != 0) { return false; + } - if(sha512_final(&md, tmp + blklen) != 0) + if(sha512_final(&md, tmp + blklen) != 0) { return false; + } // opad memxor(tmp, 0x36 ^ 0x5c, blklen); - if(sha512(tmp, sizeof(tmp), out) != 0) + + if(sha512(tmp, sizeof(tmp), out) != 0) { return false; + } return true; } @@ -84,18 +94,23 @@ bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char while(outlen > 0) { /* Inner HMAC */ - if(!hmac_sha512(secret, secretlen, data, sizeof(data), data)) + if(!hmac_sha512(secret, secretlen, data, sizeof(data), data)) { return false; + } /* Outer HMAC */ if(outlen >= mdlen) { - if(!hmac_sha512(secret, secretlen, data, sizeof(data), out)) + if(!hmac_sha512(secret, secretlen, data, sizeof(data), out)) { return false; + } + out += mdlen; outlen -= mdlen; } else { - if(!hmac_sha512(secret, secretlen, data, sizeof(data), hash)) + if(!hmac_sha512(secret, secretlen, data, sizeof(data), hash)) { return false; + } + memcpy(out, hash, outlen); out += outlen; outlen = 0; diff --git a/src/gcrypt/rsa.c b/src/gcrypt/rsa.c index d354b0c..eb9f58d 100644 --- a/src/gcrypt/rsa.c +++ b/src/gcrypt/rsa.c @@ -27,28 +27,28 @@ // Base64 decoding table static const uint8_t b64d[128] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, - 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, - 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, - 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, - 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, - 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, - 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, - 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, - 0xff, 0xff + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, + 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, + 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, + 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, + 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, + 0xff, 0xff }; // PEM encoding/decoding functions @@ -61,12 +61,15 @@ static bool pem_decode(FILE *fp, const char *header, uint8_t *buf, size_t size, size_t i, j = 0; while(!feof(fp)) { - if(!fgets(line, sizeof(line), fp)) + if(!fgets(line, sizeof(line), fp)) { return false; + } if(!decode && !strncmp(line, "-----BEGIN ", 11)) { - if(!strncmp(line + 11, header, strlen(header))) + if(!strncmp(line + 11, header, strlen(header))) { decode = true; + } + continue; } @@ -74,14 +77,18 @@ static bool pem_decode(FILE *fp, const char *header, uint8_t *buf, size_t size, break; } - if(!decode) + if(!decode) { continue; + } for(i = 0; line[i] >= ' '; i++) { - if((signed char)line[i] < 0 || b64d[(int)line[i]] == 0xff) + if((signed char)line[i] < 0 || b64d[(int)line[i]] == 0xff) { break; + } + word |= b64d[(int)line[i]] << shift; shift -= 6; + if(shift <= 2) { if(j > size) { errno = ENOMEM; @@ -95,8 +102,10 @@ static bool pem_decode(FILE *fp, const char *header, uint8_t *buf, size_t size, } } - if(outsize) + if(outsize) { *outsize = j; + } + return true; } @@ -104,20 +113,25 @@ static bool pem_decode(FILE *fp, const char *header, uint8_t *buf, size_t size, // BER decoding functions static int ber_read_id(unsigned char **p, size_t *buflen) { - if(*buflen <= 0) + if(*buflen <= 0) { return -1; + } if((**p & 0x1f) == 0x1f) { int id = 0; bool more; + while(*buflen > 0) { id <<= 7; id |= **p & 0x7f; more = *(*p)++ & 0x80; (*buflen)--; - if(!more) + + if(!more) { break; + } } + return id; } else { (*buflen)--; @@ -126,15 +140,18 @@ static int ber_read_id(unsigned char **p, size_t *buflen) { } static size_t ber_read_len(unsigned char **p, size_t *buflen) { - if(*buflen <= 0) + if(*buflen <= 0) { return -1; + } if(**p & 0x80) { size_t result = 0; int len = *(*p)++ & 0x7f; (*buflen)--; - if(len > *buflen) + + if(len > *buflen) { return 0; + } while(len--) { result <<= 8; @@ -155,8 +172,10 @@ static bool ber_read_sequence(unsigned char **p, size_t *buflen, size_t *result) size_t len = ber_read_len(p, buflen); if(tag == 0x10) { - if(result) + if(result) { *result = len; + } + return true; } else { return false; @@ -168,11 +187,13 @@ static bool ber_read_mpi(unsigned char **p, size_t *buflen, gcry_mpi_t *mpi) { size_t len = ber_read_len(p, buflen); gcry_error_t err = 0; - if(tag != 0x02 || len > *buflen) + if(tag != 0x02 || len > *buflen) { return false; + } - if(mpi) + if(mpi) { err = gcry_mpi_scan(mpi, GCRYMPI_FMT_USG, *p, len, NULL); + } *p += len; *buflen -= len; @@ -184,7 +205,7 @@ bool rsa_set_hex_public_key(rsa_t *rsa, char *n, char *e) { gcry_error_t err = 0; err = gcry_mpi_scan(&rsa->n, GCRYMPI_FMT_HEX, n, 0, NULL) - ?: gcry_mpi_scan(&rsa->e, GCRYMPI_FMT_HEX, e, 0, NULL); + ? : gcry_mpi_scan(&rsa->e, GCRYMPI_FMT_HEX, e, 0, NULL); if(err) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading RSA public key: %s", gcry_strerror(errno)); @@ -198,8 +219,8 @@ bool rsa_set_hex_private_key(rsa_t *rsa, char *n, char *e, char *d) { gcry_error_t err = 0; err = gcry_mpi_scan(&rsa->n, GCRYMPI_FMT_HEX, n, 0, NULL) - ?: gcry_mpi_scan(&rsa->e, GCRYMPI_FMT_HEX, e, 0, NULL) - ?: gcry_mpi_scan(&rsa->d, GCRYMPI_FMT_HEX, d, 0, NULL); + ? : gcry_mpi_scan(&rsa->e, GCRYMPI_FMT_HEX, e, 0, NULL) + ? : gcry_mpi_scan(&rsa->d, GCRYMPI_FMT_HEX, d, 0, NULL); if(err) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading RSA public key: %s", gcry_strerror(errno)); @@ -221,9 +242,9 @@ bool rsa_read_pem_public_key(rsa_t *rsa, FILE *fp) { } if(!ber_read_sequence(&derp, &derlen, NULL) - || !ber_read_mpi(&derp, &derlen, &rsa->n) - || !ber_read_mpi(&derp, &derlen, &rsa->e) - || derlen) { + || !ber_read_mpi(&derp, &derlen, &rsa->n) + || !ber_read_mpi(&derp, &derlen, &rsa->e) + || derlen) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while decoding RSA public key"); return NULL; } @@ -241,16 +262,16 @@ bool rsa_read_pem_private_key(rsa_t *rsa, FILE *fp) { } if(!ber_read_sequence(&derp, &derlen, NULL) - || !ber_read_mpi(&derp, &derlen, NULL) - || !ber_read_mpi(&derp, &derlen, &rsa->n) - || !ber_read_mpi(&derp, &derlen, &rsa->e) - || !ber_read_mpi(&derp, &derlen, &rsa->d) - || !ber_read_mpi(&derp, &derlen, NULL) // p - || !ber_read_mpi(&derp, &derlen, NULL) // q - || !ber_read_mpi(&derp, &derlen, NULL) - || !ber_read_mpi(&derp, &derlen, NULL) - || !ber_read_mpi(&derp, &derlen, NULL) // u - || derlen) { + || !ber_read_mpi(&derp, &derlen, NULL) + || !ber_read_mpi(&derp, &derlen, &rsa->n) + || !ber_read_mpi(&derp, &derlen, &rsa->e) + || !ber_read_mpi(&derp, &derlen, &rsa->d) + || !ber_read_mpi(&derp, &derlen, NULL) // p + || !ber_read_mpi(&derp, &derlen, NULL) // q + || !ber_read_mpi(&derp, &derlen, NULL) + || !ber_read_mpi(&derp, &derlen, NULL) + || !ber_read_mpi(&derp, &derlen, NULL) // u + || derlen) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while decoding RSA private key"); return NULL; } @@ -277,10 +298,12 @@ bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) { gcry_mpi_powm(outmpi, inmpi, rsa->e, rsa->n); int pad = len - (gcry_mpi_get_nbits(outmpi) + 7) / 8; - while(pad--) + + while(pad--) { *(char *)out++ = 0; + } - check(gcry_mpi_print(GCRYMPI_FMT_USG, out,len, NULL, outmpi)); + check(gcry_mpi_print(GCRYMPI_FMT_USG, out, len, NULL, outmpi)); return true; } @@ -293,10 +316,12 @@ bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) { gcry_mpi_powm(outmpi, inmpi, rsa->d, rsa->n); int pad = len - (gcry_mpi_get_nbits(outmpi) + 7) / 8; - while(pad--) + + while(pad--) { *(char *)out++ = 0; + } - check(gcry_mpi_print(GCRYMPI_FMT_USG, out,len, NULL, outmpi)); + check(gcry_mpi_print(GCRYMPI_FMT_USG, out, len, NULL, outmpi)); return true; } diff --git a/src/gcrypt/rsagen.c b/src/gcrypt/rsagen.c index dfbfa33..030f2bc 100644 --- a/src/gcrypt/rsagen.c +++ b/src/gcrypt/rsagen.c @@ -44,14 +44,16 @@ static bool pem_encode(FILE *fp, const char *header, uint8_t *buf, size_t size) word = buf[i] << 16 | buf[i + 1] << 8 | buf[i + 2]; } else { word = buf[i] << 16; - if(i == size - 2) + + if(i == size - 2) { word |= buf[i + 1] << 8; + } } line[j++] = b64e[(word >> 18) ]; line[j++] = b64e[(word >> 12) & 0x3f]; line[j++] = b64e[(word >> 6) & 0x3f]; - line[j++] = b64e[(word ) & 0x3f]; + line[j++] = b64e[(word) & 0x3f]; if(j >= 64) { line[j++] = '\n'; @@ -62,8 +64,10 @@ static bool pem_encode(FILE *fp, const char *header, uint8_t *buf, size_t size) } if(size % 3 > 0) { - if(size % 3 > 1) + if(size % 3 > 1) { line[j++] = '='; + } + line[j++] = '='; } @@ -82,19 +86,24 @@ static bool pem_encode(FILE *fp, const char *header, uint8_t *buf, size_t size) // BER encoding functions static bool ber_write_id(uint8_t **p, size_t *buflen, int id) { - if(*buflen <= 0) + if(*buflen <= 0) { return false; + } if(id >= 0x1f) { while(id) { - if(*buflen <= 0) + if(*buflen <= 0) { return false; + } (*buflen)--; **p = id & 0x7f; id >>= 7; - if(id) + + if(id) { **p |= 0x80; + } + (*p)++; } } else { @@ -107,14 +116,18 @@ static bool ber_write_id(uint8_t **p, size_t *buflen, int id) { static bool ber_write_len(uint8_t **p, size_t *buflen, size_t len) { do { - if(*buflen <= 0) + if(*buflen <= 0) { return false; + } (*buflen)--; **p = len & 0x7f; len >>= 7; - if(len) + + if(len) { **p |= 0x80; + } + (*p)++; } while(len); @@ -122,8 +135,9 @@ static bool ber_write_len(uint8_t **p, size_t *buflen, size_t len) { } static bool ber_write_sequence(uint8_t **p, size_t *buflen, uint8_t *seqbuf, size_t seqlen) { - if(!ber_write_id(p, buflen, 0x10) || !ber_write_len(p, buflen, seqlen) || *buflen < seqlen) + if(!ber_write_id(p, buflen, 0x10) || !ber_write_len(p, buflen, seqlen) || *buflen < seqlen) { return false; + } memcpy(*p, seqbuf, seqlen); *p += seqlen; @@ -138,11 +152,14 @@ static bool ber_write_mpi(uint8_t **p, size_t *buflen, gcry_mpi_t mpi) { gcry_error_t err; err = gcry_mpi_aprint(GCRYMPI_FMT_USG, &tmpbuf, &tmplen, mpi); - if(err) + + if(err) { return false; + } - if(!ber_write_id(p, buflen, 0x02) || !ber_write_len(p, buflen, tmplen) || *buflen < tmplen) + if(!ber_write_id(p, buflen, 0x02) || !ber_write_len(p, buflen, tmplen) || *buflen < tmplen) { return false; + } memcpy(*p, tmpbuf, tmplen); *p += tmplen; @@ -162,8 +179,8 @@ bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp) { size_t derlen2 = sizeof(derbuf2); if(!ber_write_mpi(&derp1, &derlen1, &rsa->n) - || !ber_write_mpi(&derp1, &derlen1, &rsa->e) - || !ber_write_sequence(&derp2, &derlen2, derbuf1, derlen1)) { + || !ber_write_mpi(&derp1, &derlen1, &rsa->e) + || !ber_write_sequence(&derp2, &derlen2, derbuf1, derlen1)) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while encoding RSA public key"); return false; } @@ -185,24 +202,26 @@ bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp) { size_t derlen2 = sizeof(derbuf2); if(!ber_write_mpi(&derp1, &derlen1, &bits) - || ber_write_mpi(&derp1, &derlen1, &rsa->n) // modulus - || ber_write_mpi(&derp1, &derlen1, &rsa->e) // public exponent - || ber_write_mpi(&derp1, &derlen1, &rsa->d) // private exponent - || ber_write_mpi(&derp1, &derlen1, &p) - || ber_write_mpi(&derp1, &derlen1, &q) - || ber_write_mpi(&derp1, &derlen1, &exp1) - || ber_write_mpi(&derp1, &derlen1, &exp2) - || ber_write_mpi(&derp1, &derlen1, &coeff)) + || ber_write_mpi(&derp1, &derlen1, &rsa->n) // modulus + || ber_write_mpi(&derp1, &derlen1, &rsa->e) // public exponent + || ber_write_mpi(&derp1, &derlen1, &rsa->d) // private exponent + || ber_write_mpi(&derp1, &derlen1, &p) + || ber_write_mpi(&derp1, &derlen1, &q) + || ber_write_mpi(&derp1, &derlen1, &exp1) + || ber_write_mpi(&derp1, &derlen1, &exp2) + || ber_write_mpi(&derp1, &derlen1, &coeff)) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while encoding RSA private key"); - return false; } - if(!pem_encode(fp, "RSA PRIVATE KEY", derbuf2, derlen2)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to write RSA private key: %s", strerror(errno)); - return false; - } + return false; +} - return true; +if(!pem_encode(fp, "RSA PRIVATE KEY", derbuf2, derlen2)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Unable to write RSA private key: %s", strerror(errno)); + return false; +} + +return true; } #endif diff --git a/src/getopt.c b/src/getopt.c index d63887e..5d5fb59 100644 --- a/src/getopt.c +++ b/src/getopt.c @@ -4,7 +4,7 @@ before changing it! Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97 - Free Software Foundation, Inc. + Free Software Foundation, Inc. NOTE: The canonical source of this file is maintained with the GNU C Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. @@ -69,12 +69,12 @@ with this program; if not, write to the Free Software Foundation, Inc., /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ +#ifdef __GNU_LIBRARY__ /* Don't include stdlib.h for non-GNU C libraries because some of them contain conflicting prototypes for getopt. */ #include #include -#endif /* GNU C library. */ +#endif /* GNU C library. */ #ifdef VMS #include @@ -183,40 +183,41 @@ int optopt = '?'; of the value of `ordering'. In the case of RETURN_IN_ORDER, only `--' can cause `getopt' to return -1 with `optind' != ARGC. */ -static enum -{ - REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +static enum { + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; /* Value of POSIXLY_CORRECT environment variable. */ static char *posixly_correct; -#ifdef __GNU_LIBRARY__ +#ifdef __GNU_LIBRARY__ /* We want to avoid inclusion of string.h with non-GNU libraries because there are many ways it can cause trouble. On some systems, it contains special magic macros that don't work in GCC. */ #include -#define my_index strchr +#define my_index strchr #else /* Avoid depending on library functions or files whose names are inconsistent. */ -char *getenv (); +char *getenv(); static char * -my_index (str, chr) - const char *str; - int chr; +my_index(str, chr) +const char *str; +int chr; { - while (*str) - { - if (*str == chr) - return (char *) str; - str++; - } - return 0; + while(*str) { + if(*str == chr) { + return (char *) str; + } + + str++; + } + + return 0; } /* If using GCC, we can safely declare strlen this way. @@ -227,7 +228,7 @@ my_index (str, chr) #if !defined (__STDC__) || !__STDC__ /* gcc with -traditional declares the built-in strlen to return int, and has done so at least since version 2.4.5. -- rms. */ -extern int strlen (const char *); +extern int strlen(const char *); #endif /* not __STDC__ */ #endif /* __GNUC__ */ @@ -261,26 +262,25 @@ extern pid_t __libc_pid; is valid for the getopt call we must make sure that the ARGV passed to getopt is that one passed to the process. */ static void -__attribute__ ((__unused__)) -store_args_and_env (int argc, char *const *argv) -{ - /* XXX This is no good solution. We should rather copy the args so - that we can compare them later. But we must not use malloc(3). */ - original_argc = argc; - original_argv = argv; +__attribute__((__unused__)) +store_args_and_env(int argc, char *const *argv) { + /* XXX This is no good solution. We should rather copy the args so + that we can compare them later. But we must not use malloc(3). */ + original_argc = argc; + original_argv = argv; } -text_set_element (__libc_subinit, store_args_and_env); +text_set_element(__libc_subinit, store_args_and_env); # define SWAP_FLAGS(ch1, ch2) \ - if (nonoption_flags_len > 0) \ - { \ - char __tmp = __getopt_nonoption_flags[ch1]; \ - __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ - __getopt_nonoption_flags[ch2] = __tmp; \ - } -#else /* !_LIBC */ + if (nonoption_flags_len > 0) \ + { \ + char __tmp = __getopt_nonoption_flags[ch1]; \ + __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ + __getopt_nonoption_flags[ch2] = __tmp; \ + } +#else /* !_LIBC */ # define SWAP_FLAGS(ch1, ch2) -#endif /* _LIBC */ +#endif /* _LIBC */ /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) @@ -292,161 +292,158 @@ text_set_element (__libc_subinit, store_args_and_env); the new indices of the non-options in ARGV after they are moved. */ #if defined (__STDC__) && __STDC__ -static void exchange (char **); +static void exchange(char **); #endif static void -exchange (argv) - char **argv; +exchange(argv) +char **argv; { - int bottom = first_nonopt; - int middle = last_nonopt; - int top = optind; - char *tem; + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; - /* Exchange the shorter segment with the far end of the longer segment. - That puts the shorter segment into the right place. - It leaves the longer segment in the right place overall, - but it consists of two parts that need to be swapped next. */ + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ #ifdef _LIBC - /* First make sure the handling of the `__getopt_nonoption_flags' - string can work normally. Our top argument must be in the range - of the string. */ - if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) - { - /* We must extend the array. The user plays games with us and - presents new arguments. */ - char *new_str = malloc (top + 1); - if (new_str == NULL) - nonoption_flags_len = nonoption_flags_max_len = 0; - else - { - memcpy (new_str, __getopt_nonoption_flags, nonoption_flags_max_len); - memset (&new_str[nonoption_flags_max_len], '\0', - top + 1 - nonoption_flags_max_len); - nonoption_flags_max_len = top + 1; - __getopt_nonoption_flags = new_str; + + /* First make sure the handling of the `__getopt_nonoption_flags' + string can work normally. Our top argument must be in the range + of the string. */ + if(nonoption_flags_len > 0 && top >= nonoption_flags_max_len) { + /* We must extend the array. The user plays games with us and + presents new arguments. */ + char *new_str = malloc(top + 1); + + if(new_str == NULL) { + nonoption_flags_len = nonoption_flags_max_len = 0; + } else { + memcpy(new_str, __getopt_nonoption_flags, nonoption_flags_max_len); + memset(&new_str[nonoption_flags_max_len], '\0', + top + 1 - nonoption_flags_max_len); + nonoption_flags_max_len = top + 1; + __getopt_nonoption_flags = new_str; + } } - } + #endif - while (top > middle && middle > bottom) - { - if (top - middle > middle - bottom) - { - /* Bottom segment is the short one. */ - int len = middle - bottom; - register int i; - - /* Swap it with the top part of the top segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[top - (middle - bottom) + i]; - argv[top - (middle - bottom) + i] = tem; - SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); - } - /* Exclude the moved bottom segment from further swapping. */ - top -= len; - } - else - { - /* Top segment is the short one. */ - int len = top - middle; - register int i; - - /* Swap it with the bottom part of the bottom segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[middle + i]; - argv[middle + i] = tem; - SWAP_FLAGS (bottom + i, middle + i); - } - /* Exclude the moved top segment from further swapping. */ - bottom += len; + while(top > middle && middle > bottom) { + if(top - middle > middle - bottom) { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for(i = 0; i < len; i++) { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + SWAP_FLAGS(bottom + i, top - (middle - bottom) + i); + } + + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } else { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for(i = 0; i < len; i++) { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + SWAP_FLAGS(bottom + i, middle + i); + } + + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } } - } - /* Update records for the slots the non-options now occupy. */ + /* Update records for the slots the non-options now occupy. */ - first_nonopt += (optind - last_nonopt); - last_nonopt = optind; + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; } /* Initialize the internal data when the first call is made. */ #if defined (__STDC__) && __STDC__ -static const char *_getopt_initialize (int, char *const *, const char *); +static const char *_getopt_initialize(int, char *const *, const char *); #endif static const char * -_getopt_initialize (argc, argv, optstring) - int argc; - char *const *argv; - const char *optstring; +_getopt_initialize(argc, argv, optstring) +int argc; +char *const *argv; +const char *optstring; { - /* Start processing options with ARGV-element 1 (since ARGV-element 0 - is the program name); the sequence of previously skipped - non-option ARGV-elements is empty. */ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ - first_nonopt = last_nonopt = optind; + first_nonopt = last_nonopt = optind; - nextchar = NULL; + nextchar = NULL; - posixly_correct = getenv ("POSIXLY_CORRECT"); + posixly_correct = getenv("POSIXLY_CORRECT"); - /* Determine how to handle the ordering of options and nonoptions. */ + /* Determine how to handle the ordering of options and nonoptions. */ - if (optstring[0] == '-') - { - ordering = RETURN_IN_ORDER; - ++optstring; - } - else if (optstring[0] == '+') - { - ordering = REQUIRE_ORDER; - ++optstring; - } - else if (posixly_correct != NULL) - ordering = REQUIRE_ORDER; - else - ordering = PERMUTE; + if(optstring[0] == '-') { + ordering = RETURN_IN_ORDER; + ++optstring; + } else if(optstring[0] == '+') { + ordering = REQUIRE_ORDER; + ++optstring; + } else if(posixly_correct != NULL) { + ordering = REQUIRE_ORDER; + } else { + ordering = PERMUTE; + } #ifdef _LIBC - if (posixly_correct == NULL - && argc == original_argc && argv == original_argv) - { - if (nonoption_flags_max_len == 0) - { - if (__getopt_nonoption_flags == NULL - || __getopt_nonoption_flags[0] == '\0') - nonoption_flags_max_len = -1; - else - { - const char *orig_str = __getopt_nonoption_flags; - int len = nonoption_flags_max_len = strlen (orig_str); - if (nonoption_flags_max_len < argc) - nonoption_flags_max_len = argc; - __getopt_nonoption_flags = - (char *) malloc (nonoption_flags_max_len); - if (__getopt_nonoption_flags == NULL) - nonoption_flags_max_len = -1; - else - { - memcpy (__getopt_nonoption_flags, orig_str, len); - memset (&__getopt_nonoption_flags[len], '\0', - nonoption_flags_max_len - len); + + if(posixly_correct == NULL + && argc == original_argc && argv == original_argv) { + if(nonoption_flags_max_len == 0) { + if(__getopt_nonoption_flags == NULL + || __getopt_nonoption_flags[0] == '\0') { + nonoption_flags_max_len = -1; + } else { + const char *orig_str = __getopt_nonoption_flags; + int len = nonoption_flags_max_len = strlen(orig_str); + + if(nonoption_flags_max_len < argc) { + nonoption_flags_max_len = argc; + } + + __getopt_nonoption_flags = + (char *) malloc(nonoption_flags_max_len); + + if(__getopt_nonoption_flags == NULL) { + nonoption_flags_max_len = -1; + } else { + memcpy(__getopt_nonoption_flags, orig_str, len); + memset(&__getopt_nonoption_flags[len], '\0', + nonoption_flags_max_len - len); + } + } } - } + + nonoption_flags_len = nonoption_flags_max_len; + } else { + nonoption_flags_len = 0; } - nonoption_flags_len = nonoption_flags_max_len; - } - else - nonoption_flags_len = 0; + #endif - return optstring; + return optstring; } /* Scan elements of ARGV (whose length is ARGC) for option characters @@ -506,474 +503,476 @@ _getopt_initialize (argc, argv, optstring) long-named options. */ int -_getopt_internal (argc, argv, optstring, longopts, longind, long_only) - int argc; - char *const *argv; - const char *optstring; - const struct option *longopts; - int *longind; - int long_only; +_getopt_internal(argc, argv, optstring, longopts, longind, long_only) +int argc; +char *const *argv; +const char *optstring; +const struct option *longopts; +int *longind; +int long_only; { - optarg = NULL; - - if (optind == 0 || !__getopt_initialized) - { - if (optind == 0) - optind = 1; /* Don't scan ARGV[0], the program name. */ - optstring = _getopt_initialize (argc, argv, optstring); - __getopt_initialized = 1; - } - - /* Test whether ARGV[optind] points to a non-option argument. - Either it does not have option syntax, or there is an environment flag - from the shell indicating it is not an option. The later information - is only used when the used in the GNU libc. */ + optarg = NULL; + + if(optind == 0 || !__getopt_initialized) { + if(optind == 0) { + optind = 1; /* Don't scan ARGV[0], the program name. */ + } + + optstring = _getopt_initialize(argc, argv, optstring); + __getopt_initialized = 1; + } + + /* Test whether ARGV[optind] points to a non-option argument. + Either it does not have option syntax, or there is an environment flag + from the shell indicating it is not an option. The later information + is only used when the used in the GNU libc. */ #ifdef _LIBC -#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ - || (optind < nonoption_flags_len \ - && __getopt_nonoption_flags[optind] == '1')) +#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ + || (optind < nonoption_flags_len \ + && __getopt_nonoption_flags[optind] == '1')) #else #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') #endif - if (nextchar == NULL || *nextchar == '\0') - { - /* Advance to the next ARGV-element. */ + if(nextchar == NULL || *nextchar == '\0') { + /* Advance to the next ARGV-element. */ - /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been - moved back by the user (who may also have changed the arguments). */ - if (last_nonopt > optind) - last_nonopt = optind; - if (first_nonopt > optind) - first_nonopt = optind; + /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been + moved back by the user (who may also have changed the arguments). */ + if(last_nonopt > optind) { + last_nonopt = optind; + } - if (ordering == PERMUTE) - { - /* If we have just processed some options following some non-options, - exchange them so that the options come first. */ + if(first_nonopt > optind) { + first_nonopt = optind; + } - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (last_nonopt != optind) - first_nonopt = optind; + if(ordering == PERMUTE) { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ - /* Skip any additional non-options - and extend the range of non-options previously skipped. */ + if(first_nonopt != last_nonopt && last_nonopt != optind) { + exchange((char **) argv); + } else if(last_nonopt != optind) { + first_nonopt = optind; + } - while (optind < argc && NONOPTION_P) - optind++; - last_nonopt = optind; - } + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ - /* The special ARGV-element `--' means premature end of options. - Skip it like a null option, - then exchange with previous non-options as if it were an option, - then skip everything else like a non-option. */ + while(optind < argc && NONOPTION_P) { + optind++; + } - if (optind != argc && !strcmp (argv[optind], "--")) - { - optind++; + last_nonopt = optind; + } - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (first_nonopt == last_nonopt) - first_nonopt = optind; - last_nonopt = argc; + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ - optind = argc; - } + if(optind != argc && !strcmp(argv[optind], "--")) { + optind++; - /* If we have done all the ARGV-elements, stop the scan - and back over any non-options that we skipped and permuted. */ + if(first_nonopt != last_nonopt && last_nonopt != optind) { + exchange((char **) argv); + } else if(first_nonopt == last_nonopt) { + first_nonopt = optind; + } - if (optind == argc) - { - /* Set the next-arg-index to point at the non-options - that we previously skipped, so the caller will digest them. */ - if (first_nonopt != last_nonopt) - optind = first_nonopt; - return -1; - } + last_nonopt = argc; - /* If we have come to a non-option and did not permute it, - either stop the scan or describe it to the caller and pass it by. */ + optind = argc; + } - if (NONOPTION_P) - { - if (ordering == REQUIRE_ORDER) - return -1; - optarg = argv[optind++]; - return 1; - } + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ - /* We have found another option-ARGV-element. - Skip the initial punctuation. */ - - nextchar = (argv[optind] + 1 - + (longopts != NULL && argv[optind][1] == '-')); - } - - /* Decode the current option-ARGV-element. */ - - /* Check whether the ARGV-element is a long option. - - If long_only and the ARGV-element has the form "-f", where f is - a valid short option, don't consider it an abbreviated form of - a long option that starts with f. Otherwise there would be no - way to give the -f short option. - - On the other hand, if there's a long option "fubar" and - the ARGV-element is "-fu", do consider that an abbreviation of - the long option, just like "--fu", and not "-f" with arg "u". - - This distinction seems to be the most useful approach. */ - - if (longopts != NULL - && (argv[optind][1] == '-' - || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) - { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = -1; - int option_index; - - for (nameend = nextchar; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp (p->name, nextchar, nameend - nextchar)) - { - if ((unsigned int) (nameend - nextchar) - == (unsigned int) strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else - /* Second or later nonexact match found. */ - ambig = 1; - } - - if (ambig && !exact) - { - if (opterr) - fprintf (stderr, "%s: option `%s' is ambiguous\n", - argv[0], argv[optind]); - nextchar += strlen (nextchar); - optind++; - optopt = 0; - return '?'; + if(optind == argc) { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if(first_nonopt != last_nonopt) { + optind = first_nonopt; + } + + return -1; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if(NONOPTION_P) { + if(ordering == REQUIRE_ORDER) { + return -1; + } + + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); } - if (pfound != NULL) - { - option_index = indfound; - optind++; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - optarg = nameend + 1; - else - { - if (opterr) - { - if (argv[optind - 1][1] == '-') - /* --option */ - fprintf (stderr, - "%s: option `--%s' doesn't allow an argument\n", - argv[0], pfound->name); - else - /* +option or -option */ - fprintf (stderr, - "%s: option `%c%s' doesn't allow an argument\n", - argv[0], argv[optind - 1][0], pfound->name); - } - - nextchar += strlen (nextchar); - - optopt = pfound->val; - return '?'; + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if(longopts != NULL + && (argv[optind][1] == '-' + || (long_only && (argv[optind][2] || !my_index(optstring, argv[optind][1]))))) { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for(nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for(p = longopts, option_index = 0; p->name; p++, option_index++) + if(!strncmp(p->name, nextchar, nameend - nextchar)) { + if((unsigned int)(nameend - nextchar) + == (unsigned int) strlen(p->name)) { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } else if(pfound == NULL) { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } else + /* Second or later nonexact match found. */ + { + ambig = 1; + } + } + + if(ambig && !exact) { + if(opterr) + fprintf(stderr, "%s: option `%s' is ambiguous\n", + argv[0], argv[optind]); + + nextchar += strlen(nextchar); + optind++; + optopt = 0; + return '?'; } - } - else if (pfound->has_arg == 1) - { - if (optind < argc) - optarg = argv[optind++]; - else - { - if (opterr) - fprintf (stderr, - "%s: option `%s' requires an argument\n", - argv[0], argv[optind - 1]); - nextchar += strlen (nextchar); - optopt = pfound->val; - return optstring[0] == ':' ? ':' : '?'; + + if(pfound != NULL) { + option_index = indfound; + optind++; + + if(*nameend) { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if(pfound->has_arg) { + optarg = nameend + 1; + } else { + if(opterr) { + if(argv[optind - 1][1] == '-') + /* --option */ + fprintf(stderr, + "%s: option `--%s' doesn't allow an argument\n", + argv[0], pfound->name); + else + /* +option or -option */ + fprintf(stderr, + "%s: option `%c%s' doesn't allow an argument\n", + argv[0], argv[optind - 1][0], pfound->name); + } + + nextchar += strlen(nextchar); + + optopt = pfound->val; + return '?'; + } + } else if(pfound->has_arg == 1) { + if(optind < argc) { + optarg = argv[optind++]; + } else { + if(opterr) + fprintf(stderr, + "%s: option `%s' requires an argument\n", + argv[0], argv[optind - 1]); + + nextchar += strlen(nextchar); + optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + + nextchar += strlen(nextchar); + + if(longind != NULL) { + *longind = option_index; + } + + if(pfound->flag) { + *(pfound->flag) = pfound->val; + return 0; + } + + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if(!long_only || argv[optind][1] == '-' + || my_index(optstring, *nextchar) == NULL) { + if(opterr) { + if(argv[optind][1] == '-') + /* --option */ + fprintf(stderr, "%s: unrecognized option `--%s'\n", + argv[0], nextchar); + else + /* +option or -option */ + fprintf(stderr, "%s: unrecognized option `%c%s'\n", + argv[0], argv[optind][0], nextchar); + } + + nextchar = (char *) ""; + optind++; + optopt = 0; + return '?'; } - } - nextchar += strlen (nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; } - /* Can't find it as a long option. If this is not getopt_long_only, - or the option starts with '--' or is not a valid short - option, then it's an error. - Otherwise interpret it as a short option. */ - if (!long_only || argv[optind][1] == '-' - || my_index (optstring, *nextchar) == NULL) + /* Look at and handle the next short option-character. */ + { - if (opterr) - { - if (argv[optind][1] == '-') - /* --option */ - fprintf (stderr, "%s: unrecognized option `--%s'\n", - argv[0], nextchar); - else - /* +option or -option */ - fprintf (stderr, "%s: unrecognized option `%c%s'\n", - argv[0], argv[optind][0], nextchar); - } - nextchar = (char *) ""; - optind++; - optopt = 0; - return '?'; - } - } - - /* Look at and handle the next short option-character. */ - - { - char c = *nextchar++; - char *temp = my_index (optstring, c); - - /* Increment `optind' when we start to process its last character. */ - if (*nextchar == '\0') - ++optind; - - if (temp == NULL || c == ':') - { - if (opterr) - { - if (posixly_correct) - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, "%s: illegal option -- %c\n", - argv[0], c); - else - fprintf (stderr, "%s: invalid option -- %c\n", - argv[0], c); - } - optopt = c; - return '?'; - } - /* Convenience. Treat POSIX -W foo same as long option --foo */ - if (temp[0] == 'W' && temp[1] == ';') - { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = 0; - int option_index; - - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } - else if (optind == argc) - { - if (opterr) - { - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, "%s: option requires an argument -- %c\n", - argv[0], c); - } - optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - return c; - } - else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - optarg = argv[optind++]; - - /* optarg is now the argument, see if it's in the - table of longopts. */ - - for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp (p->name, nextchar, nameend - nextchar)) - { - if ((unsigned int) (nameend - nextchar) == strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; + char c = *nextchar++; + char *temp = my_index(optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if(*nextchar == '\0') { + ++optind; } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; + + if(temp == NULL || c == ':') { + if(opterr) { + if(posixly_correct) + /* 1003.2 specifies the format of this message. */ + fprintf(stderr, "%s: illegal option -- %c\n", + argv[0], c); + else + fprintf(stderr, "%s: invalid option -- %c\n", + argv[0], c); + } + + optopt = c; + return '?'; + } + + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if(temp[0] == 'W' && temp[1] == ';') { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; + + /* This is an option that requires an argument. */ + if(*nextchar != '\0') { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } else if(optind == argc) { + if(opterr) { + /* 1003.2 specifies the format of this message. */ + fprintf(stderr, "%s: option requires an argument -- %c\n", + argv[0], c); + } + + optopt = c; + + if(optstring[0] == ':') { + c = ':'; + } else { + c = '?'; + } + + return c; + } else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + { + optarg = argv[optind++]; + } + + /* optarg is now the argument, see if it's in the + table of longopts. */ + + for(nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for(p = longopts, option_index = 0; p->name; p++, option_index++) + if(!strncmp(p->name, nextchar, nameend - nextchar)) { + if((unsigned int)(nameend - nextchar) == strlen(p->name)) { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } else if(pfound == NULL) { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } else + /* Second or later nonexact match found. */ + { + ambig = 1; + } + } + + if(ambig && !exact) { + if(opterr) + fprintf(stderr, "%s: option `-W %s' is ambiguous\n", + argv[0], argv[optind]); + + nextchar += strlen(nextchar); + optind++; + return '?'; + } + + if(pfound != NULL) { + option_index = indfound; + + if(*nameend) { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if(pfound->has_arg) { + optarg = nameend + 1; + } else { + if(opterr) + fprintf(stderr, + "%s: option `-W %s' doesn't allow an argument\n", + argv[0], pfound->name); + + nextchar += strlen(nextchar); + return '?'; + } + } else if(pfound->has_arg == 1) { + if(optind < argc) { + optarg = argv[optind++]; + } else { + if(opterr) + fprintf(stderr, + "%s: option `%s' requires an argument\n", + argv[0], argv[optind - 1]); + + nextchar += strlen(nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + + nextchar += strlen(nextchar); + + if(longind != NULL) { + *longind = option_index; + } + + if(pfound->flag) { + *(pfound->flag) = pfound->val; + return 0; + } + + return pfound->val; + } + + nextchar = NULL; + return 'W'; /* Let the application handle it. */ } - else - /* Second or later nonexact match found. */ - ambig = 1; - } - if (ambig && !exact) - { - if (opterr) - fprintf (stderr, "%s: option `-W %s' is ambiguous\n", - argv[0], argv[optind]); - nextchar += strlen (nextchar); - optind++; - return '?'; - } - if (pfound != NULL) - { - option_index = indfound; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - optarg = nameend + 1; - else - { - if (opterr) - fprintf (stderr, - "%s: option `-W %s' doesn't allow an argument\n", - argv[0], pfound->name); - - nextchar += strlen (nextchar); - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (optind < argc) - optarg = argv[optind++]; - else - { - if (opterr) - fprintf (stderr, - "%s: option `%s' requires an argument\n", - argv[0], argv[optind - 1]); - nextchar += strlen (nextchar); - return optstring[0] == ':' ? ':' : '?'; - } - } - nextchar += strlen (nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - nextchar = NULL; - return 'W'; /* Let the application handle it. */ - } - if (temp[1] == ':') - { - if (temp[2] == ':') - { - /* This is an option that accepts an argument optionally. */ - if (*nextchar != '\0') - { - optarg = nextchar; - optind++; - } - else - optarg = NULL; - nextchar = NULL; - } - else - { - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } - else if (optind == argc) - { - if (opterr) - { - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, - "%s: option requires an argument -- %c\n", - argv[0], c); - } - optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - } - else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - optarg = argv[optind++]; - nextchar = NULL; - } - } - return c; - } + + if(temp[1] == ':') { + if(temp[2] == ':') { + /* This is an option that accepts an argument optionally. */ + if(*nextchar != '\0') { + optarg = nextchar; + optind++; + } else { + optarg = NULL; + } + + nextchar = NULL; + } else { + /* This is an option that requires an argument. */ + if(*nextchar != '\0') { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } else if(optind == argc) { + if(opterr) { + /* 1003.2 specifies the format of this message. */ + fprintf(stderr, + "%s: option requires an argument -- %c\n", + argv[0], c); + } + + optopt = c; + + if(optstring[0] == ':') { + c = ':'; + } else { + c = '?'; + } + } else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + { + optarg = argv[optind++]; + } + + nextchar = NULL; + } + } + + return c; + } } int -getopt (argc, argv, optstring) - int argc; - char *const *argv; - const char *optstring; +getopt(argc, argv, optstring) +int argc; +char *const *argv; +const char *optstring; { - return _getopt_internal (argc, argv, optstring, - (const struct option *) 0, - (int *) 0, - 0); + return _getopt_internal(argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); } -#endif /* Not ELIDE_CODE. */ +#endif /* Not ELIDE_CODE. */ #ifdef TEST @@ -981,68 +980,72 @@ getopt (argc, argv, optstring) the above definition of `getopt'. */ int -main (argc, argv) - int argc; - char **argv; +main(argc, argv) +int argc; +char **argv; { - int c; - int digit_optind = 0; + int c; + int digit_optind = 0; - while (1) - { - int this_option_optind = optind ? optind : 1; + while(1) { + int this_option_optind = optind ? optind : 1; - c = getopt (argc, argv, "abc:d:0123456789"); - if (c == -1) - break; + c = getopt(argc, argv, "abc:d:0123456789"); - switch (c) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value `%s'\n", optarg); - break; - - case '?': - break; - - default: - printf ("?? getopt returned character code 0%o ??\n", c); + if(c == -1) { + break; + } + + switch(c) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if(digit_optind != 0 && digit_optind != this_option_optind) { + printf("digits occur in two different argv-elements.\n"); + } + + digit_optind = this_option_optind; + printf("option %c\n", c); + break; + + case 'a': + printf("option a\n"); + break; + + case 'b': + printf("option b\n"); + break; + + case 'c': + printf("option c with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf("?? getopt returned character code 0%o ??\n", c); + } } - } - if (optind < argc) - { - printf ("non-option ARGV-elements: "); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - } + if(optind < argc) { + printf("non-option ARGV-elements: "); + + while(optind < argc) { + printf("%s ", argv[optind++]); + } + + printf("\n"); + } - exit (0); + exit(0); } #endif /* TEST */ diff --git a/src/getopt.h b/src/getopt.h index 7cac1bd..e9a7040 100644 --- a/src/getopt.h +++ b/src/getopt.h @@ -25,7 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #ifndef _GETOPT_H #define _GETOPT_H 1 -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif @@ -66,9 +66,9 @@ extern int optopt; zero. The field `has_arg' is: - no_argument (or 0) if the option does not take an argument, - required_argument (or 1) if the option requires an argument, - optional_argument (or 2) if the option takes an optional argument. + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. If the field `flag' is not NULL, it points to a variable that is set to the value given in the field `val' when the option is found, but @@ -81,55 +81,54 @@ extern int optopt; one). For long options that have a zero `flag' field, `getopt' returns the contents of the `val' field. */ -struct option -{ +struct option { #if defined (__STDC__) && __STDC__ - const char *name; + const char *name; #else - char *name; + char *name; #endif - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; }; /* Names for the values of the `has_arg' field of `struct option'. */ -#define no_argument 0 -#define required_argument 1 -#define optional_argument 2 +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 #if defined (__STDC__) && __STDC__ #ifdef __GNU_LIBRARY__ /* Many other libraries have conflicting prototypes for getopt, with differences in the consts, in stdlib.h. To avoid compilation errors, only prototype getopt for the GNU C library. */ -extern int getopt (int argc, char *const *argv, const char *shortopts); +extern int getopt(int argc, char *const *argv, const char *shortopts); #else /* not __GNU_LIBRARY__ */ -extern int getopt (); +extern int getopt(); #endif /* __GNU_LIBRARY__ */ -extern int getopt_long (int argc, char *const *argv, const char *shortopts, - const struct option *longopts, int *longind); -extern int getopt_long_only (int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind); +extern int getopt_long(int argc, char *const *argv, const char *shortopts, + const struct option *longopts, int *longind); +extern int getopt_long_only(int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind); /* Internal only. Users should not call this directly. */ -extern int _getopt_internal (int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind, - int long_only); +extern int _getopt_internal(int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind, + int long_only); #else /* not __STDC__ */ -extern int getopt (); -extern int getopt_long (); -extern int getopt_long_only (); +extern int getopt(); +extern int getopt_long(); +extern int getopt_long_only(); -extern int _getopt_internal (); +extern int _getopt_internal(); #endif /* __STDC__ */ -#ifdef __cplusplus +#ifdef __cplusplus } #endif diff --git a/src/getopt1.c b/src/getopt1.c index 19605a5..3ccb150 100644 --- a/src/getopt1.c +++ b/src/getopt1.c @@ -60,19 +60,19 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #endif -#ifndef NULL +#ifndef NULL #define NULL 0 #endif int -getopt_long (argc, argv, options, long_options, opt_index) - int argc; - char *const *argv; - const char *options; - const struct option *long_options; - int *opt_index; +getopt_long(argc, argv, options, long_options, opt_index) +int argc; +char *const *argv; +const char *options; +const struct option *long_options; +int *opt_index; { - return _getopt_internal (argc, argv, options, long_options, opt_index, 0); + return _getopt_internal(argc, argv, options, long_options, opt_index, 0); } /* Like getopt_long, but '-' as well as '--' can indicate a long option. @@ -81,109 +81,115 @@ getopt_long (argc, argv, options, long_options, opt_index) instead. */ int -getopt_long_only (argc, argv, options, long_options, opt_index) - int argc; - char *const *argv; - const char *options; - const struct option *long_options; - int *opt_index; +getopt_long_only(argc, argv, options, long_options, opt_index) +int argc; +char *const *argv; +const char *options; +const struct option *long_options; +int *opt_index; { - return _getopt_internal (argc, argv, options, long_options, opt_index, 1); + return _getopt_internal(argc, argv, options, long_options, opt_index, 1); } -#endif /* Not ELIDE_CODE. */ +#endif /* Not ELIDE_CODE. */ #ifdef TEST #include int -main (argc, argv) - int argc; - char **argv; +main(argc, argv) +int argc; +char **argv; { - int c; - int digit_optind = 0; - - while (1) - { - int this_option_optind = optind ? optind : 1; - int option_index = 0; - static struct option long_options[] = - { - {"add", 1, 0, 0}, - {"append", 0, 0, 0}, - {"delete", 1, 0, 0}, - {"verbose", 0, 0, 0}, - {"create", 0, 0, 0}, - {"file", 1, 0, 0}, - {0, 0, 0, 0} - }; - - c = getopt_long (argc, argv, "abc:d:0123456789", - long_options, &option_index); - if (c == -1) - break; - - switch (c) - { - case 0: - printf ("option %s", long_options[option_index].name); - if (optarg) - printf (" with arg %s", optarg); - printf ("\n"); - break; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value `%s'\n", optarg); - break; - - case 'd': - printf ("option d with value `%s'\n", optarg); - break; - - case '?': - break; - - default: - printf ("?? getopt returned character code 0%o ??\n", c); + int c; + int digit_optind = 0; + + while(1) { + int this_option_optind = optind ? optind : 1; + int option_index = 0; + static struct option long_options[] = { + {"add", 1, 0, 0}, + {"append", 0, 0, 0}, + {"delete", 1, 0, 0}, + {"verbose", 0, 0, 0}, + {"create", 0, 0, 0}, + {"file", 1, 0, 0}, + {0, 0, 0, 0} + }; + + c = getopt_long(argc, argv, "abc:d:0123456789", + long_options, &option_index); + + if(c == -1) { + break; + } + + switch(c) { + case 0: + printf("option %s", long_options[option_index].name); + + if(optarg) { + printf(" with arg %s", optarg); + } + + printf("\n"); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if(digit_optind != 0 && digit_optind != this_option_optind) { + printf("digits occur in two different argv-elements.\n"); + } + + digit_optind = this_option_optind; + printf("option %c\n", c); + break; + + case 'a': + printf("option a\n"); + break; + + case 'b': + printf("option b\n"); + break; + + case 'c': + printf("option c with value `%s'\n", optarg); + break; + + case 'd': + printf("option d with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf("?? getopt returned character code 0%o ??\n", c); + } } - } - if (optind < argc) - { - printf ("non-option ARGV-elements: "); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - } + if(optind < argc) { + printf("non-option ARGV-elements: "); - exit (0); + while(optind < argc) { + printf("%s ", argv[optind++]); + } + + printf("\n"); + } + + exit(0); } #endif /* TEST */ diff --git a/src/graph.c b/src/graph.c index e6cd011..a774eac 100644 --- a/src/graph.c +++ b/src/graph.c @@ -68,15 +68,17 @@ static void mst_kruskal(void) { /* Clear MST status on connections */ - for list_each(connection_t, c, connection_list) + for list_each(connection_t, c, connection_list) { c->status.mst = false; + } logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Running Kruskal's algorithm:"); /* Clear visited status on nodes */ - for splay_each(node_t, n, node_tree) + for splay_each(node_t, n, node_tree) { n->status.visited = false; + } /* Starting point */ @@ -100,11 +102,13 @@ static void mst_kruskal(void) { e->from->status.visited = true; e->to->status.visited = true; - if(e->connection) + if(e->connection) { e->connection->status.mst = true; + } - if(e->reverse->connection) + if(e->reverse->connection) { e->reverse->connection->status.mst = true; + } logger(DEBUG_SCARY_THINGS, LOG_DEBUG, " Adding edge %s - %s weight %d", e->from->name, e->to->name, e->weight); @@ -145,20 +149,22 @@ static void sssp_bfs(void) { for list_each(node_t, n, todo_list) { /* "n" is the node from which we start */ logger(DEBUG_SCARY_THINGS, LOG_DEBUG, " Examining edges from %s", n->name); - if(n->distance < 0) + if(n->distance < 0) { abort(); + } for splay_each(edge_t, e, n->edge_tree) { /* "e" is the edge connected to "from" */ - if(!e->reverse || e->to == myself) + if(!e->reverse || e->to == myself) { continue; + } /* Situation: - / - / + / + / ----->(n)---e-->(e->to) - \ - \ + \ + \ Where e is an edge, (n) and (e->to) are nodes. n->address is set to the e->address of the edge left of n to n. @@ -172,14 +178,16 @@ static void sssp_bfs(void) { bool indirect = n->status.indirect || e->options & OPTION_INDIRECT; if(e->to->status.visited - && (!e->to->status.indirect || indirect) - && (e->to->distance != n->distance + 1 || e->weight >= e->to->prevedge->weight)) + && (!e->to->status.indirect || indirect) + && (e->to->distance != n->distance + 1 || e->weight >= e->to->prevedge->weight)) { continue; + } // Only update nexthop if it doesn't increase the path length - if(!e->to->status.visited || (e->to->distance == n->distance + 1 && e->weight >= e->to->prevedge->weight)) + if(!e->to->status.visited || (e->to->distance == n->distance + 1 && e->weight >= e->to->prevedge->weight)) { e->to->nexthop = (n->nexthop == myself) ? e->to : n->nexthop; + } e->to->status.visited = true; e->to->status.indirect = indirect; @@ -188,8 +196,9 @@ static void sssp_bfs(void) { e->to->options = e->options; e->to->distance = n->distance + 1; - if(!e->to->status.reachable || (e->to->address.sa.sa_family == AF_UNSPEC && e->address.sa.sa_family != AF_UNKNOWN)) + if(!e->to->status.reachable || (e->to->address.sa.sa_family == AF_UNSPEC && e->address.sa.sa_family != AF_UNKNOWN)) { update_node_udp(e->to, &e->address); + } list_insert_tail(todo_list, e->to); } @@ -207,6 +216,7 @@ static void check_reachability(void) { int reachable_count = 0; int became_reachable_count = 0; int became_unreachable_count = 0; + for splay_each(node_t, n, node_tree) { if(n->status.visited != n->status.reachable) { n->status.reachable = !n->status.reachable; @@ -214,26 +224,33 @@ static void check_reachability(void) { if(n->status.reachable) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Node %s (%s) became reachable", - n->name, n->hostname); - if (n != myself) + n->name, n->hostname); + + if(n != myself) { became_reachable_count++; + } } else { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Node %s (%s) became unreachable", - n->name, n->hostname); - if (n != myself) + n->name, n->hostname); + + if(n != myself) { became_unreachable_count++; + } } - if(experimental && OPTION_VERSION(n->options) >= 2) + if(experimental && OPTION_VERSION(n->options) >= 2) { n->status.sptps = true; + } /* TODO: only clear status.validkey if node is unreachable? */ n->status.validkey = false; + if(n->status.sptps) { sptps_stop(&n->sptps); n->status.waitingforkey = false; } + n->last_req_key = 0; n->status.udp_confirmed = false; @@ -273,20 +290,23 @@ static void check_reachability(void) { n->options = 0; } else if(n->connection) { // Speed up UDP probing by sending our key. - if(!n->status.sptps) + if(!n->status.sptps) { send_ans_key(n); + } } } - if(n->status.reachable && n != myself) + if(n->status.reachable && n != myself) { reachable_count++; + } } - if (device_standby) { - if (reachable_count == 0 && became_unreachable_count > 0) + if(device_standby) { + if(reachable_count == 0 && became_unreachable_count > 0) { device_disable(); - else if (reachable_count > 0 && reachable_count == became_reachable_count) + } else if(reachable_count > 0 && reachable_count == became_reachable_count) { device_enable(); + } } } diff --git a/src/hash.c b/src/hash.c index f27b257..63b8f54 100644 --- a/src/hash.c +++ b/src/hash.c @@ -27,26 +27,34 @@ static uint32_t hash_function(const void *p, size_t len) { const uint8_t *q = p; uint32_t hash = 0; + while(true) { - for(int i = len > 4 ? 4 : len; --i;) + for(int i = len > 4 ? 4 : len; --i;) { hash += (uint32_t)q[len - i] << (8 * i); + } + hash *= 0x9e370001UL; // Golden ratio prime. - if(len <= 4) + + if(len <= 4) { break; + } + len -= 4; } + return hash; } /* Map 32 bits int onto 0..n-1, without throwing away too many bits if n is 2^8 or 2^16 */ static uint32_t modulo(uint32_t hash, size_t n) { - if(n == 0x100) + if(n == 0x100) { return (hash >> 24) ^ ((hash >> 16) & 0xff) ^ ((hash >> 8) & 0xff) ^ (hash & 0xff); - else if(n == 0x10000) + } else if(n == 0x10000) { return (hash >> 16) ^ (hash & 0xffff); - else + } else { return hash % n; + } } /* (De)allocation */ @@ -76,16 +84,21 @@ void hash_insert(hash_t *hash, const void *key, const void *value) { void *hash_search(const hash_t *hash, const void *key) { uint32_t i = modulo(hash_function(key, hash->size), hash->n); + if(hash->values[i] && !memcmp(key, hash->keys + i * hash->size, hash->size)) { return (void *)hash->values[i]; } + return NULL; } void *hash_search_or_insert(hash_t *hash, const void *key, const void *value) { uint32_t i = modulo(hash_function(key, hash->size), hash->n); - if(hash->values[i] && !memcmp(key, hash->keys + i * hash->size, hash->size)) + + if(hash->values[i] && !memcmp(key, hash->keys + i * hash->size, hash->size)) { return (void *)hash->values[i]; + } + memcpy(hash->keys + i * hash->size, key, hash->size); hash->values[i] = value; return NULL; @@ -107,6 +120,7 @@ void hash_clear(hash_t *hash) { void hash_resize(hash_t *hash, size_t n) { hash->keys = xrealloc(hash->keys, n * hash->size); hash->values = xrealloc(hash->values, n * sizeof(*hash->values)); + if(n > hash->n) { memset(hash->keys + hash->n * hash->size, 0, (n - hash->n) * hash->size); memset(hash->values + hash->n, 0, (n - hash->n) * sizeof(*hash->values)); diff --git a/src/hash.h b/src/hash.h index a5ae2e9..e4b1499 100644 --- a/src/hash.h +++ b/src/hash.h @@ -27,7 +27,7 @@ typedef struct hash_t { const void **values; } hash_t; -extern hash_t *hash_alloc(size_t n, size_t size) __attribute__ ((__malloc__)); +extern hash_t *hash_alloc(size_t n, size_t size) __attribute__((__malloc__)); extern void hash_free(hash_t *); extern void hash_insert(hash_t *, const void *key, const void *value); diff --git a/src/ifconfig.c b/src/ifconfig.c index c03fef4..f4b8453 100644 --- a/src/ifconfig.c +++ b/src/ifconfig.c @@ -88,36 +88,82 @@ static subnet_t ipv4, ipv6; void ifconfig_address(FILE *out, const char *value) { subnet_t address = {}; char address_str[MAXNETSTR]; + if(!str2net(&address, value) || !net2str(address_str, sizeof(address_str), &address)) { fprintf(stderr, "Could not parse address in Ifconfig statement\n"); return; } + switch(address.type) { - case SUBNET_IPV4: ipv4 = address; break; - case SUBNET_IPV6: ipv6 = address; break; - default: return; + case SUBNET_IPV4: + ipv4 = address; + break; + + case SUBNET_IPV6: + ipv6 = address; + break; + + default: + return; } + #if defined(HAVE_LINUX) + switch(address.type) { - case SUBNET_MAC: fprintf(out, "ip link set \"$INTERFACE\" address %s\n", address_str); break; - case SUBNET_IPV4: fprintf(out, "ip addr replace %s dev \"$INTERFACE\"\n", address_str); break; - case SUBNET_IPV6: fprintf(out, "ip addr replace %s dev \"$INTERFACE\"\n", address_str); break; - default: return; + case SUBNET_MAC: + fprintf(out, "ip link set \"$INTERFACE\" address %s\n", address_str); + break; + + case SUBNET_IPV4: + fprintf(out, "ip addr replace %s dev \"$INTERFACE\"\n", address_str); + break; + + case SUBNET_IPV6: + fprintf(out, "ip addr replace %s dev \"$INTERFACE\"\n", address_str); + break; + + default: + return; } + #elif defined(HAVE_MINGW) || defined(HAVE_CYGWIN) + switch(address.type) { - case SUBNET_MAC: fprintf(out, "ip link set \"$INTERFACE\" address %s\n", address_str); break; - case SUBNET_IPV4: fprintf(out, "netsh inetface ipv4 set address \"$INTERFACE\" static %s\n", address_str); break; - case SUBNET_IPV6: fprintf(out, "netsh inetface ipv6 set address \"$INTERFACE\" static %s\n", address_str); break; - default: return; + case SUBNET_MAC: + fprintf(out, "ip link set \"$INTERFACE\" address %s\n", address_str); + break; + + case SUBNET_IPV4: + fprintf(out, "netsh inetface ipv4 set address \"$INTERFACE\" static %s\n", address_str); + break; + + case SUBNET_IPV6: + fprintf(out, "netsh inetface ipv6 set address \"$INTERFACE\" static %s\n", address_str); + break; + + default: + return; } + #else // assume BSD + switch(address.type) { - case SUBNET_MAC: fprintf(out, "ifconfig \"$INTERFACE\" link %s\n", address_str); break; - case SUBNET_IPV4: fprintf(out, "ifconfig \"$INTERFACE\" %s\n", address_str); break; - case SUBNET_IPV6: fprintf(out, "ifconfig \"$INTERFACE\" inet6 %s\n", address_str); break; - default: return; + case SUBNET_MAC: + fprintf(out, "ifconfig \"$INTERFACE\" link %s\n", address_str); + break; + + case SUBNET_IPV4: + fprintf(out, "ifconfig \"$INTERFACE\" %s\n", address_str); + break; + + case SUBNET_IPV6: + fprintf(out, "ifconfig \"$INTERFACE\" inet6 %s\n", address_str); + break; + + default: + return; } + #endif } @@ -125,73 +171,134 @@ void ifconfig_route(FILE *out, const char *value) { subnet_t subnet = {}, gateway = {}; char subnet_str[MAXNETSTR] = "", gateway_str[MAXNETSTR] = ""; char *sep = strchr(value, ' '); - if(sep) + + if(sep) { *sep++ = 0; + } + if(!str2net(&subnet, value) || !net2str(subnet_str, sizeof(subnet_str), &subnet) || subnet.type == SUBNET_MAC) { fprintf(stderr, "Could not parse subnet in Route statement\n"); return; } + if(sep) { if(!str2net(&gateway, sep) || !net2str(gateway_str, sizeof(gateway_str), &gateway) || gateway.type != subnet.type) { fprintf(stderr, "Could not parse gateway in Route statement\n"); return; } - char *slash = strchr(gateway_str, '/'); if(slash) *slash = 0; + + char *slash = strchr(gateway_str, '/'); + + if(slash) { + *slash = 0; + } } + #if defined(HAVE_LINUX) + if(*gateway_str) { switch(subnet.type) { - case SUBNET_IPV4: fprintf(out, "ip route add %s via %s dev \"$INTERFACE\"\n", subnet_str, gateway_str); break; - case SUBNET_IPV6: fprintf(out, "ip route add %s via %s dev \"$INTERFACE\"\n", subnet_str, gateway_str); break; - default: return; + case SUBNET_IPV4: + fprintf(out, "ip route add %s via %s dev \"$INTERFACE\"\n", subnet_str, gateway_str); + break; + + case SUBNET_IPV6: + fprintf(out, "ip route add %s via %s dev \"$INTERFACE\"\n", subnet_str, gateway_str); + break; + + default: + return; } } else { switch(subnet.type) { - case SUBNET_IPV4: fprintf(out, "ip route add %s dev \"$INTERFACE\"\n", subnet_str); break; - case SUBNET_IPV6: fprintf(out, "ip route add %s dev \"$INTERFACE\"\n", subnet_str); break; - default: return; + case SUBNET_IPV4: + fprintf(out, "ip route add %s dev \"$INTERFACE\"\n", subnet_str); + break; + + case SUBNET_IPV6: + fprintf(out, "ip route add %s dev \"$INTERFACE\"\n", subnet_str); + break; + + default: + return; } } + #elif defined(HAVE_MINGW) || defined(HAVE_CYGWIN) + if(*gateway_str) { switch(subnet.type) { - case SUBNET_IPV4: fprintf(out, "netsh inetface ipv4 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str); break; - case SUBNET_IPV6: fprintf(out, "netsh inetface ipv6 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str); break; - default: return; + case SUBNET_IPV4: + fprintf(out, "netsh inetface ipv4 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str); + break; + + case SUBNET_IPV6: + fprintf(out, "netsh inetface ipv6 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str); + break; + + default: + return; } } else { switch(subnet.type) { - case SUBNET_IPV4: fprintf(out, "netsh inetface ipv4 add route %s \"%%INTERFACE%%\"\n", subnet_str); break; - case SUBNET_IPV6: fprintf(out, "netsh inetface ipv6 add route %s \"%%INTERFACE%%\"\n", subnet_str); break; - default: return; + case SUBNET_IPV4: + fprintf(out, "netsh inetface ipv4 add route %s \"%%INTERFACE%%\"\n", subnet_str); + break; + + case SUBNET_IPV6: + fprintf(out, "netsh inetface ipv6 add route %s \"%%INTERFACE%%\"\n", subnet_str); + break; + + default: + return; } } + #else // assume BSD + if(!*gateway_str) { switch(subnet.type) { - case SUBNET_IPV4: - if(!ipv4.type) { - fprintf(stderr, "Route requested but no Ifconfig\n"); - return; - } - net2str(gateway_str, sizeof(gateway_str), &ipv4); - break; - case SUBNET_IPV6: - if(!ipv6.type) { - fprintf(stderr, "Route requested but no Ifconfig\n"); - return; - } - net2str(gateway_str, sizeof(gateway_str), &ipv6); - break; - default: return; + case SUBNET_IPV4: + if(!ipv4.type) { + fprintf(stderr, "Route requested but no Ifconfig\n"); + return; + } + + net2str(gateway_str, sizeof(gateway_str), &ipv4); + break; + + case SUBNET_IPV6: + if(!ipv6.type) { + fprintf(stderr, "Route requested but no Ifconfig\n"); + return; + } + + net2str(gateway_str, sizeof(gateway_str), &ipv6); + break; + + default: + return; + } + + char *slash = strchr(gateway_str, '/'); + + if(slash) { + *slash = 0; } - char *slash = strchr(gateway_str, '/'); if(slash) *slash = 0; } switch(subnet.type) { - case SUBNET_IPV4: fprintf(out, "route add %s %s\n", subnet_str, gateway_str); break; - case SUBNET_IPV6: fprintf(out, "route add -inet6 %s %s\n", subnet_str, gateway_str); break; - default: return; + case SUBNET_IPV4: + fprintf(out, "route add %s %s\n", subnet_str, gateway_str); + break; + + case SUBNET_IPV6: + fprintf(out, "route add -inet6 %s %s\n", subnet_str, gateway_str); + break; + + default: + return; } + #endif } diff --git a/src/info.c b/src/info.c index b552574..09e6580 100644 --- a/src/info.c +++ b/src/info.c @@ -37,8 +37,11 @@ void logger(int level, int priority, const char *format, ...) { char *strip_weight(char *netstr) { int len = strlen(netstr); - if(len >= 3 && !strcmp(netstr + len - 3, "#10")) + + if(len >= 3 && !strcmp(netstr + len - 3, "#10")) { netstr[len - 3] = 0; + } + return netstr; } @@ -71,8 +74,9 @@ static int info_node(int fd, const char *item) { while(recvline(fd, line, sizeof(line))) { int n = sscanf(line, "%d %d %4095s %4095s %4095s port %4095s %d %d %d %d %x %"PRIx32" %4095s %4095s %d %hd %hd %hd %ld", &code, &req, node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_union.raw, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change); - if(n == 2) + if(n == 2) { break; + } if(n != 19) { fprintf(stderr, "Unable to parse node dump from tincd.\n"); @@ -91,8 +95,9 @@ static int info_node(int fd, const char *item) { } while(recvline(fd, line, sizeof(line))) { - if(sscanf(line, "%d %d %4095s", &code, &req, node) == 2) + if(sscanf(line, "%d %d %4095s", &code, &req, node) == 2) { break; + } } printf("Node: %s\n", item); @@ -102,88 +107,128 @@ static int info_node(int fd, const char *item) { char timestr[32] = "never"; time_t lsc_time = last_state_change; - if(last_state_change) + if(last_state_change) { strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", localtime(&lsc_time)); + } status = status_union.bits; - if(status.reachable) + if(status.reachable) { printf("Online since: %s\n", timestr); - else + } else { printf("Last seen: %s\n", timestr); + } printf("Status: "); - if(status.validkey) + + if(status.validkey) { printf(" validkey"); - if(status.visited) + } + + if(status.visited) { printf(" visited"); - if(status.reachable) + } + + if(status.reachable) { printf(" reachable"); - if(status.indirect) + } + + if(status.indirect) { printf(" indirect"); - if(status.sptps) + } + + if(status.sptps) { printf(" sptps"); - if(status.udp_confirmed) + } + + if(status.udp_confirmed) { printf(" udp_confirmed"); + } + printf("\n"); printf("Options: "); - if(options & OPTION_INDIRECT) + + if(options & OPTION_INDIRECT) { printf(" indirect"); - if(options & OPTION_TCPONLY) + } + + if(options & OPTION_TCPONLY) { printf(" tcponly"); - if(options & OPTION_PMTU_DISCOVERY) + } + + if(options & OPTION_PMTU_DISCOVERY) { printf(" pmtu_discovery"); - if(options & OPTION_CLAMP_MSS) + } + + if(options & OPTION_CLAMP_MSS) { printf(" clamp_mss"); + } + printf("\n"); printf("Protocol: %d.%d\n", PROT_MAJOR, OPTION_VERSION(options)); printf("Reachability: "); - if(!strcmp(host, "MYSELF")) + + if(!strcmp(host, "MYSELF")) { printf("can reach itself\n"); - else if(!status.reachable) + } else if(!status.reachable) { printf("unreachable\n"); - else if(strcmp(via, item)) + } else if(strcmp(via, item)) { printf("indirectly via %s\n", via); - else if(!status.validkey) + } else if(!status.validkey) { printf("unknown\n"); - else if(minmtu > 0) + } else if(minmtu > 0) { printf("directly with UDP\nPMTU: %d\n", pmtu); - else if(!strcmp(nexthop, item)) + } else if(!strcmp(nexthop, item)) { printf("directly with TCP\n"); - else + } else { printf("none, forwarded via %s\n", nexthop); + } // List edges printf("Edges: "); sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_EDGES, item); + while(recvline(fd, line, sizeof(line))) { int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, from, to); - if(n == 2) + + if(n == 2) { break; + } + if(n != 4) { fprintf(stderr, "Unable to parse edge dump from tincd.\n%s\n", line); return 1; } - if(!strcmp(from, item)) + + if(!strcmp(from, item)) { printf(" %s", to); + } } + printf("\n"); // List subnets printf("Subnets: "); sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_SUBNETS, item); + while(recvline(fd, line, sizeof(line))) { int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, subnet, from); - if(n == 2) + + if(n == 2) { break; + } + if(n != 4) { fprintf(stderr, "Unable to parse subnet dump from tincd.\n"); return 1; } - if(!strcmp(from, item)) + + if(!strcmp(from, item)) { printf(" %s", strip_weight(subnet)); + } } + printf("\n"); return 0; @@ -208,47 +253,63 @@ static int info_subnet(int fd, const char *item) { int code, req; sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_SUBNETS, item); + while(recvline(fd, line, sizeof(line))) { int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, netstr, owner); - if(n == 2) + + if(n == 2) { break; + } if(n != 4 || !str2net(&subnet, netstr)) { fprintf(stderr, "Unable to parse subnet dump from tincd.\n"); return 1; } - if(find.type != subnet.type) + if(find.type != subnet.type) { continue; + } if(weight) { - if(find.weight != subnet.weight) + if(find.weight != subnet.weight) { continue; + } } if(find.type == SUBNET_IPV4) { if(address) { - if(maskcmp(&find.net.ipv4.address, &subnet.net.ipv4.address, subnet.net.ipv4.prefixlength)) + if(maskcmp(&find.net.ipv4.address, &subnet.net.ipv4.address, subnet.net.ipv4.prefixlength)) { continue; + } } else { - if(find.net.ipv4.prefixlength != subnet.net.ipv4.prefixlength) + if(find.net.ipv4.prefixlength != subnet.net.ipv4.prefixlength) { continue; - if(memcmp(&find.net.ipv4.address, &subnet.net.ipv4.address, sizeof(subnet.net.ipv4))) + } + + if(memcmp(&find.net.ipv4.address, &subnet.net.ipv4.address, sizeof(subnet.net.ipv4))) { continue; + } } } else if(find.type == SUBNET_IPV6) { if(address) { - if(maskcmp(&find.net.ipv6.address, &subnet.net.ipv6.address, subnet.net.ipv6.prefixlength)) + if(maskcmp(&find.net.ipv6.address, &subnet.net.ipv6.address, subnet.net.ipv6.prefixlength)) { continue; + } } else { - if(find.net.ipv6.prefixlength != subnet.net.ipv6.prefixlength) + if(find.net.ipv6.prefixlength != subnet.net.ipv6.prefixlength) { continue; - if(memcmp(&find.net.ipv6.address, &subnet.net.ipv6.address, sizeof(subnet.net.ipv6))) + } + + if(memcmp(&find.net.ipv6.address, &subnet.net.ipv6.address, sizeof(subnet.net.ipv6))) { continue; + } } - } if(find.type == SUBNET_MAC) { - if(memcmp(&find.net.mac.address, &subnet.net.mac.address, sizeof(subnet.net.mac))) + } + + if(find.type == SUBNET_MAC) { + if(memcmp(&find.net.mac.address, &subnet.net.mac.address, sizeof(subnet.net.mac))) { continue; + } } found = true; @@ -257,10 +318,12 @@ static int info_subnet(int fd, const char *item) { } if(!found) { - if(address) + if(address) { fprintf(stderr, "Unknown address %s.\n", item); - else + } else { fprintf(stderr, "Unknown subnet %s.\n", item); + } + return 1; } @@ -268,10 +331,13 @@ static int info_subnet(int fd, const char *item) { } int info(int fd, const char *item) { - if(check_id(item)) + if(check_id(item)) { return info_node(fd, item); - if(strchr(item, '.') || strchr(item, ':')) + } + + if(strchr(item, '.') || strchr(item, ':')) { return info_subnet(fd, item); + } fprintf(stderr, "Argument is not a node name, subnet or address.\n"); return 1; diff --git a/src/invitation.c b/src/invitation.c index 2990c47..bcb79a4 100644 --- a/src/invitation.c +++ b/src/invitation.c @@ -40,27 +40,41 @@ int addressfamily = AF_UNSPEC; static void scan_for_hostname(const char *filename, char **hostname, char **port) { - if(!filename || (*hostname && *port)) + if(!filename || (*hostname && *port)) { return; + } FILE *f = fopen(filename, "r"); - if(!f) + + if(!f) { return; + } while(fgets(line, sizeof(line), f)) { - if(!rstrip(line)) + if(!rstrip(line)) { continue; + } + char *p = line, *q; p += strcspn(p, "\t ="); - if(!*p) + + if(!*p) { continue; + } + q = p + strspn(p, "\t "); - if(*q == '=') + + if(*q == '=') { q += 1 + strspn(q + 1, "\t "); + } + *p = 0; p = q + strcspn(q, "\t "); - if(*p) + + if(*p) { *p++ = 0; + } + p += strspn(p, "\t "); p[strcspn(p, "\t ")] = 0; @@ -68,14 +82,16 @@ static void scan_for_hostname(const char *filename, char **hostname, char **port *port = xstrdup(q); } else if(!*hostname && !strcasecmp(line, "Address")) { *hostname = xstrdup(q); + if(*p) { free(*port); *port = xstrdup(p); } } - if(*hostname && *port) + if(*hostname && *port) { break; + } } fclose(f); @@ -95,8 +111,9 @@ char *get_my_hostname() { scan_for_hostname(tinc_conf, &hostname, &port); } - if(hostname) + if(hostname) { goto done; + } // If that doesn't work, guess externally visible hostname fprintf(stderr, "Trying to discover externally visible hostname...\n"); @@ -106,39 +123,54 @@ char *get_my_hostname() { while(aip) { int s = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol); + if(s >= 0) { if(connect(s, aip->ai_addr, aip->ai_addrlen)) { closesocket(s); s = -1; } } + if(s >= 0) { send(s, request, sizeof(request) - 1, 0); int len = recv(s, line, sizeof(line) - 1, MSG_WAITALL); + if(len > 0) { line[len] = 0; - if(line[len - 1] == '\n') + + if(line[len - 1] == '\n') { line[--len] = 0; + } + char *p = strrchr(line, '\n'); - if(p && p[1]) + + if(p && p[1]) { hostname = xstrdup(p + 1); + } } + closesocket(s); - if(hostname) + + if(hostname) { break; + } } + aip = aip->ai_next; continue; } - if(ai) + if(ai) { freeaddrinfo(ai); + } // Check that the hostname is reasonable if(hostname) { for(char *p = hostname; *p; p++) { - if(isalnum(*p) || *p == '-' || *p == '.' || *p == ':') + if(isalnum(*p) || *p == '-' || *p == '.' || *p == ':') { continue; + } + // If not, forget it. free(hostname); hostname = NULL; @@ -151,13 +183,17 @@ char *get_my_hostname() { fprintf(stderr, "Could not determine the external address or hostname. Please set Address manually.\n"); return NULL; } + goto save; } again: fprintf(stderr, "Please enter your host's external address or hostname"); - if(hostname) + + if(hostname) { fprintf(stderr, " [%s]", hostname); + } + fprintf(stderr, ": "); if(!fgets(line, sizeof(line), stdin)) { @@ -167,15 +203,18 @@ again: } if(!rstrip(line)) { - if(hostname) + if(hostname) { goto save; - else + } else { goto again; + } } for(char *p = line; *p; p++) { - if(isalnum(*p) || *p == '-' || *p == '.') + if(isalnum(*p) || *p == '-' || *p == '.') { continue; + } + fprintf(stderr, "Invalid address or hostname.\n"); goto again; } @@ -184,8 +223,10 @@ again: hostname = xstrdup(line); save: + if(*filename) { FILE *f = fopen(filename, "a"); + if(f) { fprintf(f, "\nAddress = %s\n", hostname); fclose(f); @@ -195,16 +236,19 @@ save: } done: + if(port) { - if(strchr(hostname, ':')) + if(strchr(hostname, ':')) { xasprintf(&hostport, "[%s]:%s", hostname, port); - else + } else { xasprintf(&hostport, "%s:%s", hostname, port); + } } else { - if(strchr(hostname, ':')) + if(strchr(hostname, ':')) { xasprintf(&hostport, "[%s]", hostname); - else + } else { hostport = xstrdup(hostname); + } } free(hostname); @@ -214,6 +258,7 @@ done: static bool fcopy(FILE *out, const char *filename) { FILE *in = fopen(filename, "r"); + if(!in) { fprintf(stderr, "Could not open %s: %s\n", filename, strerror(errno)); return false; @@ -221,8 +266,11 @@ static bool fcopy(FILE *out, const char *filename) { char buf[1024]; size_t len; - while((len = fread(buf, 1, sizeof(buf), in))) + + while((len = fread(buf, 1, sizeof(buf), in))) { fwrite(buf, len, 1, out); + } + fclose(in); return true; } @@ -240,12 +288,15 @@ int cmd_invite(int argc, char *argv[]) { } myname = get_my_name(true); - if(!myname) + + if(!myname) { return 1; + } // Ensure no host configuration file with that name exists char filename[PATH_MAX]; snprintf(filename, sizeof(filename), "%s" SLASH "hosts" SLASH "%s", confbase, argv[1]); + if(!access(filename, F_OK)) { fprintf(stderr, "A host config file for %s already exists!\n", argv[1]); return 1; @@ -259,10 +310,14 @@ int cmd_invite(int argc, char *argv[]) { while(recvline(fd, line, sizeof(line))) { char node[4096]; int code, req; - if(sscanf(line, "%d %d %4095s", &code, &req, node) != 3) + + if(sscanf(line, "%d %d %4095s", &code, &req, node) != 3) { break; - if(!strcmp(node, argv[1])) + } + + if(!strcmp(node, argv[1])) { found = true; + } } if(found) { @@ -272,6 +327,7 @@ int cmd_invite(int argc, char *argv[]) { } snprintf(filename, sizeof(filename), "%s" SLASH "invitations", confbase); + if(mkdir(filename, 0700) && errno != EEXIST) { fprintf(stderr, "Could not create directory %s: %s\n", filename, strerror(errno)); return 1; @@ -279,6 +335,7 @@ int cmd_invite(int argc, char *argv[]) { // Count the number of valid invitations, clean up old ones DIR *dir = opendir(filename); + if(!dir) { fprintf(stderr, "Could not read directory %s: %s\n", filename, strerror(errno)); return 1; @@ -290,16 +347,20 @@ int cmd_invite(int argc, char *argv[]) { time_t deadline = time(NULL) - 604800; // 1 week in the past while((ent = readdir(dir))) { - if(strlen(ent->d_name) != 24) + if(strlen(ent->d_name) != 24) { continue; + } + char invname[PATH_MAX]; struct stat st; snprintf(invname, sizeof(invname), "%s" SLASH "%s", filename, ent->d_name); + if(!stat(invname, &st)) { - if(deadline < st.st_mtime) + if(deadline < st.st_mtime) { count++; - else + } else { unlink(invname); + } } else { fprintf(stderr, "Could not stat %s: %s\n", invname, strerror(errno)); errno = 0; @@ -312,16 +373,18 @@ int cmd_invite(int argc, char *argv[]) { fprintf(stderr, "Error while reading directory %s: %s\n", filename, strerror(errno)); return 1; } - + ecdsa_t *key; snprintf(filename, sizeof(filename), "%s" SLASH "invitations" SLASH "ed25519_key.priv", confbase); // Remove the key if there are no outstanding invitations. - if(!count) + if(!count) { unlink(filename); + } // Create a new key if necessary. FILE *f = fopen(filename, "r"); + if(!f) { if(errno != ENOENT) { fprintf(stderr, "Could not read %s: %s\n", filename, strerror(errno)); @@ -329,32 +392,43 @@ int cmd_invite(int argc, char *argv[]) { } key = ecdsa_generate(); - if(!key) + + if(!key) { return 1; + } + f = fopen(filename, "w"); + if(!f) { fprintf(stderr, "Could not write %s: %s\n", filename, strerror(errno)); return 1; } + chmod(filename, 0600); + if(!ecdsa_write_pem_private_key(key, f)) { fprintf(stderr, "Could not write ECDSA private key\n"); fclose(f); return 1; } + fclose(f); - if(connect_tincd(false)) + if(connect_tincd(false)) { sendline(fd, "%d %d", CONTROL, REQ_RELOAD); + } } else { key = ecdsa_read_pem_private_key(f); fclose(f); - if(!key) + + if(!key) { fprintf(stderr, "Could not read private key from %s\n", filename); + } } - if(!key) + if(!key) { return 1; + } // Create a hash of the key. char hash[64]; @@ -379,36 +453,48 @@ int cmd_invite(int argc, char *argv[]) { // Create a file containing the details of the invitation. snprintf(filename, sizeof(filename), "%s" SLASH "invitations" SLASH "%s", confbase, cookiehash); int ifd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600); + if(!ifd) { fprintf(stderr, "Could not create invitation file %s: %s\n", filename, strerror(errno)); return 1; } + f = fdopen(ifd, "w"); - if(!f) + + if(!f) { abort(); + } // Get the local address char *address = get_my_hostname(); // Fill in the details. fprintf(f, "Name = %s\n", argv[1]); - if(check_netname(netname, true)) + + if(check_netname(netname, true)) { fprintf(f, "NetName = %s\n", netname); + } + fprintf(f, "ConnectTo = %s\n", myname); // Copy Broadcast and Mode FILE *tc = fopen(tinc_conf, "r"); + if(tc) { char buf[1024]; + while(fgets(buf, sizeof(buf), tc)) { if((!strncasecmp(buf, "Mode", 4) && strchr(" \t=", buf[4])) - || (!strncasecmp(buf, "Broadcast", 9) && strchr(" \t=", buf[9]))) { + || (!strncasecmp(buf, "Broadcast", 9) && strchr(" \t=", buf[9]))) { fputs(buf, f); + // Make sure there is a newline character. - if(!strchr(buf, '\n')) + if(!strchr(buf, '\n')) { fputc('\n', f); + } } } + fclose(tc); } @@ -450,10 +536,11 @@ static bool success = false; static char cookie[18], hash[18]; static char *get_line(const char **data) { - if(!data || !*data) + if(!data || !*data) { return NULL; + } - if(!**data) { + if(! **data) { *data = NULL; return NULL; } @@ -461,36 +548,48 @@ static char *get_line(const char **data) { static char line[1024]; const char *end = strchr(*data, '\n'); size_t len = end ? end - *data : strlen(*data); + if(len >= sizeof(line)) { fprintf(stderr, "Maximum line length exceeded!\n"); return NULL; } - if(len && !isprint(**data)) + + if(len && !isprint(**data)) { abort(); + } memcpy(line, *data, len); line[len] = 0; - if(end) + if(end) { *data = end + 1; - else + } else { *data = NULL; + } return line; } static char *get_value(const char *data, const char *var) { char *line = get_line(&data); - if(!line) + + if(!line) { return NULL; + } char *sep = line + strcspn(line, " \t="); char *val = sep + strspn(sep, " \t"); - if(*val == '=') + + if(*val == '=') { val += 1 + strspn(val + 1, " \t"); + } + *sep = 0; - if(strcasecmp(line, var)) + + if(strcasecmp(line, var)) { return NULL; + } + return val; } @@ -503,23 +602,30 @@ static char *grep(const char *data, const char *var) { // Skip all lines not starting with var while(strncasecmp(p, var, varlen) || !strchr(" \t=", p[varlen])) { p = strchr(p, '\n'); - if(!p) + + if(!p) { break; - else + } else { p++; + } } - if(!p) + if(!p) { return NULL; + } p += varlen; p += strspn(p, " \t"); - if(*p == '=') + + if(*p == '=') { p += 1 + strspn(p + 1, " \t"); + } const char *e = strchr(p, '\n'); - if(!e) + + if(!e) { return xstrdup(p); + } if(e - p >= sizeof(value)) { fprintf(stderr, "Maximum line length exceeded!\n"); @@ -533,6 +639,7 @@ static char *grep(const char *data, const char *var) { static bool finalize_join(void) { char *name = xstrdup(get_value(data, "Name")); + if(!name) { fprintf(stderr, "No Name found in invitation!\n"); return false; @@ -545,6 +652,7 @@ static bool finalize_join(void) { if(!netname) { netname = grep(data, "NetName"); + if(netname && !check_netname(netname, true)) { fprintf(stderr, "Unsafe NetName found in invitation!\n"); return false; @@ -555,6 +663,7 @@ static bool finalize_join(void) { char temp_netname[32]; make_names: + if(!confbasegiven) { free(confbase); confbase = NULL; @@ -570,15 +679,17 @@ make_names: if(!access(tinc_conf, F_OK)) { fprintf(stderr, "Configuration file %s already exists!\n", tinc_conf); - if(confbasegiven) + + if(confbasegiven) { return false; + } // Generate a random netname, ask for a better one later. ask_netname = true; snprintf(temp_netname, sizeof(temp_netname), "join_%x", rand()); netname = temp_netname; goto make_names; - } + } if(mkdir(confbase, 0777) && errno != EEXIST) { fprintf(stderr, "Could not create directory %s: %s\n", confbase, strerror(errno)); @@ -591,6 +702,7 @@ make_names: } FILE *f = fopen(tinc_conf, "w"); + if(!f) { fprintf(stderr, "Could not create file %s: %s\n", tinc_conf, strerror(errno)); return false; @@ -601,6 +713,7 @@ make_names: char filename[PATH_MAX]; snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, name); FILE *fh = fopen(filename, "w"); + if(!fh) { fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno)); fclose(f); @@ -609,6 +722,7 @@ make_names: snprintf(filename, sizeof(filename), "%s" SLASH "invitation-data", confbase); FILE *finv = fopen(filename, "w"); + if(!finv || fwrite(data, datalen, 1, finv) != 1) { fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno)); fclose(fh); @@ -616,10 +730,12 @@ make_names: fclose(finv); return false; } + fclose(finv); snprintf(filename, sizeof(filename), "%s" SLASH "tinc-up.invitation", confbase); FILE *fup = fopen(filename, "w"); + if(!fup) { fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno)); fclose(f); @@ -637,34 +753,41 @@ make_names: while((l = get_line(&p))) { // Ignore comments - if(*l == '#') + if(*l == '#') { continue; + } // Split line into variable and value int len = strcspn(l, "\t ="); value = l + len; value += strspn(value, "\t "); + if(*value == '=') { value++; value += strspn(value, "\t "); } + l[len] = 0; // Is it a Name? if(!strcasecmp(l, "Name")) - if(strcmp(value, name)) + if(strcmp(value, name)) { break; - else + } else { continue; - else if(!strcasecmp(l, "NetName")) + } else if(!strcasecmp(l, "NetName")) { continue; + } // Check the list of known variables bool found = false; int i; + for(i = 0; variables[i].name; i++) { - if(strcasecmp(l, variables[i].name)) + if(strcasecmp(l, variables[i].name)) { continue; + } + found = true; break; } @@ -672,14 +795,16 @@ make_names: // Handle Ifconfig and Route statements if(!found) { if(!strcasecmp(l, "Ifconfig")) { - if(!strcasecmp(value, "dhcp")) + if(!strcasecmp(value, "dhcp")) { ifconfig_dhcp(fup); - else if(!strcasecmp(value, "dhcp6")) + } else if(!strcasecmp(value, "dhcp6")) { ifconfig_dhcp6(fup); - else if(!strcasecmp(value, "slaac")) + } else if(!strcasecmp(value, "slaac")) { ifconfig_slaac(fup); - else + } else { ifconfig_address(fup, value); + } + continue; } else if(!strcasecmp(l, "Route")) { ifconfig_route(fup, value); @@ -724,16 +849,21 @@ make_names: } while((l = get_line(&p))) { - if(!strcmp(l, "#---------------------------------------------------------------#")) + if(!strcmp(l, "#---------------------------------------------------------------#")) { continue; + } + int len = strcspn(l, "\t ="); + if(len == 4 && !strncasecmp(l, "Name", 4)) { value = l + len; value += strspn(value, "\t "); + if(*value == '=') { value++; value += strspn(value, "\t "); } + l[len] = 0; break; } @@ -747,17 +877,23 @@ make_names: // Generate our key and send a copy to the server ecdsa_t *key = ecdsa_generate(); - if(!key) + + if(!key) { return false; + } char *b64key = ecdsa_get_base64_public_key(key); - if(!b64key) + + if(!b64key) { return false; + } snprintf(filename, sizeof(filename), "%s" SLASH "ed25519_key.priv", confbase); f = fopenmask(filename, "w", 0600); - if(!f) + + if(!f) { return false; + } if(!ecdsa_write_pem_private_key(key, f)) { fprintf(stderr, "Error writing private key!\n"); @@ -795,19 +931,24 @@ make_names: check_port(name); ask_netname: + if(ask_netname && tty) { fprintf(stderr, "Enter a new netname: "); + if(!fgets(line, sizeof(line), stdin)) { fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno)); return false; } - if(!*line || *line == '\n') + + if(!*line || *line == '\n') { goto ask_netname; + } line[strlen(line) - 1] = 0; char newbase[PATH_MAX]; snprintf(newbase, sizeof(newbase), CONFDIR SLASH "tinc" SLASH "%s", line); + if(rename(confbase, newbase)) { fprintf(stderr, "Error trying to rename %s to %s: %s\n", confbase, newbase, strerror(errno)); goto ask_netname; @@ -824,15 +965,20 @@ ask_netname: if(valid_tinc_up) { if(tty) { FILE *fup = fopen(filename, "r"); + if(fup) { fprintf(stderr, "\nPlease review the following tinc-up script:\n\n"); char buf[MAXSIZE]; - while(fgets(buf, sizeof(buf), fup)) + + while(fgets(buf, sizeof(buf), fup)) { fputs(buf, stderr); + } + fclose(fup); int response = 0; + do { fprintf(stderr, "\nDo you want to use this script [y]es/[n]o/[e]dit? "); response = tolower(getchar()); @@ -843,14 +989,17 @@ ask_netname: if(response == 'e') { char *command; #ifndef HAVE_MINGW - xasprintf(&command, "\"%s\" \"%s\"", getenv("VISUAL") ?: getenv("EDITOR") ?: "vi", filename); + xasprintf(&command, "\"%s\" \"%s\"", getenv("VISUAL") ? : getenv("EDITOR") ? : "vi", filename); #else xasprintf(&command, "edit \"%s\"", filename); #endif - if(system(command)) + + if(system(command)) { response = 'n'; - else + } else { response = 'y'; + } + free(command); } @@ -880,39 +1029,43 @@ ask_netname: static bool invitation_send(void *handle, uint8_t type, const void *data, size_t len) { while(len) { int result = send(sock, data, len, 0); - if(result == -1 && errno == EINTR) + + if(result == -1 && errno == EINTR) { continue; - else if(result <= 0) + } else if(result <= 0) { return false; + } + data += result; len -= result; } + return true; } static bool invitation_receive(void *handle, uint8_t type, const void *msg, uint16_t len) { switch(type) { - case SPTPS_HANDSHAKE: - return sptps_send_record(&sptps, 0, cookie, sizeof(cookie)); - - case 0: - data = xrealloc(data, datalen + len + 1); - memcpy(data + datalen, msg, len); - datalen += len; - data[datalen] = 0; - break; - - case 1: - return finalize_join(); - - case 2: - fprintf(stderr, "Invitation succesfully accepted.\n"); - shutdown(sock, SHUT_RDWR); - success = true; - break; - - default: - return false; + case SPTPS_HANDSHAKE: + return sptps_send_record(&sptps, 0, cookie, sizeof(cookie)); + + case 0: + data = xrealloc(data, datalen + len + 1); + memcpy(data + datalen, msg, len); + datalen += len; + data[datalen] = 0; + break; + + case 1: + return finalize_join(); + + case 2: + fprintf(stderr, "Invitation succesfully accepted.\n"); + shutdown(sock, SHUT_RDWR); + success = true; + break; + + default: + return false; } return true; @@ -956,13 +1109,17 @@ int cmd_join(int argc, char *argv[]) { if(argc > 1) { invitation = argv[1]; } else { - if(tty) + if(tty) { fprintf(stderr, "Enter invitation URL: "); + } + errno = EPIPE; + if(!fgets(line, sizeof(line), stdin)) { fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno)); return false; } + invitation = line; } @@ -970,60 +1127,80 @@ int cmd_join(int argc, char *argv[]) { rstrip(line); char *slash = strchr(invitation, '/'); - if(!slash) + + if(!slash) { goto invalid; + } *slash++ = 0; - if(strlen(slash) != 48) + if(strlen(slash) != 48) { goto invalid; + } char *address = invitation; char *port = NULL; + if(*address == '[') { address++; char *bracket = strchr(address, ']'); - if(!bracket) + + if(!bracket) { goto invalid; + } + *bracket = 0; - if(bracket[1] == ':') + + if(bracket[1] == ':') { port = bracket + 2; + } } else { port = strchr(address, ':'); - if(port) + + if(port) { *port++ = 0; + } } - if(!port || !*port) + if(!port || !*port) { port = "655"; + } - if(!b64decode(slash, hash, 24) || !b64decode(slash + 24, cookie, 24)) + if(!b64decode(slash, hash, 24) || !b64decode(slash + 24, cookie, 24)) { goto invalid; + } // Generate a throw-away key for the invitation. ecdsa_t *key = ecdsa_generate(); - if(!key) + + if(!key) { return 1; + } char *b64key = ecdsa_get_base64_public_key(key); // Connect to the tinc daemon mentioned in the URL. struct addrinfo *ai = str2addrinfo(address, port, SOCK_STREAM); - if(!ai) + + if(!ai) { return 1; + } struct addrinfo *aip = NULL; next: - if(!aip) + if(!aip) { aip = ai; - else { + } else { aip = aip->ai_next; - if(!aip) + + if(!aip) { return 1; + } } sock = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol); + if(sock <= 0) { fprintf(stderr, "Could not open socket: %s\n", strerror(errno)); goto next; @@ -1043,8 +1220,10 @@ next: // Tell him we have an invitation, and give him our throw-away key. int len = snprintf(line, sizeof(line), "0 ?%s %d.%d\n", b64key, PROT_MAJOR, PROT_MINOR); - if(len <= 0 || len >= sizeof(line)) + + if(len <= 0 || len >= sizeof(line)) { abort(); + } if(!sendline(sock, "0 ?%s %d.%d", b64key, PROT_MAJOR, 1)) { fprintf(stderr, "Error sending request to %s port %s: %s\n", address, port, strerror(errno)); @@ -1064,46 +1243,58 @@ next: // Check if the hash of the key he gave us matches the hash in the URL. char *fingerprint = line + 2; char hishash[64]; + if(sha512(fingerprint, strlen(fingerprint), hishash)) { fprintf(stderr, "Could not create digest\n%s\n", line + 2); return 1; } + if(memcmp(hishash, hash, 18)) { fprintf(stderr, "Peer has an invalid key!\n%s\n", line + 2); return 1; } - + ecdsa_t *hiskey = ecdsa_set_base64_public_key(fingerprint); - if(!hiskey) + + if(!hiskey) { return 1; + } // Start an SPTPS session - if(!sptps_start(&sptps, NULL, true, false, key, hiskey, "tinc invitation", 15, invitation_send, invitation_receive)) + if(!sptps_start(&sptps, NULL, true, false, key, hiskey, "tinc invitation", 15, invitation_send, invitation_receive)) { return 1; + } // Feed rest of input buffer to SPTPS - if(!sptps_receive_data(&sptps, buffer, blen)) + if(!sptps_receive_data(&sptps, buffer, blen)) { return 1; + } while((len = recv(sock, line, sizeof(line), 0))) { if(len < 0) { - if(errno == EINTR) + if(errno == EINTR) { continue; + } + fprintf(stderr, "Error reading data from %s port %s: %s\n", address, port, strerror(errno)); return 1; } char *p = line; + while(len) { int done = sptps_receive_data(&sptps, p, len); - if(!done) + + if(!done) { return 1; + } + len -= done; p += done; } } - + sptps_stop(&sptps); ecdsa_free(hiskey); ecdsa_free(key); diff --git a/src/ipv4.h b/src/ipv4.h index 7ad7e01..1e34ccb 100644 --- a/src/ipv4.h +++ b/src/ipv4.h @@ -64,11 +64,11 @@ #ifndef HAVE_STRUCT_IP struct ip { #if __BYTE_ORDER == __LITTLE_ENDIAN - unsigned int ip_hl:4; - unsigned int ip_v:4; + unsigned int ip_hl: 4; + unsigned int ip_v: 4; #else - unsigned int ip_v:4; - unsigned int ip_hl:4; + unsigned int ip_v: 4; + unsigned int ip_hl: 4; #endif uint8_t ip_tos; uint16_t ip_len; @@ -81,7 +81,7 @@ struct ip { uint8_t ip_p; uint16_t ip_sum; struct in_addr ip_src, ip_dst; -} __attribute__ ((__gcc_struct__, __packed__)); +} __attribute__((__gcc_struct__, __packed__)); #endif #ifndef IP_OFFMASK @@ -143,7 +143,7 @@ struct icmp { #define icmp_radv icmp_dun.id_radv #define icmp_mask icmp_dun.id_mask #define icmp_data icmp_dun.id_data -} __attribute__ ((__gcc_struct__, __packed__)); +} __attribute__((__gcc_struct__, __packed__)); #endif #endif diff --git a/src/ipv6.h b/src/ipv6.h index b57ba74..4d5173f 100644 --- a/src/ipv6.h +++ b/src/ipv6.h @@ -32,8 +32,8 @@ #ifndef IN6_IS_ADDR_V4MAPPED #define IN6_IS_ADDR_V4MAPPED(a) \ ((((__const uint32_t *) (a))[0] == 0) \ - && (((__const uint32_t *) (a))[1] == 0) \ - && (((__const uint32_t *) (a))[2] == htonl (0xffff))) + && (((__const uint32_t *) (a))[1] == 0) \ + && (((__const uint32_t *) (a))[2] == htonl (0xffff))) #endif #ifndef HAVE_STRUCT_IP6_HDR @@ -49,7 +49,7 @@ struct ip6_hdr { } ip6_ctlun; struct in6_addr ip6_src; struct in6_addr ip6_dst; -} __attribute__ ((__gcc_struct__, __packed__)); +} __attribute__((__gcc_struct__, __packed__)); #define ip6_vfc ip6_ctlun.ip6_un2_vfc #define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow #define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen @@ -68,7 +68,7 @@ struct icmp6_hdr { uint16_t icmp6_un_data16[2]; uint8_t icmp6_un_data8[4]; } icmp6_dataun; -} __attribute__ ((__gcc_struct__, __packed__)); +} __attribute__((__gcc_struct__, __packed__)); #define ICMP6_DST_UNREACH_NOROUTE 0 #define ICMP6_DST_UNREACH 1 #define ICMP6_PACKET_TOO_BIG 2 @@ -88,7 +88,7 @@ struct icmp6_hdr { struct nd_neighbor_solicit { struct icmp6_hdr nd_ns_hdr; struct in6_addr nd_ns_target; -} __attribute__ ((__gcc_struct__, __packed__)); +} __attribute__((__gcc_struct__, __packed__)); #define ND_OPT_SOURCE_LINKADDR 1 #define ND_OPT_TARGET_LINKADDR 2 #define nd_ns_type nd_ns_hdr.icmp6_type @@ -101,7 +101,7 @@ struct nd_neighbor_solicit { struct nd_opt_hdr { uint8_t nd_opt_type; uint8_t nd_opt_len; -} __attribute__ ((__gcc_struct__, __packed__)); +} __attribute__((__gcc_struct__, __packed__)); #endif #endif diff --git a/src/linux/device.c b/src/linux/device.c index e273bfa..23178a3 100644 --- a/src/linux/device.c +++ b/src/linux/device.c @@ -47,12 +47,14 @@ static char ifrname[IFNAMSIZ]; static char *device_info; static bool setup_device(void) { - if(!get_config_string(lookup_config(config_tree, "Device"), &device)) + if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { device = xstrdup(DEFAULT_DEVICE); + } if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) - if(netname) + if(netname) { iface = xstrdup(netname); + } device_fd = open(device, O_RDWR | O_NONBLOCK); @@ -79,8 +81,10 @@ static bool setup_device(void) { device_type = DEVICE_TYPE_TUN; device_info = "Linux tun/tap device (tun mode)"; } else { - if (routing_mode == RMODE_ROUTER) + if(routing_mode == RMODE_ROUTER) { overwrite_mac = true; + } + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; device_type = DEVICE_TYPE_TAP; device_info = "Linux tun/tap device (tap mode)"; @@ -90,12 +94,16 @@ static bool setup_device(void) { /* Set IFF_ONE_QUEUE flag... */ bool t1q = false; - if(get_config_bool(lookup_config(config_tree, "IffOneQueue"), &t1q) && t1q) + + if(get_config_bool(lookup_config(config_tree, "IffOneQueue"), &t1q) && t1q) { ifr.ifr_flags |= IFF_ONE_QUEUE; + } + #endif - if(iface) + if(iface) { strncpy(ifr.ifr_name, iface, IFNAMSIZ); + } if(!ioctl(device_fd, TUNSETIFF, &ifr)) { strncpy(ifrname, ifr.ifr_name, IFNAMSIZ); @@ -110,10 +118,12 @@ static bool setup_device(void) { if(ifr.ifr_flags & IFF_TAP) { struct ifreq ifr_mac = {}; - if(!ioctl(device_fd, SIOCGIFHWADDR, &ifr_mac)) + + if(!ioctl(device_fd, SIOCGIFHWADDR, &ifr_mac)) { memcpy(mymac.x, ifr_mac.ifr_hwaddr.sa_data, ETH_ALEN); - else + } else { logger(DEBUG_ALWAYS, LOG_WARNING, "Could not get MAC address of %s: %s", device, strerror(errno)); + } } return true; @@ -123,9 +133,12 @@ static void close_device(void) { close(device_fd); device_fd = -1; - free(type); type = NULL; - free(device); device = NULL; - free(iface); iface = NULL; + free(type); + type = NULL; + free(device); + device = NULL; + free(iface); + iface = NULL; device_info = NULL; } @@ -133,64 +146,73 @@ static bool read_packet(vpn_packet_t *packet) { int inlen; switch(device_type) { - case DEVICE_TYPE_TUN: - inlen = read(device_fd, DATA(packet) + 10, MTU - 10); - - if(inlen <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", - device_info, device, strerror(errno)); - if (errno == EBADFD) { /* File descriptor in bad state */ - event_exit(); - } - return false; - } + case DEVICE_TYPE_TUN: + inlen = read(device_fd, DATA(packet) + 10, MTU - 10); - memset(DATA(packet), 0, 12); - packet->len = inlen + 10; - break; - case DEVICE_TYPE_TAP: - inlen = read(device_fd, DATA(packet), MTU); + if(inlen <= 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", + device_info, device, strerror(errno)); - if(inlen <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", - device_info, device, strerror(errno)); - return false; + if(errno == EBADFD) { /* File descriptor in bad state */ + event_exit(); } - packet->len = inlen; - break; - default: - abort(); + return false; + } + + memset(DATA(packet), 0, 12); + packet->len = inlen + 10; + break; + + case DEVICE_TYPE_TAP: + inlen = read(device_fd, DATA(packet), MTU); + + if(inlen <= 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", + device_info, device, strerror(errno)); + return false; + } + + packet->len = inlen; + break; + + default: + abort(); } logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, - device_info); + device_info); return true; } static bool write_packet(vpn_packet_t *packet) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + packet->len, device_info); switch(device_type) { - case DEVICE_TYPE_TUN: - DATA(packet)[10] = DATA(packet)[11] = 0; - if(write(device_fd, DATA(packet) + 10, packet->len - 10) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, - strerror(errno)); - return false; - } - break; - case DEVICE_TYPE_TAP: - if(write(device_fd, DATA(packet), packet->len) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, - strerror(errno)); - return false; - } - break; - default: - abort(); + case DEVICE_TYPE_TUN: + DATA(packet)[10] = DATA(packet)[11] = 0; + + if(write(device_fd, DATA(packet) + 10, packet->len - 10) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, + strerror(errno)); + return false; + } + + break; + + case DEVICE_TYPE_TAP: + if(write(device_fd, DATA(packet), packet->len) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, + strerror(errno)); + return false; + } + + break; + + default: + abort(); } return true; diff --git a/src/list.c b/src/list.c index 0bbc5d4..27494c8 100644 --- a/src/list.c +++ b/src/list.c @@ -41,8 +41,9 @@ list_node_t *list_alloc_node(void) { } void list_free_node(list_t *list, list_node_t *node) { - if(node->data && list->delete) + if(node->data && list->delete) { list->delete(node->data); + } free(node); } @@ -57,10 +58,11 @@ list_node_t *list_insert_head(list_t *list, void *data) { node->next = list->head; list->head = node; - if(node->next) + if(node->next) { node->next->prev = node; - else + } else { list->tail = node; + } list->count++; @@ -75,10 +77,11 @@ list_node_t *list_insert_tail(list_t *list, void *data) { node->prev = list->tail; list->tail = node; - if(node->prev) + if(node->prev) { node->prev->next = node; - else + } else { list->head = node; + } list->count++; @@ -93,10 +96,11 @@ list_node_t *list_insert_after(list_t *list, list_node_t *after, void *data) { node->prev = after; after->next = node; - if(node->next) + if(node->next) { node->next->prev = node; - else + } else { list->tail = node; + } list->count++; @@ -113,10 +117,11 @@ list_node_t *list_insert_before(list_t *list, list_node_t *before, void *data) { node->prev = before->prev; before->prev = node; - if(node->prev) + if(node->prev) { node->prev->next = node; - else + } else { list->head = node; + } list->count++; @@ -124,15 +129,17 @@ list_node_t *list_insert_before(list_t *list, list_node_t *before, void *data) { } void list_unlink_node(list_t *list, list_node_t *node) { - if(node->prev) + if(node->prev) { node->prev->next = node->next; - else + } else { list->head = node->next; + } - if(node->next) + if(node->next) { node->next->prev = node->prev; - else + } else { list->tail = node->prev; + } list->count--; } @@ -152,31 +159,35 @@ void list_delete_tail(list_t *list) { void list_delete(list_t *list, const void *data) { for(list_node_t *node = list->head, *next; next = node ? node->next : NULL, node; node = next) - if(node->data == data) + if(node->data == data) { list_delete_node(list, node); + } } /* Head/tail lookup */ void *list_get_head(list_t *list) { - if(list->head) + if(list->head) { return list->head->data; - else + } else { return NULL; + } } void *list_get_tail(list_t *list) { - if(list->tail) + if(list->tail) { return list->tail->data; - else + } else { return NULL; + } } /* Fast list deletion */ void list_delete_list(list_t *list) { - for(list_node_t *node = list->head, *next; next = node ? node->next : NULL, node; node = next) + for(list_node_t *node = list->head, *next; next = node ? node->next : NULL, node; node = next) { list_free_node(list, node); + } list_free(list); } @@ -184,12 +195,14 @@ void list_delete_list(list_t *list) { /* Traversing */ void list_foreach_node(list_t *list, list_action_node_t action) { - for(list_node_t *node = list->head, *next; next = node ? node->next : NULL, node; node = next) + for(list_node_t *node = list->head, *next; next = node ? node->next : NULL, node; node = next) { action(node); + } } void list_foreach(list_t *list, list_action_t action) { for(list_node_t *node = list->head, *next; next = node ? node->next : NULL, node; node = next) - if(node->data) + if(node->data) { action(node->data); + } } diff --git a/src/list.h b/src/list.h index 489c8d1..5f4a409 100644 --- a/src/list.h +++ b/src/list.h @@ -45,7 +45,7 @@ typedef struct list_t { /* (De)constructors */ -extern list_t *list_alloc(list_action_t) __attribute__ ((__malloc__)); +extern list_t *list_alloc(list_action_t) __attribute__((__malloc__)); extern void list_free(list_t *); extern list_node_t *list_alloc_node(void); extern void list_free_node(list_t *, list_node_t *); diff --git a/src/logger.c b/src/logger.c index 70180f7..7fb1629 100644 --- a/src/logger.c +++ b/src/logger.c @@ -45,40 +45,48 @@ static void real_logger(int level, int priority, const char *message) { static bool suppress = false; // Bail out early if there is nothing to do. - if(suppress) + if(suppress) { return; + } - if(!logcontrol && (level > debug_level || logmode == LOGMODE_NULL)) + if(!logcontrol && (level > debug_level || logmode == LOGMODE_NULL)) { return; + } if(level <= debug_level) { switch(logmode) { - case LOGMODE_STDERR: - fprintf(stderr, "%s\n", message); - fflush(stderr); - break; - case LOGMODE_FILE: - if(!now.tv_sec) - gettimeofday(&now, NULL); - time_t now_sec = now.tv_sec; - strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", localtime(&now_sec)); - fprintf(logfile, "%s %s[%ld]: %s\n", timestr, logident, (long)logpid, message); - fflush(logfile); - break; - case LOGMODE_SYSLOG: + case LOGMODE_STDERR: + fprintf(stderr, "%s\n", message); + fflush(stderr); + break; + + case LOGMODE_FILE: + if(!now.tv_sec) { + gettimeofday(&now, NULL); + } + + time_t now_sec = now.tv_sec; + strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", localtime(&now_sec)); + fprintf(logfile, "%s %s[%ld]: %s\n", timestr, logident, (long)logpid, message); + fflush(logfile); + break; + + case LOGMODE_SYSLOG: #ifdef HAVE_MINGW - { - const char *messages[] = {message}; - ReportEvent(loghandle, priority, 0, 0, NULL, 1, 0, messages, NULL); - } + { + const char *messages[] = {message}; + ReportEvent(loghandle, priority, 0, 0, NULL, 1, 0, messages, NULL); + } + #else #ifdef HAVE_SYSLOG_H - syslog(priority, "%s", message); + syslog(priority, "%s", message); #endif #endif - break; - case LOGMODE_NULL: - break; + break; + + case LOGMODE_NULL: + break; } if(umbilical && do_detach) { @@ -90,16 +98,25 @@ static void real_logger(int level, int priority, const char *message) { if(logcontrol) { suppress = true; logcontrol = false; + for list_each(connection_t, c, connection_list) { - if(!c->status.log) + if(!c->status.log) { continue; + } + logcontrol = true; - if(level > (c->outcompression >= 0 ? c->outcompression : debug_level)) + + if(level > (c->outcompression >= 0 ? c->outcompression : debug_level)) { continue; + } + int len = strlen(message); - if(send_request(c, "%d %d %d", CONTROL, REQ_LOG, len)) + + if(send_request(c, "%d %d %d", CONTROL, REQ_LOG, len)) { send_meta(c, message, len); + } } + suppress = false; } } @@ -113,8 +130,9 @@ void logger(int level, int priority, const char *format, ...) { message[sizeof(message) - 1] = 0; va_end(ap); - if(len > 0 && len < sizeof(message) - 1 && message[len - 1] == '\n') + if(len > 0 && len < sizeof(message) - 1 && message[len - 1] == '\n') { message[len - 1] = 0; + } real_logger(level, priority, message); } @@ -125,15 +143,19 @@ static void sptps_logger(sptps_t *s, int s_errno, const char *format, va_list ap int len = vsnprintf(message, msglen, format, ap); message[sizeof(message) - 1] = 0; + if(len > 0 && len < sizeof(message) - 1) { - if(message[len - 1] == '\n') + if(message[len - 1] == '\n') { message[--len] = 0; + } // WARNING: s->handle can point to a connection_t or a node_t, // but both types have the name and hostname fields at the same offsets. connection_t *c = s->handle; - if(c) + + if(c) { snprintf(message + len, sizeof(message) - len, " from %s (%s)", c->name, c->hostname); + } } real_logger(DEBUG_ALWAYS, LOG_ERR, message); @@ -144,51 +166,62 @@ void openlogger(const char *ident, logmode_t mode) { logmode = mode; switch(mode) { - case LOGMODE_STDERR: - logpid = getpid(); - break; - case LOGMODE_FILE: - logpid = getpid(); - logfile = fopen(logfilename, "a"); - if(!logfile) { - fprintf(stderr, "Could not open log file %s: %s\n", logfilename, strerror(errno)); - logmode = LOGMODE_NULL; - } - break; - case LOGMODE_SYSLOG: + case LOGMODE_STDERR: + logpid = getpid(); + break; + + case LOGMODE_FILE: + logpid = getpid(); + logfile = fopen(logfilename, "a"); + + if(!logfile) { + fprintf(stderr, "Could not open log file %s: %s\n", logfilename, strerror(errno)); + logmode = LOGMODE_NULL; + } + + break; + + case LOGMODE_SYSLOG: #ifdef HAVE_MINGW - loghandle = RegisterEventSource(NULL, logident); - if(!loghandle) { - fprintf(stderr, "Could not open log handle!"); - logmode = LOGMODE_NULL; - } - break; + loghandle = RegisterEventSource(NULL, logident); + + if(!loghandle) { + fprintf(stderr, "Could not open log handle!"); + logmode = LOGMODE_NULL; + } + + break; #else #ifdef HAVE_SYSLOG_H - openlog(logident, LOG_CONS | LOG_PID, LOG_DAEMON); - break; + openlog(logident, LOG_CONS | LOG_PID, LOG_DAEMON); + break; #endif #endif - case LOGMODE_NULL: - break; + + case LOGMODE_NULL: + break; } - if(logmode != LOGMODE_NULL) + if(logmode != LOGMODE_NULL) { sptps_log = sptps_logger; - else + } else { sptps_log = sptps_log_quiet; + } } void reopenlogger() { - if(logmode != LOGMODE_FILE) + if(logmode != LOGMODE_FILE) { return; + } fflush(logfile); FILE *newfile = fopen(logfilename, "a"); + if(!newfile) { logger(DEBUG_ALWAYS, LOG_ERR, "Unable to reopen log file %s: %s", logfilename, strerror(errno)); return; } + fclose(logfile); logfile = newfile; } @@ -196,21 +229,23 @@ void reopenlogger() { void closelogger(void) { switch(logmode) { - case LOGMODE_FILE: - fclose(logfile); - break; - case LOGMODE_SYSLOG: + case LOGMODE_FILE: + fclose(logfile); + break; + + case LOGMODE_SYSLOG: #ifdef HAVE_MINGW - DeregisterEventSource(loghandle); - break; + DeregisterEventSource(loghandle); + break; #else #ifdef HAVE_SYSLOG_H - closelog(); - break; + closelog(); + break; #endif #endif - case LOGMODE_NULL: - case LOGMODE_STDERR: - break; + + case LOGMODE_NULL: + case LOGMODE_STDERR: + break; } } diff --git a/src/logger.h b/src/logger.h index a14b909..0e06d19 100644 --- a/src/logger.h +++ b/src/logger.h @@ -72,7 +72,7 @@ extern bool logcontrol; extern int umbilical; extern void openlogger(const char *, logmode_t); extern void reopenlogger(void); -extern void logger(int, int, const char *, ...) __attribute__ ((__format__(printf, 3, 4))); +extern void logger(int, int, const char *, ...) __attribute__((__format__(printf, 3, 4))); extern void closelogger(void); #endif diff --git a/src/meta.c b/src/meta.c index 8191983..5b47aa6 100644 --- a/src/meta.c +++ b/src/meta.c @@ -55,16 +55,18 @@ bool send_meta(connection_t *c, const char *buffer, int length) { } logger(DEBUG_META, LOG_DEBUG, "Sending %d bytes of metadata to %s (%s)", length, - c->name, c->hostname); + c->name, c->hostname); - if(c->protocol_minor >= 2) + if(c->protocol_minor >= 2) { return sptps_send_record(&c->sptps, 0, buffer, length); + } /* Add our data to buffer */ if(c->status.encryptout) { #ifdef DISABLE_LEGACY return false; #else + if(length > c->outbudget) { logger(DEBUG_META, LOG_ERR, "Byte limit exceeded for encryption to %s (%s)", c->name, c->hostname); return false; @@ -76,9 +78,10 @@ bool send_meta(connection_t *c, const char *buffer, int length) { if(!cipher_encrypt(c->outcipher, buffer, length, buffer_prepare(&c->outbuf, length), &outlen, false) || outlen != length) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting metadata to %s (%s)", - c->name, c->hostname); + c->name, c->hostname); return false; } + #endif } else { buffer_add(&c->outbuf, buffer, length); @@ -96,7 +99,7 @@ void send_meta_raw(connection_t *c, const char *buffer, int length) { } logger(DEBUG_META, LOG_DEBUG, "Sending %d bytes of raw metadata to %s (%s)", length, - c->name, c->hostname); + c->name, c->hostname); buffer_add(&c->outbuf, buffer, length); @@ -105,8 +108,9 @@ void send_meta_raw(connection_t *c, const char *buffer, int length) { void broadcast_meta(connection_t *from, const char *buffer, int length) { for list_each(connection_t, c, connection_list) - if(c != from && c->edge) + if(c != from && c->edge) { send_meta(c, buffer, length); + } } bool receive_meta_sptps(void *handle, uint8_t type, const void *vdata, uint16_t length) { @@ -119,20 +123,24 @@ bool receive_meta_sptps(void *handle, uint8_t type, const void *vdata, uint16_t } if(type == SPTPS_HANDSHAKE) { - if(c->allow_request == ACK) + if(c->allow_request == ACK) { return send_ack(c); - else + } else { return true; + } } - if(!data) + if(!data) { return true; + } /* Are we receiving a TCPpacket? */ if(c->tcplen) { - if(length != c->tcplen) + if(length != c->tcplen) { return false; + } + receive_tcppacket(c, data, length); c->tcplen = 0; return true; @@ -140,8 +148,9 @@ bool receive_meta_sptps(void *handle, uint8_t type, const void *vdata, uint16_t /* Change newline to null byte, just like non-SPTPS requests */ - if(data[length - 1] == '\n') + if(data[length - 1] == '\n') { ((char *)data)[length - 1] = 0; + } /* Otherwise we are waiting for a request */ @@ -174,12 +183,13 @@ bool receive_meta(connection_t *c) { if(inlen <= 0) { if(!inlen || !sockerrno) { logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection closed by %s (%s)", - c->name, c->hostname); - } else if(sockwouldblock(sockerrno)) + c->name, c->hostname); + } else if(sockwouldblock(sockerrno)) { return true; - else + } else logger(DEBUG_ALWAYS, LOG_ERR, "Metadata socket read error for %s (%s): %s", - c->name, c->hostname, sockstrerror(sockerrno)); + c->name, c->hostname, sockstrerror(sockerrno)); + return false; } @@ -191,11 +201,15 @@ bool receive_meta(connection_t *c) { buffer_add(&c->inbuf, bufp, len); char *sptpspacket = buffer_read(&c->inbuf, c->sptpslen); - if(!sptpspacket) + + if(!sptpspacket) { return true; + } - if(!receive_tcppacket_sptps(c, sptpspacket, c->sptpslen)) + if(!receive_tcppacket_sptps(c, sptpspacket, c->sptpslen)) { return false; + } + c->sptpslen = 0; bufp += len; @@ -205,8 +219,11 @@ bool receive_meta(connection_t *c) { if(c->protocol_minor >= 2) { int len = sptps_receive_data(&c->sptps, bufp, inlen); - if(!len) + + if(!len) { return false; + } + bufp += len; inlen -= len; continue; @@ -214,10 +231,12 @@ bool receive_meta(connection_t *c) { if(!c->status.decryptin) { endp = memchr(bufp, '\n', inlen); - if(endp) + + if(endp) { endp++; - else + } else { endp = bufp + inlen; + } buffer_add(&c->inbuf, bufp, endp - bufp); @@ -227,6 +246,7 @@ bool receive_meta(connection_t *c) { #ifdef DISABLE_LEGACY return false; #else + if(inlen > c->inbudget) { logger(DEBUG_META, LOG_ERR, "yte limit exceeded for decryption from %s (%s)", c->name, c->hostname); return false; @@ -238,7 +258,7 @@ bool receive_meta(connection_t *c) { if(!cipher_decrypt(c->incipher, bufp, inlen, buffer_prepare(&c->inbuf, inlen), &outlen, false) || inlen != outlen) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting metadata from %s (%s)", - c->name, c->hostname); + c->name, c->hostname); return false; } @@ -251,8 +271,10 @@ bool receive_meta(connection_t *c) { if(c->tcplen) { char *tcpbuffer = buffer_read(&c->inbuf, c->tcplen); - if(!tcpbuffer) + + if(!tcpbuffer) { break; + } if(!c->node) { if(c->outgoing && proxytype == PROXY_SOCKS4 && c->allow_request == ID) { @@ -267,14 +289,17 @@ bool receive_meta(connection_t *c) { logger(DEBUG_CONNECTIONS, LOG_ERR, "Invalid response from proxy server"); return false; } + if(tcpbuffer[1] == (char)0xff) { logger(DEBUG_CONNECTIONS, LOG_ERR, "Proxy request rejected: unsuitable authentication method"); return false; } + if(tcpbuffer[2] != 5) { logger(DEBUG_CONNECTIONS, LOG_ERR, "Invalid response from proxy server"); return false; } + if(tcpbuffer[3] == 0) { logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Proxy request granted"); } else { @@ -300,10 +325,14 @@ bool receive_meta(connection_t *c) { /* Otherwise we are waiting for a request */ char *request = buffer_readline(&c->inbuf); + if(request) { bool result = receive_request(c, request); - if(!result) + + if(!result) { return false; + } + continue; } else { break; diff --git a/src/mingw/common.h b/src/mingw/common.h index f16744b..ff052c9 100644 --- a/src/mingw/common.h +++ b/src/mingw/common.h @@ -40,7 +40,7 @@ //============= #define TAP_CONTROL_CODE(request,method) \ - CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS) + CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS) #define TAP_IOCTL_GET_MAC TAP_CONTROL_CODE (1, METHOD_BUFFERED) #define TAP_IOCTL_GET_VERSION TAP_CONTROL_CODE (2, METHOD_BUFFERED) diff --git a/src/mingw/device.c b/src/mingw/device.c index 9c79ac0..468ba50 100644 --- a/src/mingw/device.c +++ b/src/mingw/device.c @@ -52,13 +52,16 @@ static void device_issue_read() { device_read_overlapped.OffsetHigh = 0; int status; - for (;;) { + + for(;;) { DWORD len; status = ReadFile(device_handle, (void *)device_read_packet.data, MTU, &len, &device_read_overlapped); - if (!status) { - if (GetLastError() != ERROR_IO_PENDING) + + if(!status) { + if(GetLastError() != ERROR_IO_PENDING) logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); + device, strerror(errno)); + break; } @@ -72,9 +75,10 @@ static void device_handle_read(void *data, int flags) { ResetEvent(device_read_overlapped.hEvent); DWORD len; - if (!GetOverlappedResult(device_handle, &device_read_overlapped, &len, FALSE)) { + + if(!GetOverlappedResult(device_handle, &device_read_overlapped, &len, FALSE)) { logger(DEBUG_ALWAYS, LOG_ERR, "Error getting read result from %s %s: %s", device_info, - device, strerror(errno)); + device, strerror(errno)); return; } @@ -101,8 +105,9 @@ static bool setup_device(void) { get_config_string(lookup_config(config_tree, "Device"), &device); get_config_string(lookup_config(config_tree, "Interface"), &iface); - if(device && iface) + if(device && iface) { logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: both Device and Interface specified, results may not be as expected"); + } /* Open registry and look for network adapters */ @@ -111,44 +116,51 @@ static bool setup_device(void) { return false; } - for (i = 0; ; i++) { + for(i = 0; ; i++) { len = sizeof(adapterid); - if(RegEnumKeyEx(key, i, adapterid, &len, 0, 0, 0, NULL)) + + if(RegEnumKeyEx(key, i, adapterid, &len, 0, 0, 0, NULL)) { break; + } /* Find out more about this adapter */ snprintf(regpath, sizeof(regpath), "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapterid); - if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2)) + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2)) { continue; + } len = sizeof(adaptername); err = RegQueryValueEx(key2, "Name", 0, 0, (LPBYTE)adaptername, &len); RegCloseKey(key2); - if(err) + if(err) { continue; + } if(device) { if(!strcmp(device, adapterid)) { found = true; break; - } else + } else { continue; + } } if(iface) { if(!strcmp(iface, adaptername)) { found = true; break; - } else + } else { continue; + } } snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid); device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0); + if(device_handle != INVALID_HANDLE_VALUE) { found = true; break; @@ -162,11 +174,13 @@ static bool setup_device(void) { return false; } - if(!device) + if(!device) { device = xstrdup(adapterid); + } - if(!iface) + if(!iface) { iface = xstrdup(adaptername); + } /* Try to open the corresponding tap device */ @@ -185,17 +199,18 @@ static bool setup_device(void) { { ULONG info[3] = {0}; DWORD len; - if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_VERSION, &info, sizeof(info), &info, sizeof info, &len, NULL)) + + if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_VERSION, &info, sizeof(info), &info, sizeof info, &len, NULL)) { logger(DEBUG_ALWAYS, LOG_WARNING, "Could not get version information from Windows tap device %s (%s): %s", device, iface, winerror(GetLastError())); - else { + } else { logger(DEBUG_ALWAYS, LOG_INFO, "TAP-Windows driver version: %lu.%lu%s", info[0], info[1], info[2] ? " (DEBUG)" : ""); /* Warn if using >=9.21. This is because starting from 9.21, TAP-Win32 seems to use a different, less efficient write path. */ if(info[0] == 9 && info[1] >= 21) logger(DEBUG_ALWAYS, LOG_WARNING, - "You are using the newer (>= 9.0.0.21, NDIS6) series of TAP-Win32 drivers. " - "Using these drivers with tinc is not recommanded as it can result in poor performance. " - "You might want to revert back to 9.0.0.9 instead."); + "You are using the newer (>= 9.0.0.21, NDIS6) series of TAP-Win32 drivers. " + "Using these drivers with tinc is not recommanded as it can result in poor performance. " + "You might want to revert back to 9.0.0.9 instead."); } } @@ -257,19 +272,27 @@ static void close_device(void) { before we close the event it's referencing. */ DWORD len; - if(!GetOverlappedResult(device_handle, &device_read_overlapped, &len, TRUE) && GetLastError() != ERROR_OPERATION_ABORTED) + + if(!GetOverlappedResult(device_handle, &device_read_overlapped, &len, TRUE) && GetLastError() != ERROR_OPERATION_ABORTED) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not wait for %s %s read to cancel: %s", device_info, device, winerror(GetLastError())); - if(device_write_packet.len > 0 && !GetOverlappedResult(device_handle, &device_write_overlapped, &len, TRUE) && GetLastError() != ERROR_OPERATION_ABORTED) + } + + if(device_write_packet.len > 0 && !GetOverlappedResult(device_handle, &device_write_overlapped, &len, TRUE) && GetLastError() != ERROR_OPERATION_ABORTED) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not wait for %s %s write to cancel: %s", device_info, device, winerror(GetLastError())); + } + device_write_packet.len = 0; CloseHandle(device_read_overlapped.hEvent); CloseHandle(device_write_overlapped.hEvent); - CloseHandle(device_handle); device_handle = INVALID_HANDLE_VALUE; + CloseHandle(device_handle); + device_handle = INVALID_HANDLE_VALUE; - free(device); device = NULL; - free(iface); iface = NULL; + free(device); + device = NULL; + free(iface); + iface = NULL; device_info = NULL; } @@ -281,7 +304,7 @@ static bool write_packet(vpn_packet_t *packet) { DWORD outlen; logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + packet->len, device_info); if(device_write_packet.len > 0) { /* Make sure the previous write operation is finished before we start the next one; @@ -299,9 +322,9 @@ static bool write_packet(vpn_packet_t *packet) { memcpy(&device_write_packet, packet, sizeof(*packet)); - if(WriteFile(device_handle, DATA(&device_write_packet), device_write_packet.len, &outlen, &device_write_overlapped)) + if(WriteFile(device_handle, DATA(&device_write_packet), device_write_packet.len, &outlen, &device_write_overlapped)) { device_write_packet.len = 0; - else if (GetLastError() != ERROR_IO_PENDING) { + } else if(GetLastError() != ERROR_IO_PENDING) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, device, winerror(GetLastError())); return false; } diff --git a/src/multicast_device.c b/src/multicast_device.c index 082ba7d..c19852b 100644 --- a/src/multicast_device.c +++ b/src/multicast_device.c @@ -51,6 +51,7 @@ static bool setup_device(void) { host = xstrdup(device); space = strchr(host, ' '); + if(!space) { logger(DEBUG_ALWAYS, LOG_ERR, "Port number required for %s", device_info); goto error; @@ -66,10 +67,13 @@ static bool setup_device(void) { } ai = str2addrinfo(host, port, SOCK_DGRAM); - if(!ai) + + if(!ai) { goto error; + } device_fd = socket(ai->ai_family, SOCK_DGRAM, IPPROTO_UDP); + if(device_fd < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Creating socket failed: %s", sockstrerror(sockerrno)); goto error; @@ -89,48 +93,56 @@ static bool setup_device(void) { switch(ai->ai_family) { #ifdef IP_ADD_MEMBERSHIP - case AF_INET: { - struct ip_mreq mreq; - struct sockaddr_in in; - memcpy(&in, ai->ai_addr, sizeof(in)); - mreq.imr_multiaddr.s_addr = in.sin_addr.s_addr; - mreq.imr_interface.s_addr = htonl(INADDR_ANY); - if(setsockopt(device_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&mreq, sizeof(mreq))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Cannot join multicast group %s %s: %s", host, port, sockstrerror(sockerrno)); - goto error; - } + + case AF_INET: { + struct ip_mreq mreq; + struct sockaddr_in in; + memcpy(&in, ai->ai_addr, sizeof(in)); + mreq.imr_multiaddr.s_addr = in.sin_addr.s_addr; + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + + if(setsockopt(device_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&mreq, sizeof(mreq))) { + logger(DEBUG_ALWAYS, LOG_ERR, "Cannot join multicast group %s %s: %s", host, port, sockstrerror(sockerrno)); + goto error; + } + #ifdef IP_MULTICAST_LOOP - setsockopt(device_fd, IPPROTO_IP, IP_MULTICAST_LOOP, (const void *)&one, sizeof(one)); + setsockopt(device_fd, IPPROTO_IP, IP_MULTICAST_LOOP, (const void *)&one, sizeof(one)); #endif #ifdef IP_MULTICAST_TTL - setsockopt(device_fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&ttl, sizeof(ttl)); + setsockopt(device_fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&ttl, sizeof(ttl)); #endif - } break; + } + break; #endif #ifdef IPV6_JOIN_GROUP - case AF_INET6: { - struct ipv6_mreq mreq; - struct sockaddr_in6 in6; - memcpy(&in6, ai->ai_addr, sizeof(in6)); - memcpy(&mreq.ipv6mr_multiaddr, &in6.sin6_addr, sizeof(mreq.ipv6mr_multiaddr)); - mreq.ipv6mr_interface = in6.sin6_scope_id; - if(setsockopt(device_fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, (void *)&mreq, sizeof(mreq))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Cannot join multicast group %s %s: %s", host, port, sockstrerror(sockerrno)); - goto error; - } + + case AF_INET6: { + struct ipv6_mreq mreq; + struct sockaddr_in6 in6; + memcpy(&in6, ai->ai_addr, sizeof(in6)); + memcpy(&mreq.ipv6mr_multiaddr, &in6.sin6_addr, sizeof(mreq.ipv6mr_multiaddr)); + mreq.ipv6mr_interface = in6.sin6_scope_id; + + if(setsockopt(device_fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, (void *)&mreq, sizeof(mreq))) { + logger(DEBUG_ALWAYS, LOG_ERR, "Cannot join multicast group %s %s: %s", host, port, sockstrerror(sockerrno)); + goto error; + } + #ifdef IPV6_MULTICAST_LOOP - setsockopt(device_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (const void *)&one, sizeof(one)); + setsockopt(device_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (const void *)&one, sizeof(one)); #endif #ifdef IPV6_MULTICAST_HOPS - setsockopt(device_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (void *)&ttl, sizeof(ttl)); + setsockopt(device_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (void *)&ttl, sizeof(ttl)); #endif - } break; + } + break; #endif - default: - logger(DEBUG_ALWAYS, LOG_ERR, "Multicast for address family %x unsupported", ai->ai_family); - goto error; + default: + logger(DEBUG_ALWAYS, LOG_ERR, "Multicast for address family %x unsupported", ai->ai_family); + goto error; } logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); @@ -138,24 +150,34 @@ static bool setup_device(void) { return true; error: - if(device_fd >= 0) + + if(device_fd >= 0) { closesocket(device_fd); - if(ai) + } + + if(ai) { freeaddrinfo(ai); + } + free(host); return false; } static void close_device(void) { - close(device_fd); device_fd = -1; + close(device_fd); + device_fd = -1; - free(device); device = NULL; - free(iface); iface = NULL; + free(device); + device = NULL; + free(iface); + iface = NULL; if(ai) { - freeaddrinfo(ai); ai = NULL; + freeaddrinfo(ai); + ai = NULL; } + device_info = NULL; } @@ -164,7 +186,7 @@ static bool read_packet(vpn_packet_t *packet) { if((lenin = recv(device_fd, (void *)DATA(packet), MTU, 0)) <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, sockstrerror(sockerrno)); + device, sockstrerror(sockerrno)); return false; } @@ -176,18 +198,18 @@ static bool read_packet(vpn_packet_t *packet) { packet->len = lenin; logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, - device_info); + device_info); return true; } static bool write_packet(vpn_packet_t *packet) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + packet->len, device_info); if(sendto(device_fd, (void *)DATA(packet), packet->len, 0, ai->ai_addr, ai->ai_addrlen) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, - sockstrerror(sockerrno)); + sockstrerror(sockerrno)); return false; } diff --git a/src/names.c b/src/names.c index 95aad2b..6db364e 100644 --- a/src/names.c +++ b/src/names.c @@ -46,87 +46,116 @@ void make_names(bool daemon) { #endif confbase_given = confbase; - if(netname && confbase) + if(netname && confbase) { logger(DEBUG_ALWAYS, LOG_INFO, "Both netname and configuration directory given, using the latter..."); + } - if(netname) + if(netname) { xasprintf(&identname, "tinc.%s", netname); - else + } else { identname = xstrdup("tinc"); + } #ifdef HAVE_MINGW + if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\tinc", 0, KEY_READ, &key)) { if(!RegQueryValueEx(key, NULL, 0, 0, (LPBYTE)installdir, &len)) { confdir = xstrdup(installdir); + if(!confbase) { - if(netname) + if(netname) { xasprintf(&confbase, "%s" SLASH "%s", installdir, netname); - else + } else { xasprintf(&confbase, "%s", installdir); + } } - if(!logfilename) + + if(!logfilename) { xasprintf(&logfilename, "%s" SLASH "tinc.log", confbase); + } } + RegCloseKey(key); } + #endif - if(!confdir) + + if(!confdir) { confdir = xstrdup(CONFDIR SLASH "tinc"); + } if(!confbase) { - if(netname) + if(netname) { xasprintf(&confbase, CONFDIR SLASH "tinc" SLASH "%s", netname); - else + } else { xasprintf(&confbase, CONFDIR SLASH "tinc"); + } } #ifdef HAVE_MINGW - if(!logfilename) + + if(!logfilename) { xasprintf(&logfilename, "%s" SLASH "log", confbase); + } - if(!pidfilename) + if(!pidfilename) { xasprintf(&pidfilename, "%s" SLASH "pid", confbase); + } + #else bool fallback = false; + if(daemon) { - if(access(LOCALSTATEDIR, R_OK | W_OK | X_OK)) + if(access(LOCALSTATEDIR, R_OK | W_OK | X_OK)) { fallback = true; + } } else { char fname[PATH_MAX]; snprintf(fname, sizeof(fname), LOCALSTATEDIR SLASH "run" SLASH "%s.pid", identname); + if(access(fname, R_OK)) { snprintf(fname, sizeof(fname), "%s" SLASH "pid", confbase); - if(!access(fname, R_OK)) + + if(!access(fname, R_OK)) { fallback = true; + } } } if(!fallback) { - if(!logfilename) + if(!logfilename) { xasprintf(&logfilename, LOCALSTATEDIR SLASH "log" SLASH "%s.log", identname); + } - if(!pidfilename) + if(!pidfilename) { xasprintf(&pidfilename, LOCALSTATEDIR SLASH "run" SLASH "%s.pid", identname); + } } else { - if(!logfilename) + if(!logfilename) { xasprintf(&logfilename, "%s" SLASH "log", confbase); + } if(!pidfilename) { - if(daemon) + if(daemon) { logger(DEBUG_ALWAYS, LOG_WARNING, "Could not access " LOCALSTATEDIR SLASH " (%s), storing pid and socket files in %s" SLASH, strerror(errno), confbase); + } + xasprintf(&pidfilename, "%s" SLASH "pid", confbase); } } + #endif if(!unixsocketname) { int len = strlen(pidfilename); unixsocketname = xmalloc(len + 8); memcpy(unixsocketname, pidfilename, len); - if(len > 4 && !strcmp(pidfilename + len - 4, ".pid")) + + if(len > 4 && !strcmp(pidfilename + len - 4, ".pid")) { strncpy(unixsocketname + len - 4, ".socket", 8); - else + } else { strncpy(unixsocketname + len, ".socket", 8); + } } } diff --git a/src/net.c b/src/net.c index 887447b..097a79c 100644 --- a/src/net.c +++ b/src/net.c @@ -58,13 +58,17 @@ void purge(void) { for splay_each(subnet_t, s, n->subnet_tree) { send_del_subnet(everyone, s); - if(!strictsubnets) + + if(!strictsubnets) { subnet_del(n, s); + } } for splay_each(edge_t, e, n->edge_tree) { - if(!tunnelserver) + if(!tunnelserver) { send_del_edge(everyone, e); + } + edge_del(e); } } @@ -75,12 +79,15 @@ void purge(void) { for splay_each(node_t, n, node_tree) { if(!n->status.reachable) { for splay_each(edge_t, e, edge_weight_tree) - if(e->to == n) + if(e->to == n) { return; + } if(!autoconnect && (!strictsubnets || !n->subnet_tree->head)) /* in strictsubnets mode do not delete nodes with subnets */ + { node_del(n); + } } } } @@ -96,12 +103,14 @@ void terminate_connection(connection_t *c, bool report) { logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Closing connection with %s (%s)", c->name, c->hostname); if(c->node) { - if(c->node->connection == c) + if(c->node->connection == c) { c->node->connection = NULL; + } if(c->edge) { - if(report && !tunnelserver) + if(report && !tunnelserver) { send_del_edge(everyone, c->edge); + } edge_del(c->edge); c->edge = NULL; @@ -115,9 +124,12 @@ void terminate_connection(connection_t *c, bool report) { if(report && !c->node->status.reachable) { edge_t *e; e = lookup_edge(c->node, myself); + if(e) { - if(!tunnelserver) + if(!tunnelserver) { send_del_edge(everyone, e); + } + edge_del(e); } } @@ -129,13 +141,15 @@ void terminate_connection(connection_t *c, bool report) { /* Check if this was our outgoing connection */ - if(outgoing) + if(outgoing) { do_outgoing_connection(outgoing); + } #ifndef HAVE_MINGW /* Clean up dead proxy processes */ while(waitpid(-1, NULL, WNOHANG) > 0); + #endif } @@ -152,37 +166,40 @@ static void timeout_handler(void *data) { bool close_all_connections = false; /* - timeout_handler will start after 30 seconds from start of tincd - hold information about the elapsed time since last time the handler - has been run + timeout_handler will start after 30 seconds from start of tincd + hold information about the elapsed time since last time the handler + has been run */ long sleep_time = now.tv_sec - last_periodic_run_time.tv_sec; + /* - It seems that finding sane default value is harder than expected - Since we send every second a UDP packet to make holepunching work - And default UDP state expire on firewalls is between 15-30 seconds - we drop all connections after 60 Seconds - UDPDiscoveryTimeout=30 - by default + It seems that finding sane default value is harder than expected + Since we send every second a UDP packet to make holepunching work + And default UDP state expire on firewalls is between 15-30 seconds + we drop all connections after 60 Seconds - UDPDiscoveryTimeout=30 + by default */ - if (sleep_time > 2 * udp_discovery_timeout) { + if(sleep_time > 2 * udp_discovery_timeout) { logger(DEBUG_ALWAYS, LOG_ERR, "Awaking from dead after %ld seconds of sleep", sleep_time); /* - Do not send any packets to tinc after we wake up. - The other node probably closed our connection but we still - are holding context information to them. This may happen on - laptops or any other hardware which can be suspended for some time. - Sending any data to node that wasn't expecting it will produce - annoying and misleading errors on the other side about failed signature - verification and or about missing sptps context + Do not send any packets to tinc after we wake up. + The other node probably closed our connection but we still + are holding context information to them. This may happen on + laptops or any other hardware which can be suspended for some time. + Sending any data to node that wasn't expecting it will produce + annoying and misleading errors on the other side about failed signature + verification and or about missing sptps context */ close_all_connections = true; } + last_periodic_run_time = now; for list_each(connection_t, c, connection_list) { // control connections (eg. tinc ctl) do not have any timeout - if(c->status.control) + if(c->status.control) { continue; + } if(close_all_connections) { logger(DEBUG_ALWAYS, LOG_ERR, "Forcing connection close after sleep time %s (%s)", c->name, c->hostname); @@ -191,15 +208,17 @@ static void timeout_handler(void *data) { } // Bail out early if we haven't reached the ping timeout for this node yet - if(c->last_ping_time + pingtimeout > now.tv_sec) + if(c->last_ping_time + pingtimeout > now.tv_sec) { continue; + } // timeout during connection establishing if(!c->edge) { - if(c->status.connecting) + if(c->status.connecting) { logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout while connecting to %s (%s)", c->name, c->hostname); - else + } else { logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout from %s (%s) during authentication", c->name, c->hostname); + } terminate_connection(c, c->edge); continue; @@ -216,11 +235,14 @@ static void timeout_handler(void *data) { } // check whether we need to send a new ping - if(c->last_ping_time + pinginterval <= now.tv_sec) + if(c->last_ping_time + pinginterval <= now.tv_sec) { send_ping(c); + } } - timeout_set(data, &(struct timeval){1, rand() % 100000}); + timeout_set(data, &(struct timeval) { + 1, rand() % 100000 + }); } static void periodic_handler(void *data) { @@ -231,14 +253,20 @@ static void periodic_handler(void *data) { if(contradicting_del_edge > 100 && contradicting_add_edge > 100) { logger(DEBUG_ALWAYS, LOG_WARNING, "Possible node with same Name as us! Sleeping %d seconds.", sleeptime); - nanosleep(&(struct timespec){sleeptime, 0}, NULL); + nanosleep(&(struct timespec) { + sleeptime, 0 + }, NULL); sleeptime *= 2; - if(sleeptime < 0) + + if(sleeptime < 0) { sleeptime = 3600; + } } else { sleeptime /= 2; - if(sleeptime < 10) + + if(sleeptime < 10) { sleeptime = 10; + } } contradicting_add_edge = 0; @@ -246,14 +274,17 @@ static void periodic_handler(void *data) { /* If AutoConnect is set, check if we need to make or break connections. */ - if(autoconnect && node_tree->count > 1) + if(autoconnect && node_tree->count > 1) { do_autoconnect(); + } - timeout_set(data, &(struct timeval){5, rand() % 100000}); + timeout_set(data, &(struct timeval) { + 5, rand() % 100000 + }); } void handle_meta_connection_data(connection_t *c) { - if (!receive_meta(c)) { + if(!receive_meta(c)) { terminate_connection(c, c->edge); return; } @@ -268,8 +299,10 @@ static void sigterm_handler(void *data) { static void sighup_handler(void *data) { logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum)); reopenlogger(); - if(reload_configuration()) + + if(reload_configuration()) { exit(1); + } } static void sigalrm_handler(void *data) { @@ -304,48 +337,60 @@ int reload_configuration(void) { if(strictsubnets) { for splay_each(subnet_t, subnet, subnet_tree) - if (subnet->owner) + if(subnet->owner) { subnet->expires = 1; + } } - for splay_each(node_t, n, node_tree) + for splay_each(node_t, n, node_tree) { n->status.has_address = false; + } load_all_nodes(); if(strictsubnets) { for splay_each(subnet_t, subnet, subnet_tree) { - if (!subnet->owner) + if(!subnet->owner) { continue; + } + if(subnet->expires == 1) { send_del_subnet(everyone, subnet); - if(subnet->owner->status.reachable) + + if(subnet->owner->status.reachable) { subnet_update(subnet->owner, subnet, false); + } + subnet_del(subnet->owner, subnet); } else if(subnet->expires == -1) { subnet->expires = 0; } else { send_add_subnet(everyone, subnet); - if(subnet->owner->status.reachable) + + if(subnet->owner->status.reachable) { subnet_update(subnet->owner, subnet, true); + } } } } else { /* Only read our own subnets back in */ for splay_each(subnet_t, subnet, myself->subnet_tree) - if(!subnet->expires) + if(!subnet->expires) { subnet->expires = 1; + } config_t *cfg = lookup_config(config_tree, "Subnet"); while(cfg) { subnet_t *subnet, *s2; - if(!get_config_subnet(cfg, &subnet)) + if(!get_config_subnet(cfg, &subnet)) { continue; + } if((s2 = lookup_subnet(myself, subnet))) { - if(s2->expires == 1) + if(s2->expires == 1) { s2->expires = 0; + } free_subnet(subnet); } else { @@ -373,11 +418,13 @@ int reload_configuration(void) { /* Close connections to hosts that have a changed or deleted host config file */ for list_each(connection_t, c, connection_list) { - if(c->status.control) + if(c->status.control) { continue; + } snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, c->name); struct stat s; + if(stat(fname, &s) || s.st_mtime > last_config_check) { logger(DEBUG_CONNECTIONS, LOG_INFO, "Host config file of %s has been changed", c->name); terminate_connection(c, c->edge); @@ -393,18 +440,24 @@ void retry(void) { /* Reset the reconnection timers for all outgoing connections */ for list_each(outgoing_t, outgoing, outgoing_list) { outgoing->timeout = 0; + if(outgoing->ev.cb) - timeout_set(&outgoing->ev, &(struct timeval){0, 0}); + timeout_set(&outgoing->ev, &(struct timeval) { + 0, 0 + }); } /* Check for outgoing connections that are in progress, and reset their ping timers */ for list_each(connection_t, c, connection_list) { - if(c->outgoing && !c->node) + if(c->outgoing && !c->node) { c->last_ping_time = 0; + } } /* Kick the ping timeout handler */ - timeout_set(&pingtimer, &(struct timeval){0, 0}); + timeout_set(&pingtimer, &(struct timeval) { + 0, 0 + }); } /* @@ -412,8 +465,12 @@ void retry(void) { */ int main_loop(void) { last_periodic_run_time = now; - timeout_add(&pingtimer, timeout_handler, &pingtimer, &(struct timeval){pingtimeout, rand() % 100000}); - timeout_add(&periodictimer, periodic_handler, &periodictimer, &(struct timeval){0, 0}); + timeout_add(&pingtimer, timeout_handler, &pingtimer, &(struct timeval) { + pingtimeout, rand() % 100000 + }); + timeout_add(&periodictimer, periodic_handler, &periodictimer, &(struct timeval) { + 0, 0 + }); #ifndef HAVE_MINGW signal_t sighup = {0}; diff --git a/src/net_packet.c b/src/net_packet.c index 2d430bc..5709d49 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -74,14 +74,17 @@ int udp_discovery_timeout = 30; #define MAX_SEQNO 1073741824 static void try_fix_mtu(node_t *n) { - if(n->mtuprobes < 0) + if(n->mtuprobes < 0) { return; + } if(n->mtuprobes == 20 || n->minmtu >= n->maxmtu) { - if(n->minmtu > n->maxmtu) + if(n->minmtu > n->maxmtu) { n->minmtu = n->maxmtu; - else + } else { n->maxmtu = n->minmtu; + } + n->mtu = n->minmtu; logger(DEBUG_TRAFFIC, LOG_INFO, "Fixing MTU of %s (%s) to %d after %d probes", n->name, n->hostname, n->mtu, n->mtuprobes); n->mtuprobes = -1; @@ -90,8 +93,10 @@ static void try_fix_mtu(node_t *n) { static void udp_probe_timeout_handler(void *data) { node_t *n = data; - if(!n->status.udp_confirmed) + + if(!n->status.udp_confirmed) { return; + } logger(DEBUG_TRAFFIC, LOG_INFO, "Too much time has elapsed since last UDP ping response from %s (%s), stopping UDP communication", n->name, n->hostname); n->status.udp_confirmed = false; @@ -108,7 +113,7 @@ static void send_udp_probe_reply(node_t *n, vpn_packet_t *packet, length_t len) } /* Type 2 probe replies were introduced in protocol 17.3 */ - if ((n->options >> 24) >= 3) { + if((n->options >> 24) >= 3) { DATA(packet)[0] = 2; uint16_t len16 = htons(len); memcpy(DATA(packet) + 1, &len16, 2); @@ -136,7 +141,7 @@ static void udp_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { return send_udp_probe_reply(n, packet, len); } - if (DATA(packet)[0] == 2) { + if(DATA(packet)[0] == 2) { // It's a type 2 probe reply, use the length field inside the packet uint16_t len16; memcpy(&len16, DATA(packet) + 1, 2); @@ -155,7 +160,9 @@ static void udp_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { if(udp_discovery) { timeout_del(&n->udp_ping_timeout); - timeout_add(&n->udp_ping_timeout, &udp_probe_timeout_handler, n, &(struct timeval){udp_discovery_timeout, 0}); + timeout_add(&n->udp_ping_timeout, &udp_probe_timeout_handler, n, &(struct timeval) { + udp_discovery_timeout, 0 + }); } if(len > n->maxmtu) { @@ -194,9 +201,10 @@ static length_t compress_packet(uint8_t *dest, const uint8_t *source, length_t l } else if(level < 10) { #ifdef HAVE_ZLIB unsigned long destlen = MAXSIZE; - if(compress2(dest, &destlen, source, len, level) == Z_OK) + + if(compress2(dest, &destlen, source, len, level) == Z_OK) { return destlen; - else + } else #endif return -1; } else { @@ -219,20 +227,25 @@ static length_t uncompress_packet(uint8_t *dest, const uint8_t *source, length_t } else if(level > 9) { #ifdef HAVE_LZO lzo_uint lzolen = MAXSIZE; - if(lzo1x_decompress_safe(source, len, dest, &lzolen, NULL) == LZO_E_OK) + + if(lzo1x_decompress_safe(source, len, dest, &lzolen, NULL) == LZO_E_OK) { return lzolen; - else + } else #endif return -1; } + #ifdef HAVE_ZLIB else { unsigned long destlen = MAXSIZE; - if(uncompress(dest, &destlen, source, len) == Z_OK) + + if(uncompress(dest, &destlen, source, len) == Z_OK) { return destlen; - else + } else { return -1; + } } + #endif return -1; @@ -242,7 +255,7 @@ static length_t uncompress_packet(uint8_t *dest, const uint8_t *source, length_t static void receive_packet(node_t *n, vpn_packet_t *packet) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Received packet of %d bytes from %s (%s)", - packet->len, n->name, n->hostname); + packet->len, n->name, n->hostname); n->in_packets++; n->in_bytes += packet->len; @@ -251,14 +264,17 @@ static void receive_packet(node_t *n, vpn_packet_t *packet) { } static bool try_mac(node_t *n, const vpn_packet_t *inpkt) { - if(n->status.sptps) + if(n->status.sptps) { return sptps_verify_datagram(&n->sptps, DATA(inpkt), inpkt->len); + } #ifdef DISABLE_LEGACY return false; #else - if(!n->status.validkey_in || !digest_active(n->indigest) || inpkt->len < sizeof(seqno_t) + digest_length(n->indigest)) + + if(!n->status.validkey_in || !digest_active(n->indigest) || inpkt->len < sizeof(seqno_t) + digest_length(n->indigest)) { return false; + } return digest_verify(n->indigest, inpkt->data, inpkt->len - digest_length(n->indigest), inpkt->data + inpkt->len - digest_length(n->indigest)); #endif @@ -280,8 +296,10 @@ static bool receive_udppacket(node_t *n, vpn_packet_t *inpkt) { } else { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet", n->name, n->hostname); } + return false; } + n->status.udppacket = true; bool result = sptps_receive_data(&n->sptps, DATA(inpkt), inpkt->len); n->status.udppacket = false; @@ -295,14 +313,17 @@ static bool receive_udppacket(node_t *n, vpn_packet_t *inpkt) { logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode raw TCP packet from %s (%s), restarting SPTPS", n->name, n->hostname); send_req_key(n); } + return false; } + return true; } #ifdef DISABLE_LEGACY return false; #else + if(!n->status.validkey_in) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet", n->name, n->hostname); return false; @@ -312,7 +333,7 @@ static bool receive_udppacket(node_t *n, vpn_packet_t *inpkt) { if(inpkt->len < sizeof(seqno_t) + digest_length(n->indigest)) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got too short packet from %s (%s)", - n->name, n->hostname); + n->name, n->hostname); return false; } @@ -324,11 +345,13 @@ static bool receive_udppacket(node_t *n, vpn_packet_t *inpkt) { if(digest_active(n->indigest)) { inpkt->len -= digest_length(n->indigest); + if(!digest_verify(n->indigest, SEQNO(inpkt), inpkt->len, SEQNO(inpkt) + inpkt->len)) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got unauthenticated packet from %s (%s)", n->name, n->hostname); return false; } } + /* Decrypt the packet */ if(cipher_active(n->incipher)) { @@ -356,21 +379,23 @@ static bool receive_udppacket(node_t *n, vpn_packet_t *inpkt) { if(seqno >= n->received_seqno + replaywin * 8) { if(n->farfuture++ < replaywin >> 2) { logger(DEBUG_TRAFFIC, LOG_WARNING, "Packet from %s (%s) is %d seqs in the future, dropped (%u)", - n->name, n->hostname, seqno - n->received_seqno - 1, n->farfuture); + n->name, n->hostname, seqno - n->received_seqno - 1, n->farfuture); return false; } + logger(DEBUG_TRAFFIC, LOG_WARNING, "Lost %d packets from %s (%s)", - seqno - n->received_seqno - 1, n->name, n->hostname); + seqno - n->received_seqno - 1, n->name, n->hostname); memset(n->late, 0, replaywin); - } else if (seqno <= n->received_seqno) { + } else if(seqno <= n->received_seqno) { if((n->received_seqno >= replaywin * 8 && seqno <= n->received_seqno - replaywin * 8) || !(n->late[(seqno / 8) % replaywin] & (1 << seqno % 8))) { logger(DEBUG_TRAFFIC, LOG_WARNING, "Got late or replayed packet from %s (%s), seqno %d, last received %d", - n->name, n->hostname, seqno, n->received_seqno); + n->name, n->hostname, seqno, n->received_seqno); return false; } } else { - for(int i = n->received_seqno + 1; i < seqno; i++) + for(int i = n->received_seqno + 1; i < seqno; i++) { n->late[(i / 8) % replaywin] |= 1 << i % 8; + } } } @@ -378,13 +403,15 @@ static bool receive_udppacket(node_t *n, vpn_packet_t *inpkt) { n->late[(seqno / 8) % replaywin] &= ~(1 << seqno % 8); } - if(seqno > n->received_seqno) + if(seqno > n->received_seqno) { n->received_seqno = seqno; + } n->received++; - if(n->received_seqno > MAX_SEQNO) + if(n->received_seqno > MAX_SEQNO) { regenerate_key(); + } /* Decompress the packet */ @@ -395,24 +422,27 @@ static bool receive_udppacket(node_t *n, vpn_packet_t *inpkt) { if((outpkt->len = uncompress_packet(DATA(outpkt), DATA(inpkt), inpkt->len, n->incompression)) < 0) { logger(DEBUG_TRAFFIC, LOG_ERR, "Error while uncompressing packet from %s (%s)", - n->name, n->hostname); + n->name, n->hostname); return false; } inpkt = outpkt; - origlen -= MTU/64 + 20; + origlen -= MTU / 64 + 20; } - if(inpkt->len > n->maxrecentlen) + if(inpkt->len > n->maxrecentlen) { n->maxrecentlen = inpkt->len; + } inpkt->priority = 0; - if(!DATA(inpkt)[12] && !DATA(inpkt)[13]) + if(!DATA(inpkt)[12] && !DATA(inpkt)[13]) { udp_probe_h(n, inpkt, origlen); - else + } else { receive_packet(n, inpkt); + } + return true; #endif } @@ -421,34 +451,42 @@ void receive_tcppacket(connection_t *c, const char *buffer, int len) { vpn_packet_t outpkt; outpkt.offset = DEFAULT_PACKET_OFFSET; - if(len > sizeof(outpkt.data) - outpkt.offset) + if(len > sizeof(outpkt.data) - outpkt.offset) { return; + } outpkt.len = len; - if(c->options & OPTION_TCPONLY) + + if(c->options & OPTION_TCPONLY) { outpkt.priority = 0; - else + } else { outpkt.priority = -1; + } + memcpy(DATA(&outpkt), buffer, len); receive_packet(c->node, &outpkt); } bool receive_tcppacket_sptps(connection_t *c, const char *data, int len) { - if (len < sizeof(node_id_t) + sizeof(node_id_t)) { + if(len < sizeof(node_id_t) + sizeof(node_id_t)) { logger(DEBUG_PROTOCOL, LOG_ERR, "Got too short TCP SPTPS packet from %s (%s)", c->name, c->hostname); return false; } node_t *to = lookup_node_id((node_id_t *)data); - data += sizeof(node_id_t); len -= sizeof(node_id_t); + data += sizeof(node_id_t); + len -= sizeof(node_id_t); + if(!to) { logger(DEBUG_PROTOCOL, LOG_ERR, "Got TCP SPTPS packet from %s (%s) with unknown destination ID", c->name, c->hostname); return true; } node_t *from = lookup_node_id((node_id_t *)data); - data += sizeof(node_id_t); len -= sizeof(node_id_t); + data += sizeof(node_id_t); + len -= sizeof(node_id_t); + if(!from) { logger(DEBUG_PROTOCOL, LOG_ERR, "Got TCP SPTPS packet from %s (%s) with unknown source ID", c->name, c->hostname); return true; @@ -464,8 +502,9 @@ bool receive_tcppacket_sptps(connection_t *c, const char *data, int len) { /* Help the sender reach us over UDP. Note that we only do this if we're the destination or the static relay; otherwise every hop would initiate its own UDP info message, resulting in elevated chatter. */ - if(to->via == myself) + if(to->via == myself) { send_udp_info(myself, from); + } /* If we're not the final recipient, relay the packet. */ @@ -485,6 +524,7 @@ bool receive_tcppacket_sptps(connection_t *c, const char *data, int len) { logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode raw TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname); send_req_key(from); } + return true; } @@ -493,8 +533,9 @@ bool receive_tcppacket_sptps(connection_t *c, const char *data, int len) { } static void send_sptps_packet(node_t *n, vpn_packet_t *origpkt) { - if(!n->status.validkey && !n->connection) + if(!n->status.validkey && !n->connection) { return; + } uint8_t type = 0; int offset = 0; @@ -504,19 +545,22 @@ static void send_sptps_packet(node_t *n, vpn_packet_t *origpkt) { return; } - if(routing_mode == RMODE_ROUTER) + if(routing_mode == RMODE_ROUTER) { offset = 14; - else + } else { type = PKT_MAC; + } - if(origpkt->len < offset) + if(origpkt->len < offset) { return; + } vpn_packet_t outpkt; if(n->outcompression) { outpkt.offset = 0; int len = compress_packet(DATA(&outpkt) + offset, DATA(origpkt) + offset, origpkt->len - offset, n->outcompression); + if(len < 0) { logger(DEBUG_TRAFFIC, LOG_ERR, "Error while compressing packet to %s (%s)", n->name, n->hostname); } else if(len < origpkt->len - offset) { @@ -530,10 +574,12 @@ static void send_sptps_packet(node_t *n, vpn_packet_t *origpkt) { don't bother with SPTPS and just use a "plaintext" PACKET message. We don't really care about end-to-end security since we're not sending the message through any intermediate nodes. */ - if(n->connection && origpkt->len > n->minmtu) + if(n->connection && origpkt->len > n->minmtu) { send_tcppacket(n->connection, origpkt); - else + } else { sptps_send_record(&n->sptps, type, DATA(origpkt) + offset, origpkt->len - offset); + } + return; } @@ -555,14 +601,16 @@ static void choose_udp_address(const node_t *n, const sockaddr_t **sa, int *sock *sock = n->sock; /* If the UDP address is confirmed, use it. */ - if(n->status.udp_confirmed) + if(n->status.udp_confirmed) { return; + } /* Send every third packet to n->address; that could be set to the node's reflexive UDP address discovered during key exchange. */ static int x = 0; + if(++x >= 3) { x = 0; return; @@ -606,7 +654,7 @@ static void choose_local_address(const node_t *n, const sockaddr_t **sa, int *so } } - if (candidate && candidate->local_address.sa.sa_family) { + if(candidate && candidate->local_address.sa.sa_family) { *sa = &candidate->local_address; *sock = rand() % listen_sockets; adapt_socket(*sa, sock); @@ -631,8 +679,9 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { return; } - if(n->status.sptps) + if(n->status.sptps) { return send_sptps_packet(n, origpkt); + } #ifdef DISABLE_LEGACY return; @@ -641,21 +690,22 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { if(!n->status.validkey) { logger(DEBUG_TRAFFIC, LOG_INFO, - "No valid key known yet for %s (%s), forwarding via TCP", - n->name, n->hostname); + "No valid key known yet for %s (%s), forwarding via TCP", + n->name, n->hostname); send_tcppacket(n->nexthop->connection, origpkt); return; } if(n->options & OPTION_PMTU_DISCOVERY && inpkt->len > n->minmtu && (DATA(inpkt)[12] | DATA(inpkt)[13])) { logger(DEBUG_TRAFFIC, LOG_INFO, - "Packet for %s (%s) larger than minimum MTU, forwarding via %s", - n->name, n->hostname, n != n->nexthop ? n->nexthop->name : "TCP"); + "Packet for %s (%s) larger than minimum MTU, forwarding via %s", + n->name, n->hostname, n != n->nexthop ? n->nexthop->name : "TCP"); - if(n != n->nexthop) + if(n != n->nexthop) { send_packet(n->nexthop, origpkt); - else + } else { send_tcppacket(n->nexthop->connection, origpkt); + } return; } @@ -667,7 +717,7 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { if((outpkt->len = compress_packet(DATA(outpkt), DATA(inpkt), inpkt->len, n->outcompression)) < 0) { logger(DEBUG_TRAFFIC, LOG_ERR, "Error while compressing packet to %s (%s)", - n->name, n->hostname); + n->name, n->hostname); return; } @@ -711,28 +761,41 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { const sockaddr_t *sa = NULL; int sock; - if(n->status.send_locally) + if(n->status.send_locally) { choose_local_address(n, &sa, &sock); - if(!sa) + } + + if(!sa) { choose_udp_address(n, &sa, &sock); + } if(priorityinheritance && origpriority != listen_socket[sock].priority) { listen_socket[sock].priority = origpriority; + switch(sa->sa.sa_family) { #if defined(IPPROTO_IP) && defined(IP_TOS) + case AF_INET: logger(DEBUG_TRAFFIC, LOG_DEBUG, "Setting IPv4 outgoing packet priority to %d", origpriority); - if(setsockopt(listen_socket[sock].udp.fd, IPPROTO_IP, IP_TOS, (void *)&origpriority, sizeof(origpriority))) /* SO_PRIORITY doesn't seem to work */ + + if(setsockopt(listen_socket[sock].udp.fd, IPPROTO_IP, IP_TOS, (void *)&origpriority, sizeof(origpriority))) { /* SO_PRIORITY doesn't seem to work */ logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setsockopt", sockstrerror(sockerrno)); + } + break; #endif #if defined(IPPROTO_IPV6) & defined(IPV6_TCLASS) + case AF_INET6: logger(DEBUG_TRAFFIC, LOG_DEBUG, "Setting IPv6 outgoing packet priority to %d", origpriority); - if(setsockopt(listen_socket[sock].udp.fd, IPPROTO_IPV6, IPV6_TCLASS, (void *)&origpriority, sizeof(origpriority))) /* SO_PRIORITY doesn't seem to work */ + + if(setsockopt(listen_socket[sock].udp.fd, IPPROTO_IPV6, IPV6_TCLASS, (void *)&origpriority, sizeof(origpriority))) { /* SO_PRIORITY doesn't seem to work */ logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setsockopt", sockstrerror(sockerrno)); + } + break; #endif + default: break; } @@ -740,13 +803,18 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { if(sendto(listen_socket[sock].udp.fd, (void *)SEQNO(inpkt), inpkt->len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) { if(sockmsgsize(sockerrno)) { - if(n->maxmtu >= origlen) + if(n->maxmtu >= origlen) { n->maxmtu = origlen - 1; - if(n->mtu >= origlen) + } + + if(n->mtu >= origlen) { n->mtu = origlen - 1; + } + try_fix_mtu(n); - } else + } else { logger(DEBUG_TRAFFIC, LOG_WARNING, "Error sending packet to %s (%s): %s", n->name, n->hostname, sockstrerror(sockerrno)); + } } end: @@ -764,9 +832,12 @@ bool send_sptps_data(node_t *to, node_t *from, int type, const void *data, size_ if(type == SPTPS_HANDSHAKE || tcponly || (!direct && !relay_supported) || (type != PKT_PROBE && (len - SPTPS_DATAGRAM_OVERHEAD) > relay->minmtu)) { if(type != SPTPS_HANDSHAKE && (to->nexthop->connection->options >> 24) >= 7) { - char buf[len + sizeof(to->id) + sizeof from->id]; char* buf_ptr = buf; - memcpy(buf_ptr, &to->id, sizeof(to->id)); buf_ptr += sizeof to->id; - memcpy(buf_ptr, &from->id, sizeof(from->id)); buf_ptr += sizeof from->id; + char buf[len + sizeof(to->id) + sizeof from->id]; + char *buf_ptr = buf; + memcpy(buf_ptr, &to->id, sizeof(to->id)); + buf_ptr += sizeof to->id; + memcpy(buf_ptr, &from->id, sizeof(from->id)); + buf_ptr += sizeof from->id; memcpy(buf_ptr, data, len); logger(DEBUG_TRAFFIC, LOG_INFO, "Sending packet from %s (%s) to %s (%s) via %s (%s) (TCP)", from->name, from->hostname, to->name, to->hostname, to->nexthop->name, to->nexthop->hostname); return send_sptps_tcppacket(to->nexthop->connection, buf, sizeof(buf)); @@ -774,6 +845,7 @@ bool send_sptps_data(node_t *to, node_t *from, int type, const void *data, size_ char buf[len * 4 / 3 + 5]; b64encode(data, buf, len); + /* If this is a handshake packet, use ANS_KEY instead of REQ_KEY, for two reasons: - We don't want intermediate nodes to switch to UDP to relay these packets; - ANS_KEY allows us to learn the reflexive UDP address. */ @@ -786,37 +858,60 @@ bool send_sptps_data(node_t *to, node_t *from, int type, const void *data, size_ } size_t overhead = 0; - if(relay_supported) overhead += sizeof(to->id) + sizeof from->id; - char buf[len + overhead]; char* buf_ptr = buf; + + if(relay_supported) { + overhead += sizeof(to->id) + sizeof from->id; + } + + char buf[len + overhead]; + char *buf_ptr = buf; + if(relay_supported) { if(direct) { /* Inform the recipient that this packet was sent directly. */ node_id_t nullid = {}; - memcpy(buf_ptr, &nullid, sizeof(nullid)); buf_ptr += sizeof nullid; + memcpy(buf_ptr, &nullid, sizeof(nullid)); + buf_ptr += sizeof nullid; } else { - memcpy(buf_ptr, &to->id, sizeof(to->id)); buf_ptr += sizeof to->id; + memcpy(buf_ptr, &to->id, sizeof(to->id)); + buf_ptr += sizeof to->id; } - memcpy(buf_ptr, &from->id, sizeof(from->id)); buf_ptr += sizeof from->id; + + memcpy(buf_ptr, &from->id, sizeof(from->id)); + buf_ptr += sizeof from->id; } + /* TODO: if this copy turns out to be a performance concern, change sptps_send_record() to add some "pre-padding" to the buffer and use that instead */ - memcpy(buf_ptr, data, len); buf_ptr += len; + memcpy(buf_ptr, data, len); + buf_ptr += len; const sockaddr_t *sa = NULL; int sock; - if(relay->status.send_locally) + + if(relay->status.send_locally) { choose_local_address(relay, &sa, &sock); - if(!sa) + } + + if(!sa) { choose_udp_address(relay, &sa, &sock); + } + logger(DEBUG_TRAFFIC, LOG_INFO, "Sending packet from %s (%s) to %s (%s) via %s (%s) (UDP)", from->name, from->hostname, to->name, to->hostname, relay->name, relay->hostname); + if(sendto(listen_socket[sock].udp.fd, buf, buf_ptr - buf, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) { if(sockmsgsize(sockerrno)) { // Compensate for SPTPS overhead len -= SPTPS_DATAGRAM_OVERHEAD; - if(relay->maxmtu >= len) + + if(relay->maxmtu >= len) { relay->maxmtu = len - 1; - if(relay->mtu >= len) + } + + if(relay->mtu >= len) { relay->mtu = len - 1; + } + try_fix_mtu(relay); } else { logger(DEBUG_TRAFFIC, LOG_WARNING, "Error sending UDP SPTPS packet to %s (%s): %s", relay->name, relay->hostname, sockstrerror(sockerrno)); @@ -836,6 +931,7 @@ bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t from->status.waitingforkey = false; logger(DEBUG_META, LOG_INFO, "SPTPS key exchange with %s (%s) succesful", from->name, from->hostname); } + return true; } @@ -853,10 +949,14 @@ bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t logger(DEBUG_ALWAYS, LOG_ERR, "Got SPTPS PROBE packet from %s (%s) via TCP", from->name, from->hostname); return false; } + inpkt.len = len; memcpy(DATA(&inpkt), data, len); - if(inpkt.len > from->maxrecentlen) + + if(inpkt.len > from->maxrecentlen) { from->maxrecentlen = inpkt.len; + } + udp_probe_h(from, &inpkt, len); return true; } @@ -875,15 +975,19 @@ bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t } int offset = (type & PKT_MAC) ? 0 : 14; + if(type & PKT_COMPRESSED) { length_t ulen = uncompress_packet(DATA(&inpkt) + offset, (const uint8_t *)data, len, from->incompression); + if(ulen < 0) { return false; } else { inpkt.len = ulen + offset; } - if(inpkt.len > MAXSIZE) + + if(inpkt.len > MAXSIZE) { abort(); + } } else { memcpy(DATA(&inpkt) + offset, data, len); inpkt.len = len + offset; @@ -892,24 +996,27 @@ bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t /* Generate the Ethernet packet type if necessary */ if(offset) { switch(DATA(&inpkt)[14] >> 4) { - case 4: - DATA(&inpkt)[12] = 0x08; - DATA(&inpkt)[13] = 0x00; - break; - case 6: - DATA(&inpkt)[12] = 0x86; - DATA(&inpkt)[13] = 0xDD; - break; - default: - logger(DEBUG_TRAFFIC, LOG_ERR, - "Unknown IP version %d while reading packet from %s (%s)", - DATA(&inpkt)[14] >> 4, from->name, from->hostname); - return false; + case 4: + DATA(&inpkt)[12] = 0x08; + DATA(&inpkt)[13] = 0x00; + break; + + case 6: + DATA(&inpkt)[12] = 0x86; + DATA(&inpkt)[13] = 0xDD; + break; + + default: + logger(DEBUG_TRAFFIC, LOG_ERR, + "Unknown IP version %d while reading packet from %s (%s)", + DATA(&inpkt)[14] >> 4, from->name, from->hostname); + return false; } } - if(from->status.udppacket && inpkt.len > from->maxrecentlen) + if(from->status.udppacket && inpkt.len > from->maxrecentlen) { from->maxrecentlen = inpkt.len; + } receive_packet(from, &inpkt); return true; @@ -918,14 +1025,15 @@ bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t // This function tries to get SPTPS keys, if they aren't already known. // This function makes no guarantees - it is up to the caller to check the node's state to figure out if the keys are available. static void try_sptps(node_t *n) { - if(n->status.validkey) + if(n->status.validkey) { return; + } logger(DEBUG_TRAFFIC, LOG_INFO, "No valid key known yet for %s (%s)", n->name, n->hostname); - if(!n->status.waitingforkey) + if(!n->status.waitingforkey) { send_req_key(n); - else if(n->last_req_key + 10 < now.tv_sec) { + } else if(n->last_req_key + 10 < now.tv_sec) { logger(DEBUG_ALWAYS, LOG_DEBUG, "No key from %s after 10 seconds, restarting SPTPS", n->name); sptps_stop(&n->sptps); n->status.waitingforkey = false; @@ -951,9 +1059,10 @@ static void send_udp_probe_packet(node_t *n, int len) { // This function tries to establish a UDP tunnel to a node so that packets can be sent. // If a tunnel is already established, it makes sure it stays up. // This function makes no guarantees - it is up to the caller to check the node's state to figure out if UDP is usable. -static void try_udp(node_t* n) { - if(!udp_discovery) +static void try_udp(node_t *n) { + if(!udp_discovery) { return; + } /* Send gratuitous probe replies to 1.1 nodes. */ @@ -963,6 +1072,7 @@ static void try_udp(node_t* n) { if(ping_tx_elapsed.tv_sec >= udp_discovery_keepalive_interval - 1) { n->udp_reply_sent = now; + if(n->maxrecentlen) { vpn_packet_t pkt; pkt.len = n->maxrecentlen; @@ -1002,10 +1112,13 @@ static length_t choose_initial_maxmtu(node_t *n) { const sockaddr_t *sa = NULL; int sockindex; choose_udp_address(n, &sa, &sockindex); - if(!sa) + + if(!sa) { return MTU; + } sock = socket(sa->sa.sa_family, SOCK_DGRAM, IPPROTO_UDP); + if(sock < 0) { logger(DEBUG_TRAFFIC, LOG_ERR, "Creating MTU assessment socket for %s (%s) failed: %s", n->name, n->hostname, sockstrerror(sockerrno)); return MTU; @@ -1019,6 +1132,7 @@ static length_t choose_initial_maxmtu(node_t *n) { int ip_mtu; socklen_t ip_mtu_len = sizeof(ip_mtu); + if(getsockopt(sock, IPPROTO_IP, IP_MTU, &ip_mtu, &ip_mtu_len)) { logger(DEBUG_TRAFFIC, LOG_ERR, "getsockopt(IP_MTU) on %s (%s) failed: %s", n->name, n->hostname, sockstrerror(sockerrno)); close(sock); @@ -1032,10 +1146,14 @@ static length_t choose_initial_maxmtu(node_t *n) { length_t mtu = ip_mtu; mtu -= (sa->sa.sa_family == AF_INET6) ? sizeof(struct ip6_hdr) : sizeof(struct ip); mtu -= 8; /* UDP */ + if(n->status.sptps) { mtu -= SPTPS_DATAGRAM_OVERHEAD; - if((n->options >> 24) >= 4) + + if((n->options >> 24) >= 4) { mtu -= sizeof(node_id_t) + sizeof(node_id_t); + } + #ifndef DISABLE_LEGACY } else { mtu -= digest_length(n->outdigest); @@ -1059,12 +1177,14 @@ static length_t choose_initial_maxmtu(node_t *n) { #endif } - if (mtu < 512) { + if(mtu < 512) { logger(DEBUG_TRAFFIC, LOG_ERR, "getsockopt(IP_MTU) on %s (%s) returned absurdly small value: %d", n->name, n->hostname, ip_mtu); return MTU; } - if (mtu > MTU) + + if(mtu > MTU) { return MTU; + } logger(DEBUG_TRAFFIC, LOG_INFO, "Using system-provided maximum tinc MTU for %s (%s): %hd", n->name, n->hostname, mtu); return mtu; @@ -1083,8 +1203,9 @@ static length_t choose_initial_maxmtu(node_t *n) { */ static void try_mtu(node_t *n) { - if(!(n->options & OPTION_PMTU_DISCOVERY)) + if(!(n->options & OPTION_PMTU_DISCOVERY)) { return; + } if(udp_discovery && !n->status.udp_confirmed) { n->maxrecentlen = 0; @@ -1102,16 +1223,20 @@ static void try_mtu(node_t *n) { struct timeval elapsed; timersub(&now, &n->mtu_ping_sent, &elapsed); + if(n->mtuprobes >= 0) { - if(n->mtuprobes != 0 && elapsed.tv_sec == 0 && elapsed.tv_usec < 333333) + if(n->mtuprobes != 0 && elapsed.tv_sec == 0 && elapsed.tv_usec < 333333) { return; + } } else { if(n->mtuprobes < -1) { - if(elapsed.tv_sec < 1) + if(elapsed.tv_sec < 1) { return; + } } else { - if(elapsed.tv_sec < pinginterval) + if(elapsed.tv_sec < pinginterval) { return; + } } } @@ -1130,16 +1255,20 @@ static void try_mtu(node_t *n) { /* After the initial discovery, we only send one maxmtu and one maxmtu+1 probe to detect PMTU increases. */ send_udp_probe_packet(n, n->maxmtu); - if(n->mtuprobes == -1 && n->maxmtu + 1 < MTU) + + if(n->mtuprobes == -1 && n->maxmtu + 1 < MTU) { send_udp_probe_packet(n, n->maxmtu + 1); + } + n->mtuprobes--; } else { /* Before initial discovery begins, set maxmtu to the most likely value. If it's underestimated, we will correct it after initial discovery. */ - if(n->mtuprobes == 0) + if(n->mtuprobes == 0) { n->maxmtu = choose_initial_maxmtu(n); + } - for (;;) { + for(;;) { /* Decreasing the number of probes per cycle might make the algorithm react faster to lost packets, but it will typically increase convergence time in the no-loss case. */ const length_t probes_per_cycle = 8; @@ -1168,14 +1297,17 @@ static void try_mtu(node_t *n) { length_t maxmtu = n->maxmtu; send_udp_probe_packet(n, minmtu + offset); + /* If maxmtu changed, it means the probe was rejected by the system because it was too large. In that case, we recalculate with the new maxmtu and try again. */ - if(n->mtuprobes < 0 || maxmtu == n->maxmtu) + if(n->mtuprobes < 0 || maxmtu == n->maxmtu) { break; + } } - if(n->mtuprobes >= 0) + if(n->mtuprobes >= 0) { n->mtuprobes++; + } } } @@ -1196,8 +1328,9 @@ static void try_tx_sptps(node_t *n, bool mtu) { /* If n is a TCP-only neighbor, we'll only use "cleartext" PACKET messages anyway, so there's no need for SPTPS at all. */ - if(n->connection && ((myself->options | n->options) & OPTION_TCPONLY)) + if(n->connection && ((myself->options | n->options) & OPTION_TCPONLY)) { return; + } /* Otherwise, try to do SPTPS authentication with n if necessary. */ @@ -1210,29 +1343,35 @@ static void try_tx_sptps(node_t *n, bool mtu) { /* If we do have a static relay, try everything with that one instead, if it supports relaying. */ if(via != n) { - if((via->options >> 24) < 4) + if((via->options >> 24) < 4) { return; + } + return try_tx(via, mtu); } /* Otherwise, try to establish UDP connectivity. */ try_udp(n); - if(mtu) + + if(mtu) { try_mtu(n); + } /* If we don't have UDP connectivity (yet), we need to use a dynamic relay (nexthop) while we try to establish direct connectivity. */ - if(!n->status.udp_confirmed && n != n->nexthop && (n->nexthop->options >> 24) >= 4) + if(!n->status.udp_confirmed && n != n->nexthop && (n->nexthop->options >> 24) >= 4) { try_tx(n->nexthop, mtu); + } } static void try_tx_legacy(node_t *n, bool mtu) { /* Does he have our key? If not, send one. */ - if(!n->status.validkey_in) + if(!n->status.validkey_in) { send_ans_key(n); + } /* Check if we already have a key, or request one. */ @@ -1241,21 +1380,27 @@ static void try_tx_legacy(node_t *n, bool mtu) { send_req_key(n); n->last_req_key = now.tv_sec; } + return; } try_udp(n); - if(mtu) + + if(mtu) { try_mtu(n); + } } void try_tx(node_t *n, bool mtu) { - if(!n->status.reachable) + if(!n->status.reachable) { return; - if(n->status.sptps) + } + + if(n->status.sptps) { try_tx_sptps(n, mtu); - else + } else { try_tx_legacy(n, mtu); + } } void send_packet(node_t *n, vpn_packet_t *packet) { @@ -1263,11 +1408,12 @@ void send_packet(node_t *n, vpn_packet_t *packet) { if(n == myself) { if(overwrite_mac) { - memcpy(DATA(packet), mymac.x, ETH_ALEN); - // Use an arbitrary fake source address. - memcpy(DATA(packet) + ETH_ALEN, DATA(packet), ETH_ALEN); - DATA(packet)[ETH_ALEN * 2 - 1] ^= 0xFF; + memcpy(DATA(packet), mymac.x, ETH_ALEN); + // Use an arbitrary fake source address. + memcpy(DATA(packet) + ETH_ALEN, DATA(packet), ETH_ALEN); + DATA(packet)[ETH_ALEN * 2 - 1] ^= 0xFF; } + n->out_packets++; n->out_bytes += packet->len; devops.write(packet); @@ -1300,14 +1446,17 @@ void send_packet(node_t *n, vpn_packet_t *packet) { node_t *via = (packet->priority == -1 || n->via == myself) ? n->nexthop : n->via; - if(via != n) + if(via != n) { logger(DEBUG_TRAFFIC, LOG_INFO, "Sending packet to %s via %s (%s)", n->name, via->name, n->via->hostname); + } // Try to send via UDP, unless TCP is forced. if(packet->priority == -1 || ((myself->options | via->options) & OPTION_TCPONLY)) { - if(!send_tcppacket(via->connection, packet)) + if(!send_tcppacket(via->connection, packet)) { terminate_connection(via->connection, true); + } + return; } @@ -1317,41 +1466,48 @@ void send_packet(node_t *n, vpn_packet_t *packet) { void broadcast_packet(const node_t *from, vpn_packet_t *packet) { // Always give ourself a copy of the packet. - if(from != myself) + if(from != myself) { send_packet(myself, packet); + } // In TunnelServer mode, do not forward broadcast packets. // The MST might not be valid and create loops. - if(tunnelserver || broadcast_mode == BMODE_NONE) + if(tunnelserver || broadcast_mode == BMODE_NONE) { return; + } logger(DEBUG_TRAFFIC, LOG_INFO, "Broadcasting packet of %d bytes from %s (%s)", - packet->len, from->name, from->hostname); + packet->len, from->name, from->hostname); switch(broadcast_mode) { - // In MST mode, broadcast packets travel via the Minimum Spanning Tree. - // This guarantees all nodes receive the broadcast packet, and - // usually distributes the sending of broadcast packets over all nodes. - case BMODE_MST: - for list_each(connection_t, c, connection_list) - if(c->edge && c->status.mst && c != from->nexthop->connection) - send_packet(c->node, packet); - break; + // In MST mode, broadcast packets travel via the Minimum Spanning Tree. + // This guarantees all nodes receive the broadcast packet, and + // usually distributes the sending of broadcast packets over all nodes. + case BMODE_MST: + for list_each(connection_t, c, connection_list) + if(c->edge && c->status.mst && c != from->nexthop->connection) { + send_packet(c->node, packet); + } - // In direct mode, we send copies to each node we know of. - // However, this only reaches nodes that can be reached in a single hop. - // We don't have enough information to forward broadcast packets in this case. - case BMODE_DIRECT: - if(from != myself) - break; + break; - for splay_each(node_t, n, node_tree) - if(n->status.reachable && n != myself && ((n->via == myself && n->nexthop == n) || n->via == n)) - send_packet(n, packet); + // In direct mode, we send copies to each node we know of. + // However, this only reaches nodes that can be reached in a single hop. + // We don't have enough information to forward broadcast packets in this case. + case BMODE_DIRECT: + if(from != myself) { break; + } - default: - break; + for splay_each(node_t, n, node_tree) + if(n->status.reachable && n != myself && ((n->via == myself && n->nexthop == n) || n->via == n)) { + send_packet(n, packet); + } + + break; + + default: + break; } } @@ -1367,17 +1523,21 @@ static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) { static time_t last_hard_try = 0; for splay_each(node_t, n, node_tree) { - if(!n->status.reachable || n == myself) + if(!n->status.reachable || n == myself) { continue; + } - if(!n->status.validkey_in && !(n->status.sptps && n->sptps.instate)) + if(!n->status.validkey_in && !(n->status.sptps && n->sptps.instate)) { continue; + } bool soft = false; for splay_each(edge_t, e, n->edge_tree) { - if(!e->reverse) + if(!e->reverse) { continue; + } + if(!sockaddrcmp_noport(from, &e->reverse->address)) { soft = true; break; @@ -1385,20 +1545,24 @@ static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) { } if(!soft) { - if(last_hard_try == now.tv_sec) + if(last_hard_try == now.tv_sec) { continue; + } + hard = true; } - if(!try_mac(n, pkt)) + if(!try_mac(n, pkt)) { continue; + } match = n; break; } - if(hard) + if(hard) { last_hard_try = now.tv_sec; + } return match; } @@ -1415,18 +1579,21 @@ static void handle_incoming_vpn_packet(listen_socket_t *ls, vpn_packet_t *pkt, s node_t *n = lookup_node_udp(addr); - if(n && !n->status.udp_confirmed) - n = NULL; // Don't believe it if we don't have confirmation yet. + if(n && !n->status.udp_confirmed) { + n = NULL; // Don't believe it if we don't have confirmation yet. + } if(!n) { // It might be from a 1.1 node, which might have a source ID in the packet. pkt->offset = 2 * sizeof(node_id_t); from = lookup_node_id(SRCID(pkt)); + if(from && !memcmp(DSTID(pkt), &nullid, sizeof(nullid)) && from->status.sptps) { - if(sptps_verify_datagram(&from->sptps, DATA(pkt), pkt->len - 2 * sizeof(node_id_t))) + if(sptps_verify_datagram(&from->sptps, DATA(pkt), pkt->len - 2 * sizeof(node_id_t))) { n = from; - else + } else { goto skip_harder; + } } } @@ -1436,12 +1603,14 @@ static void handle_incoming_vpn_packet(listen_socket_t *ls, vpn_packet_t *pkt, s } skip_harder: + if(!n) { if(debug_level >= DEBUG_PROTOCOL) { hostname = sockaddr2hostname(addr); logger(DEBUG_PROTOCOL, LOG_WARNING, "Received UDP packet from unknown source %s", hostname); free(hostname); } + return; } @@ -1449,7 +1618,8 @@ skip_harder: if(n->status.sptps) { bool relay_enabled = (n->options >> 24) >= 4; - if (relay_enabled) { + + if(relay_enabled) { pkt->offset = 2 * sizeof(node_id_t); pkt->len -= pkt->offset; } @@ -1462,6 +1632,7 @@ skip_harder: from = lookup_node_id(SRCID(pkt)); to = lookup_node_id(DSTID(pkt)); } + if(!from || !to) { logger(DEBUG_PROTOCOL, LOG_WARNING, "Received UDP packet from %s (%s) with unknown source and/or destination ID", n->name, n->hostname); return; @@ -1480,8 +1651,9 @@ skip_harder: Note that we only do this if we're the destination or the static relay; otherwise every hop would initiate its own UDP info message, resulting in elevated chatter. */ - if(n != from->via && to->via == myself) + if(n != from->via && to->via == myself) { send_udp_info(myself, from); + } /* If we're not the final recipient, relay the packet. */ @@ -1495,18 +1667,22 @@ skip_harder: from = n; } - if(!receive_udppacket(from, pkt)) + if(!receive_udppacket(from, pkt)) { return; + } n->sock = ls - listen_socket; - if(direct && sockaddrcmp(addr, &n->address)) + + if(direct && sockaddrcmp(addr, &n->address)) { update_node_udp(n, addr); + } /* If the packet went through a relay, help the sender find the appropriate MTU through the relay path. */ - if(!direct) + if(!direct) { send_mtu_info(myself, n, MTU); + } } void handle_incoming_vpn_data(void *data, int flags) { @@ -1523,33 +1699,39 @@ void handle_incoming_vpn_data(void *data, int flags) { for(int i = 0; i < num; i++) { pkt[i].offset = 0; - iov[i] = (struct iovec){ + iov[i] = (struct iovec) { .iov_base = DATA(&pkt[i]), - .iov_len = MAXSIZE, + .iov_len = MAXSIZE, }; - msg[i].msg_hdr = (struct msghdr){ + msg[i].msg_hdr = (struct msghdr) { .msg_name = &addr[i].sa, - .msg_namelen = sizeof(addr)[i], - .msg_iov = &iov[i], - .msg_iovlen = 1, + .msg_namelen = sizeof(addr)[i], + .msg_iov = &iov[i], + .msg_iovlen = 1, }; } num = recvmmsg(ls->udp.fd, msg, MAX_MSG, MSG_DONTWAIT, NULL); if(num < 0) { - if(!sockwouldblock(sockerrno)) + if(!sockwouldblock(sockerrno)) { logger(DEBUG_ALWAYS, LOG_ERR, "Receiving packet failed: %s", sockstrerror(sockerrno)); + } + return; } for(int i = 0; i < num; i++) { pkt[i].len = msg[i].msg_len; - if(pkt[i].len <= 0 || pkt[i].len > MAXSIZE) + + if(pkt[i].len <= 0 || pkt[i].len > MAXSIZE) { continue; + } + handle_incoming_vpn_packet(ls, &pkt[i], &addr[i]); } + #else vpn_packet_t pkt; sockaddr_t addr = {}; @@ -1559,8 +1741,10 @@ void handle_incoming_vpn_data(void *data, int flags) { int len = recvfrom(ls->udp.fd, (void *)DATA(&pkt), MAXSIZE, 0, &addr.sa, &addrlen); if(len <= 0 || len > MAXSIZE) { - if(!sockwouldblock(sockerrno)) + if(!sockwouldblock(sockerrno)) { logger(DEBUG_ALWAYS, LOG_ERR, "Receiving packet failed: %s", sockstrerror(sockerrno)); + } + return; } @@ -1584,6 +1768,7 @@ void handle_device_data(void *data, int flags) { } else { usleep(errors * 50000); errors++; + if(errors > 10) { logger(DEBUG_ALWAYS, LOG_ERR, "Too many errors from %s, exiting!", device); event_exit(); diff --git a/src/net_setup.c b/src/net_setup.c index 85553be..314fd71 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -64,8 +64,9 @@ char *scriptinterpreter; char *scriptextension; bool node_read_ecdsa_public_key(node_t *n) { - if(ecdsa_active(n->ecdsa)) + if(ecdsa_active(n->ecdsa)) { return true; + } splay_tree_t *config_tree; FILE *fp; @@ -73,8 +74,10 @@ bool node_read_ecdsa_public_key(node_t *n) { char *p; init_configuration(&config_tree); - if(!read_host_config(config_tree, n->name)) + + if(!read_host_config(config_tree, n->name)) { goto exit; + } /* First, check for simple Ed25519PublicKey statement */ @@ -86,13 +89,15 @@ bool node_read_ecdsa_public_key(node_t *n) { /* Else, check for Ed25519PublicKeyFile statement and read it */ - if(!get_config_string(lookup_config(config_tree, "Ed25519PublicKeyFile"), &pubname)) + if(!get_config_string(lookup_config(config_tree, "Ed25519PublicKeyFile"), &pubname)) { xasprintf(&pubname, "%s" SLASH "hosts" SLASH "%s", confbase, n->name); + } fp = fopen(pubname, "r"); - if(!fp) + if(!fp) { goto exit; + } n->ecdsa = ecdsa_read_pem_public_key(fp); fclose(fp); @@ -104,8 +109,9 @@ exit: } bool read_ecdsa_public_key(connection_t *c) { - if(ecdsa_active(c->ecdsa)) + if(ecdsa_active(c->ecdsa)) { return true; + } FILE *fp; char *fname; @@ -113,8 +119,10 @@ bool read_ecdsa_public_key(connection_t *c) { if(!c->config_tree) { init_configuration(&c->config_tree); - if(!read_host_config(c->config_tree, c->name)) + + if(!read_host_config(c->config_tree, c->name)) { return false; + } } /* First, check for simple Ed25519PublicKey statement */ @@ -127,22 +135,24 @@ bool read_ecdsa_public_key(connection_t *c) { /* Else, check for Ed25519PublicKeyFile statement and read it */ - if(!get_config_string(lookup_config(c->config_tree, "Ed25519PublicKeyFile"), &fname)) + if(!get_config_string(lookup_config(c->config_tree, "Ed25519PublicKeyFile"), &fname)) { xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, c->name); + } fp = fopen(fname, "r"); if(!fp) { logger(DEBUG_ALWAYS, LOG_ERR, "Error reading Ed25519 public key file `%s': %s", - fname, strerror(errno)); + fname, strerror(errno)); free(fname); return false; } c->ecdsa = ecdsa_read_pem_public_key(fp); - if(!c->ecdsa && errno != ENOENT) + if(!c->ecdsa && errno != ENOENT) { logger(DEBUG_ALWAYS, LOG_ERR, "Parsing Ed25519 public key file `%s' failed.", fname); + } fclose(fp); free(fname); @@ -165,8 +175,9 @@ bool read_rsa_public_key(connection_t *c) { /* Else, check for PublicKeyFile statement and read it */ - if(!get_config_string(lookup_config(c->config_tree, "PublicKeyFile"), &fname)) + if(!get_config_string(lookup_config(c->config_tree, "PublicKeyFile"), &fname)) { xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, c->name); + } fp = fopen(fname, "r"); @@ -179,8 +190,10 @@ bool read_rsa_public_key(connection_t *c) { c->rsa = rsa_read_pem_public_key(fp); fclose(fp); - if(!c->rsa) + if(!c->rsa) { logger(DEBUG_ALWAYS, LOG_ERR, "Reading RSA public key file `%s' failed: %s", fname, strerror(errno)); + } + free(fname); return c->rsa; } @@ -192,15 +205,19 @@ static bool read_ecdsa_private_key(void) { /* Check for PrivateKeyFile statement and read it */ - if(!get_config_string(lookup_config(config_tree, "Ed25519PrivateKeyFile"), &fname)) + if(!get_config_string(lookup_config(config_tree, "Ed25519PrivateKeyFile"), &fname)) { xasprintf(&fname, "%s" SLASH "ed25519_key.priv", confbase); + } fp = fopen(fname, "r"); if(!fp) { logger(DEBUG_ALWAYS, LOG_ERR, "Error reading Ed25519 private key file `%s': %s", fname, strerror(errno)); - if(errno == ENOENT) - logger(DEBUG_ALWAYS, LOG_INFO, "Create an Ed25519 keypair with `tinc -n %s generate-ed25519-keys'.", netname ?: "."); + + if(errno == ENOENT) { + logger(DEBUG_ALWAYS, LOG_INFO, "Create an Ed25519 keypair with `tinc -n %s generate-ed25519-keys'.", netname ? : "."); + } + free(fname); return false; } @@ -214,15 +231,19 @@ static bool read_ecdsa_private_key(void) { return false; } - if(s.st_mode & ~0100700) + if(s.st_mode & ~0100700) { logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: insecure file permissions for Ed25519 private key file `%s'!", fname); + } + #endif myself->connection->ecdsa = ecdsa_read_pem_private_key(fp); fclose(fp); - if(!myself->connection->ecdsa) + if(!myself->connection->ecdsa) { logger(DEBUG_ALWAYS, LOG_ERR, "Reading Ed25519 private key file `%s' failed", fname); + } + free(fname); return myself->connection->ecdsa; } @@ -243,8 +264,10 @@ static bool read_invitation_key(void) { if(fp) { invitation_key = ecdsa_read_pem_private_key(fp); fclose(fp); - if(!invitation_key) + + if(!invitation_key) { logger(DEBUG_ALWAYS, LOG_ERR, "Reading Ed25519 private key file `%s' failed", fname); + } } return invitation_key; @@ -264,6 +287,7 @@ static bool read_rsa_private_key(void) { free(d); return false; } + myself->connection->rsa = rsa_set_hex_private_key(n, "FFFF", d); free(n); free(d); @@ -272,16 +296,20 @@ static bool read_rsa_private_key(void) { /* Else, check for PrivateKeyFile statement and read it */ - if(!get_config_string(lookup_config(config_tree, "PrivateKeyFile"), &fname)) + if(!get_config_string(lookup_config(config_tree, "PrivateKeyFile"), &fname)) { xasprintf(&fname, "%s" SLASH "rsa_key.priv", confbase); + } fp = fopen(fname, "r"); if(!fp) { logger(DEBUG_ALWAYS, LOG_ERR, "Error reading RSA private key file `%s': %s", - fname, strerror(errno)); - if(errno == ENOENT) - logger(DEBUG_ALWAYS, LOG_INFO, "Create an RSA keypair with `tinc -n %s generate-rsa-keys'.", netname ?: "."); + fname, strerror(errno)); + + if(errno == ENOENT) { + logger(DEBUG_ALWAYS, LOG_INFO, "Create an RSA keypair with `tinc -n %s generate-rsa-keys'.", netname ? : "."); + } + free(fname); return false; } @@ -295,15 +323,19 @@ static bool read_rsa_private_key(void) { return false; } - if(s.st_mode & ~0100700) + if(s.st_mode & ~0100700) { logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: insecure file permissions for RSA private key file `%s'!", fname); + } + #endif myself->connection->rsa = rsa_read_pem_private_key(fp); fclose(fp); - if(!myself->connection->rsa) + if(!myself->connection->rsa) { logger(DEBUG_ALWAYS, LOG_ERR, "Reading RSA private key file `%s' failed: %s", fname, strerror(errno)); + } + free(fname); return myself->connection->rsa; } @@ -313,14 +345,18 @@ static timeout_t keyexpire_timeout; static void keyexpire_handler(void *data) { regenerate_key(); - timeout_set(data, &(struct timeval){keylifetime, rand() % 100000}); + timeout_set(data, &(struct timeval) { + keylifetime, rand() % 100000 + }); } void regenerate_key(void) { logger(DEBUG_STATUS, LOG_INFO, "Expiring symmetric keys"); send_key_changed(); - for splay_each(node_t, n, node_tree) + + for splay_each(node_t, n, node_tree) { n->status.validkey_in = false; + } } void load_all_nodes(void) { @@ -330,14 +366,16 @@ void load_all_nodes(void) { snprintf(dname, sizeof(dname), "%s" SLASH "hosts", confbase); dir = opendir(dname); + if(!dir) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", dname, strerror(errno)); return; } while((ent = readdir(dir))) { - if(!check_id(ent->d_name)) + if(!check_id(ent->d_name)) { continue; + } node_t *n = lookup_node(ent->d_name); @@ -356,8 +394,9 @@ void load_all_nodes(void) { for(config_t *cfg = lookup_config(config_tree, "Subnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) { subnet_t *s, *s2; - if(!get_config_subnet(cfg, &s)) + if(!get_config_subnet(cfg, &s)) { continue; + } if((s2 = lookup_subnet(n, s))) { s2->expires = -1; @@ -368,8 +407,9 @@ void load_all_nodes(void) { } } - if(lookup_config(config_tree, "Address")) + if(lookup_config(config_tree, "Address")) { n->status.has_address = true; + } exit_configuration(&config_tree); } @@ -383,8 +423,9 @@ char *get_name(void) { get_config_string(lookup_config(config_tree, "Name"), &name); - if(!name) + if(!name) { return NULL; + } returned_name = replace_name(name); free(name); @@ -406,13 +447,17 @@ bool setup_myself_reloadable(void) { free(scriptextension); - if(!get_config_string(lookup_config(config_tree, "ScriptsExtension"), &scriptextension)) + + if(!get_config_string(lookup_config(config_tree, "ScriptsExtension"), &scriptextension)) { scriptextension = xstrdup(""); + } get_config_string(lookup_config(config_tree, "Proxy"), &proxy); + if(proxy) { - if((space = strchr(proxy, ' '))) + if((space = strchr(proxy, ' '))) { *space++ = 0; + } if(!strcasecmp(proxy, "none")) { proxytype = PROXY_NONE; @@ -432,53 +477,70 @@ bool setup_myself_reloadable(void) { } switch(proxytype) { - case PROXY_NONE: - default: - break; + case PROXY_NONE: + default: + break; - case PROXY_EXEC: - if(!space || !*space) { - logger(DEBUG_ALWAYS, LOG_ERR, "Argument expected for proxy type exec!"); - return false; - } - proxyhost = xstrdup(space); - break; + case PROXY_EXEC: + if(!space || !*space) { + logger(DEBUG_ALWAYS, LOG_ERR, "Argument expected for proxy type exec!"); + return false; + } - case PROXY_SOCKS4: - case PROXY_SOCKS4A: - case PROXY_SOCKS5: - case PROXY_HTTP: - proxyhost = space; - if(space && (space = strchr(space, ' '))) - *space++ = 0, proxyport = space; - if(space && (space = strchr(space, ' '))) - *space++ = 0, proxyuser = space; - if(space && (space = strchr(space, ' '))) - *space++ = 0, proxypass = space; - if(!proxyhost || !*proxyhost || !proxyport || !*proxyport) { - logger(DEBUG_ALWAYS, LOG_ERR, "Host and port argument expected for proxy!"); - return false; - } - proxyhost = xstrdup(proxyhost); - proxyport = xstrdup(proxyport); - if(proxyuser && *proxyuser) - proxyuser = xstrdup(proxyuser); - if(proxypass && *proxypass) - proxypass = xstrdup(proxypass); - break; + proxyhost = xstrdup(space); + break; + + case PROXY_SOCKS4: + case PROXY_SOCKS4A: + case PROXY_SOCKS5: + case PROXY_HTTP: + proxyhost = space; + + if(space && (space = strchr(space, ' '))) { + *space++ = 0, proxyport = space; + } + + if(space && (space = strchr(space, ' '))) { + *space++ = 0, proxyuser = space; + } + + if(space && (space = strchr(space, ' '))) { + *space++ = 0, proxypass = space; + } + + if(!proxyhost || !*proxyhost || !proxyport || !*proxyport) { + logger(DEBUG_ALWAYS, LOG_ERR, "Host and port argument expected for proxy!"); + return false; + } + + proxyhost = xstrdup(proxyhost); + proxyport = xstrdup(proxyport); + + if(proxyuser && *proxyuser) { + proxyuser = xstrdup(proxyuser); + } + + if(proxypass && *proxypass) { + proxypass = xstrdup(proxypass); + } + + break; } free(proxy); } - if(get_config_bool(lookup_config(config_tree, "IndirectData"), &choice) && choice) + if(get_config_bool(lookup_config(config_tree, "IndirectData"), &choice) && choice) { myself->options |= OPTION_INDIRECT; + } - if(get_config_bool(lookup_config(config_tree, "TCPOnly"), &choice) && choice) + if(get_config_bool(lookup_config(config_tree, "TCPOnly"), &choice) && choice) { myself->options |= OPTION_TCPONLY; + } - if(myself->options & OPTION_TCPONLY) + if(myself->options & OPTION_TCPONLY) { myself->options |= OPTION_INDIRECT; + } get_config_bool(lookup_config(config_tree, "UDPDiscovery"), &udp_discovery); get_config_int(lookup_config(config_tree, "UDPDiscoveryKeepaliveInterval"), &udp_discovery_keepalive_interval); @@ -492,114 +554,141 @@ bool setup_myself_reloadable(void) { get_config_bool(lookup_config(config_tree, "LocalDiscovery"), &localdiscovery); if(get_config_string(lookup_config(config_tree, "Mode"), &rmode)) { - if(!strcasecmp(rmode, "router")) + if(!strcasecmp(rmode, "router")) { routing_mode = RMODE_ROUTER; - else if(!strcasecmp(rmode, "switch")) + } else if(!strcasecmp(rmode, "switch")) { routing_mode = RMODE_SWITCH; - else if(!strcasecmp(rmode, "hub")) + } else if(!strcasecmp(rmode, "hub")) { routing_mode = RMODE_HUB; - else { + } else { logger(DEBUG_ALWAYS, LOG_ERR, "Invalid routing mode!"); return false; } + free(rmode); } if(get_config_string(lookup_config(config_tree, "Forwarding"), &fmode)) { - if(!strcasecmp(fmode, "off")) + if(!strcasecmp(fmode, "off")) { forwarding_mode = FMODE_OFF; - else if(!strcasecmp(fmode, "internal")) + } else if(!strcasecmp(fmode, "internal")) { forwarding_mode = FMODE_INTERNAL; - else if(!strcasecmp(fmode, "kernel")) + } else if(!strcasecmp(fmode, "kernel")) { forwarding_mode = FMODE_KERNEL; - else { + } else { logger(DEBUG_ALWAYS, LOG_ERR, "Invalid forwarding mode!"); return false; } + free(fmode); } choice = true; get_config_bool(lookup_config(config_tree, "PMTUDiscovery"), &choice); - if(choice) + + if(choice) { myself->options |= OPTION_PMTU_DISCOVERY; + } choice = true; get_config_bool(lookup_config(config_tree, "ClampMSS"), &choice); - if(choice) + + if(choice) { myself->options |= OPTION_CLAMP_MSS; + } get_config_bool(lookup_config(config_tree, "PriorityInheritance"), &priorityinheritance); get_config_bool(lookup_config(config_tree, "DecrementTTL"), &decrement_ttl); + if(get_config_string(lookup_config(config_tree, "Broadcast"), &bmode)) { - if(!strcasecmp(bmode, "no")) + if(!strcasecmp(bmode, "no")) { broadcast_mode = BMODE_NONE; - else if(!strcasecmp(bmode, "yes") || !strcasecmp(bmode, "mst")) + } else if(!strcasecmp(bmode, "yes") || !strcasecmp(bmode, "mst")) { broadcast_mode = BMODE_MST; - else if(!strcasecmp(bmode, "direct")) + } else if(!strcasecmp(bmode, "direct")) { broadcast_mode = BMODE_DIRECT; - else { + } else { logger(DEBUG_ALWAYS, LOG_ERR, "Invalid broadcast mode!"); return false; } + free(bmode); } - const char* const DEFAULT_BROADCAST_SUBNETS[] = { "ff:ff:ff:ff:ff:ff", "255.255.255.255", "224.0.0.0/4", "ff00::/8" }; - for (size_t i = 0; i < sizeof(DEFAULT_BROADCAST_SUBNETS) / sizeof(*DEFAULT_BROADCAST_SUBNETS); i++) { + const char *const DEFAULT_BROADCAST_SUBNETS[] = { "ff:ff:ff:ff:ff:ff", "255.255.255.255", "224.0.0.0/4", "ff00::/8" }; + + for(size_t i = 0; i < sizeof(DEFAULT_BROADCAST_SUBNETS) / sizeof(*DEFAULT_BROADCAST_SUBNETS); i++) { subnet_t *s = new_subnet(); - if (!str2net(s, DEFAULT_BROADCAST_SUBNETS[i])) + + if(!str2net(s, DEFAULT_BROADCAST_SUBNETS[i])) { abort(); + } + subnet_add(NULL, s); } - for (config_t* cfg = lookup_config(config_tree, "BroadcastSubnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) { + + for(config_t *cfg = lookup_config(config_tree, "BroadcastSubnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) { subnet_t *s; - if (!get_config_subnet(cfg, &s)) + + if(!get_config_subnet(cfg, &s)) { continue; + } + subnet_add(NULL, s); } #if !defined(IPPROTO_IP) || !defined(IP_TOS) - if(priorityinheritance) + + if(priorityinheritance) { logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform for IPv4 connections", "PriorityInheritance"); + } + #endif #if !defined(IPPROTO_IPV6) || !defined(IPV6_TCLASS) - if(priorityinheritance) + + if(priorityinheritance) { logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform for IPv6 connections", "PriorityInheritance"); + } + #endif - if(!get_config_int(lookup_config(config_tree, "MACExpire"), &macexpire)) + if(!get_config_int(lookup_config(config_tree, "MACExpire"), &macexpire)) { macexpire = 600; + } if(get_config_int(lookup_config(config_tree, "MaxTimeout"), &maxtimeout)) { if(maxtimeout <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Bogus maximum timeout!"); return false; } - } else + } else { maxtimeout = 900; + } if(get_config_string(lookup_config(config_tree, "AddressFamily"), &afname)) { - if(!strcasecmp(afname, "IPv4")) + if(!strcasecmp(afname, "IPv4")) { addressfamily = AF_INET; - else if(!strcasecmp(afname, "IPv6")) + } else if(!strcasecmp(afname, "IPv6")) { addressfamily = AF_INET6; - else if(!strcasecmp(afname, "any")) + } else if(!strcasecmp(afname, "any")) { addressfamily = AF_UNSPEC; - else { + } else { logger(DEBUG_ALWAYS, LOG_ERR, "Invalid address family!"); return false; } + free(afname); } get_config_bool(lookup_config(config_tree, "Hostnames"), &hostnames); - if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime)) + if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime)) { keylifetime = 3600; + } config_t *cfg = lookup_config(config_tree, "AutoConnect"); + if(cfg) { if(!get_config_bool(cfg, &autoconnect)) { // Some backwards compatibility with when this option was an int @@ -611,8 +700,9 @@ bool setup_myself_reloadable(void) { get_config_bool(lookup_config(config_tree, "DisableBuggyPeers"), &disablebuggypeers); - if(!get_config_int(lookup_config(config_tree, "InvitationExpire"), &invitation_lifetime)) - invitation_lifetime = 604800; // 1 week + if(!get_config_int(lookup_config(config_tree, "InvitationExpire"), &invitation_lifetime)) { + invitation_lifetime = 604800; // 1 week + } read_invitation_key(); @@ -627,25 +717,33 @@ static bool add_listen_address(char *address, bool bindto) { if(address) { char *space = strchr(address, ' '); + if(space) { *space++ = 0; port = space; } - if(!strcmp(address, "*")) + if(!strcmp(address, "*")) { *address = 0; + } } struct addrinfo *ai, hint = {0}; + hint.ai_family = addressfamily; + hint.ai_socktype = SOCK_STREAM; + hint.ai_protocol = IPPROTO_TCP; + hint.ai_flags = AI_PASSIVE; #if HAVE_DECL_RES_INIT res_init(); + #endif int err = getaddrinfo(address && *address ? address : NULL, port, &hint, &ai); + free(address); if(err || !ai) { @@ -663,8 +761,9 @@ static bool add_listen_address(char *address, bool bindto) { break; } - if(found) + if(found) { continue; + } if(listen_sockets >= MAXSOCKETS) { logger(DEBUG_ALWAYS, LOG_ERR, "Too many listening sockets"); @@ -673,8 +772,9 @@ static bool add_listen_address(char *address, bool bindto) { int tcp_fd = setup_listen_socket((sockaddr_t *) aip->ai_addr); - if(tcp_fd < 0) + if(tcp_fd < 0) { continue; + } int udp_fd = setup_vpn_in_socket((sockaddr_t *) aip->ai_addr); @@ -702,8 +802,9 @@ static bool add_listen_address(char *address, bool bindto) { } void device_enable(void) { - if (devops.enable) + if(devops.enable) { devops.enable(); + } /* Run tinc-up script to further initialize the tap interface */ @@ -719,8 +820,9 @@ void device_disable(void) { execute_script("tinc-down", &env); environment_exit(&env); - if (devops.disable) + if(devops.disable) { devops.disable(); + } } /* @@ -743,10 +845,11 @@ static bool setup_myself(void) { myself->connection->name = xstrdup(name); read_host_config(config_tree, name); - if(!get_config_string(lookup_config(config_tree, "Port"), &myport)) + if(!get_config_string(lookup_config(config_tree, "Port"), &myport)) { myport = xstrdup("655"); - else + } else { port_specified = true; + } myself->connection->options = 0; myself->connection->protocol_major = PROT_MAJOR; @@ -756,18 +859,24 @@ static bool setup_myself(void) { #ifdef DISABLE_LEGACY experimental = read_ecdsa_private_key(); + if(!experimental) { logger(DEBUG_ALWAYS, LOG_ERR, "No private key available, cannot start tinc!"); return false; } + #else + if(!get_config_bool(lookup_config(config_tree, "ExperimentalProtocol"), &experimental)) { experimental = read_ecdsa_private_key(); - if(!experimental) + + if(!experimental) { logger(DEBUG_ALWAYS, LOG_WARNING, "Support for SPTPS disabled."); + } } else { - if(experimental && !read_ecdsa_private_key()) + if(experimental && !read_ecdsa_private_key()) { return false; + } } if(!read_rsa_private_key()) { @@ -778,6 +887,7 @@ static bool setup_myself(void) { return false; } } + #endif /* Ensure myport is numeric */ @@ -785,8 +895,11 @@ static bool setup_myself(void) { if(!atoi(myport)) { struct addrinfo *ai = str2addrinfo("localhost", myport, SOCK_DGRAM); sockaddr_t sa; - if(!ai || !ai->ai_addr) + + if(!ai || !ai->ai_addr) { return false; + } + free(myport); memcpy(&sa, ai->ai_addr, ai->ai_addrlen); sockaddr2str(&sa, NULL, &myport); @@ -797,16 +910,18 @@ static bool setup_myself(void) { for(config_t *cfg = lookup_config(config_tree, "Subnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) { subnet_t *subnet; - if(!get_config_subnet(cfg, &subnet)) + if(!get_config_subnet(cfg, &subnet)) { return false; + } subnet_add(myself, subnet); } /* Check some options */ - if(!setup_myself_reloadable()) + if(!setup_myself_reloadable()) { return false; + } get_config_bool(lookup_config(config_tree, "StrictSubnets"), &strictsubnets); get_config_bool(lookup_config(config_tree, "TunnelServer"), &tunnelserver); @@ -834,11 +949,13 @@ static bool setup_myself(void) { } int replaywin_int; + if(get_config_int(lookup_config(config_tree, "ReplayWindow"), &replaywin_int)) { if(replaywin_int < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "ReplayWindow cannot be negative!"); return false; } + replaywin = (unsigned)replaywin_int; sptps_replaywin = replaywin; } @@ -846,8 +963,9 @@ static bool setup_myself(void) { #ifndef DISABLE_LEGACY /* Generate packet encryption key */ - if(!get_config_string(lookup_config(config_tree, "Cipher"), &cipher)) + if(!get_config_string(lookup_config(config_tree, "Cipher"), &cipher)) { cipher = xstrdup("aes-256-cbc"); + } if(!strcasecmp(cipher, "none")) { myself->incipher = NULL; @@ -858,7 +976,9 @@ static bool setup_myself(void) { free(cipher); - timeout_add(&keyexpire_timeout, keyexpire_handler, &keyexpire_timeout, &(struct timeval){keylifetime, rand() % 100000}); + timeout_add(&keyexpire_timeout, keyexpire_handler, &keyexpire_timeout, &(struct timeval) { + keylifetime, rand() % 100000 + }); /* Check if we want to use message authentication codes... */ @@ -870,8 +990,9 @@ static bool setup_myself(void) { return false; } - if(!get_config_string(lookup_config(config_tree, "Digest"), &digest)) + if(!get_config_string(lookup_config(config_tree, "Digest"), &digest)) { digest = xstrdup("sha256"); + } if(!strcasecmp(digest, "none")) { myself->indigest = NULL; @@ -890,8 +1011,9 @@ static bool setup_myself(void) { logger(DEBUG_ALWAYS, LOG_ERR, "Bogus compression level!"); return false; } - } else + } else { myself->incompression = 0; + } myself->connection->outcompression = 0; @@ -913,32 +1035,40 @@ static bool setup_myself(void) { devops = os_devops; if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) { - if(!strcasecmp(type, "dummy")) + if(!strcasecmp(type, "dummy")) { devops = dummy_devops; - else if(!strcasecmp(type, "raw_socket")) + } else if(!strcasecmp(type, "raw_socket")) { devops = raw_socket_devops; - else if(!strcasecmp(type, "multicast")) + } else if(!strcasecmp(type, "multicast")) { devops = multicast_devops; - else if(!strcasecmp(type, "fd")) + } else if(!strcasecmp(type, "fd")) { devops = fd_devops; + } + #ifdef ENABLE_UML - else if(!strcasecmp(type, "uml")) + else if(!strcasecmp(type, "uml")) { devops = uml_devops; + } + #endif #ifdef ENABLE_VDE - else if(!strcasecmp(type, "vde")) + else if(!strcasecmp(type, "vde")) { devops = vde_devops; + } + #endif free(type); } get_config_bool(lookup_config(config_tree, "DeviceStandby"), &device_standby); - if(!devops.setup()) + if(!devops.setup()) { return false; + } - if(device_fd >= 0) + if(device_fd >= 0) { io_add(&device_io, handle_device_data, NULL, device_fd, IO_READ); + } /* Open sockets */ @@ -958,6 +1088,7 @@ static bool setup_myself(void) { for(int i = 0; i < listen_sockets; i++) { salen = sizeof(sa); + if(getsockname(i + 3, &sa.sa, &salen) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not get address of listen fd %d: %s", i + 3, sockstrerror(sockerrno)); return false; @@ -968,8 +1099,10 @@ static bool setup_myself(void) { #endif int udp_fd = setup_vpn_in_socket(&sa); - if(udp_fd < 0) + + if(udp_fd < 0) { return false; + } io_add(&listen_socket[i].tcp, (io_cb_t)handle_new_meta_connection, &listen_socket[i], i + 3, IO_READ); io_add(&listen_socket[i].udp, (io_cb_t)handle_incoming_vpn_data, &listen_socket[i], udp_fd, IO_READ); @@ -989,20 +1122,25 @@ static bool setup_myself(void) { for(config_t *cfg = lookup_config(config_tree, "BindToAddress"); cfg; cfg = lookup_config_next(config_tree, cfg)) { cfgs++; get_config_string(cfg, &address); - if(!add_listen_address(address, true)) + + if(!add_listen_address(address, true)) { return false; + } } for(config_t *cfg = lookup_config(config_tree, "ListenAddress"); cfg; cfg = lookup_config_next(config_tree, cfg)) { cfgs++; get_config_string(cfg, &address); - if(!add_listen_address(address, false)) + + if(!add_listen_address(address, false)) { return false; + } } if(!cfgs) - if(!add_listen_address(address, NULL)) + if(!add_listen_address(address, NULL)) { return false; + } } if(!listen_sockets) { @@ -1015,11 +1153,14 @@ static bool setup_myself(void) { if(!port_specified || atoi(myport) == 0) { sockaddr_t sa; socklen_t salen = sizeof(sa); + if(!getsockname(listen_socket[0].udp.fd, &sa.sa, &salen)) { free(myport); sockaddr2str(&sa, NULL, &myport); - if(!myport) + + if(!myport) { myport = xstrdup("655"); + } } } @@ -1030,14 +1171,18 @@ static bool setup_myself(void) { get_config_string(lookup_config(config_tree, "UPnP"), &upnp); bool upnp_tcp = false; bool upnp_udp = false; - if (upnp) { - if (!strcasecmp(upnp, "yes")) + + if(upnp) { + if(!strcasecmp(upnp, "yes")) { upnp_tcp = upnp_udp = true; - else if (!strcasecmp(upnp, "udponly")) + } else if(!strcasecmp(upnp, "udponly")) { upnp_udp = true; + } + free(upnp); } - if (upnp_tcp || upnp_udp) { + + if(upnp_tcp || upnp_udp) { #ifdef HAVE_MINIUPNPC upnp_init(upnp_tcp, upnp_udp); #else @@ -1066,25 +1211,33 @@ bool setup_network(void) { if(pinginterval < 1) { pinginterval = 86400; } - } else + } else { pinginterval = 60; + } - if(!get_config_int(lookup_config(config_tree, "PingTimeout"), &pingtimeout)) + if(!get_config_int(lookup_config(config_tree, "PingTimeout"), &pingtimeout)) { pingtimeout = 5; - if(pingtimeout < 1 || pingtimeout > pinginterval) + } + + if(pingtimeout < 1 || pingtimeout > pinginterval) { pingtimeout = pinginterval; + } - if(!get_config_int(lookup_config(config_tree, "MaxOutputBufferSize"), &maxoutbufsize)) + if(!get_config_int(lookup_config(config_tree, "MaxOutputBufferSize"), &maxoutbufsize)) { maxoutbufsize = 10 * MTU; + } - if(!setup_myself()) + if(!setup_myself()) { return false; + } - if(!init_control()) + if(!init_control()) { return false; + } - if (!device_standby) + if(!device_standby) { device_enable(); + } /* Run subnet-up scripts for our own subnets */ @@ -1100,15 +1253,19 @@ void close_network_connections(void) { for(list_node_t *node = connection_list->head, *next; node; node = next) { next = node->next; connection_t *c = node->data; + /* Keep control connections open until the end, so they know when we really terminated */ - if(c->status.control) + if(c->status.control) { c->socket = -1; + } + c->outgoing = NULL; terminate_connection(c, false); } - if(outgoing_list) + if(outgoing_list) { list_delete_list(outgoing_list); + } if(myself && myself->connection) { subnet_update(myself, NULL, false); @@ -1128,15 +1285,19 @@ void close_network_connections(void) { exit_nodes(); exit_connections(); - if (!device_standby) + if(!device_standby) { device_disable(); + } free(myport); - if (device_fd >= 0) + if(device_fd >= 0) { io_del(&device_io); - if (devops.close) + } + + if(devops.close) { devops.close(); + } exit_control(); diff --git a/src/net_socket.c b/src/net_socket.c index 46dbdf6..c020e8f 100644 --- a/src/net_socket.c +++ b/src/net_socket.c @@ -60,12 +60,14 @@ static void configure_tcp(connection_t *c) { if(fcntl(c->socket, F_SETFL, flags | O_NONBLOCK) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "fcntl for %s: %s", c->hostname, strerror(errno)); } + #elif defined(WIN32) unsigned long arg = 1; if(ioctlsocket(c->socket, FIONBIO, &arg) != 0) { logger(DEBUG_ALWAYS, LOG_ERR, "ioctlsocket for %s: %s", c->hostname, sockstrerror(sockerrno)); } + #endif #if defined(IPPROTO_TCP) && defined(TCP_NODELAY) @@ -92,8 +94,9 @@ static bool bind_to_interface(int sd) { int status; #endif /* defined(SOL_SOCKET) && defined(SO_BINDTODEVICE) */ - if(!get_config_string (lookup_config (config_tree, "BindToInterface"), &iface)) + if(!get_config_string(lookup_config(config_tree, "BindToInterface"), &iface)) { return true; + } #if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE) memset(&ifr, 0, sizeof(ifr)); @@ -101,11 +104,13 @@ static bool bind_to_interface(int sd) { ifr.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = 0; status = setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)); + if(status) { logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to interface %s: %s", iface, - sockstrerror(sockerrno)); + sockstrerror(sockerrno)); return false; } + #else /* if !defined(SOL_SOCKET) || !defined(SO_BINDTODEVICE) */ logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform", "BindToInterface"); #endif @@ -117,21 +122,28 @@ static bool bind_to_address(connection_t *c) { int s = -1; for(int i = 0; i < listen_sockets && listen_socket[i].bindto; i++) { - if(listen_socket[i].sa.sa.sa_family != c->address.sa.sa_family) + if(listen_socket[i].sa.sa.sa_family != c->address.sa.sa_family) { continue; - if(s >= 0) + } + + if(s >= 0) { return false; + } + s = i; } - if(s < 0) + if(s < 0) { return false; + } sockaddr_t sa = listen_socket[s].sa; - if(sa.sa.sa_family == AF_INET) + + if(sa.sa.sa_family == AF_INET) { sa.in.sin_port = 0; - else if(sa.sa.sa_family == AF_INET6) + } else if(sa.sa.sa_family == AF_INET6) { sa.in6.sin6_port = 0; + } if(bind(c->socket, &sa.sa, SALEN(sa.sa))) { logger(DEBUG_CONNECTIONS, LOG_WARNING, "Can't bind outgoing socket: %s", sockstrerror(sockerrno)); @@ -164,12 +176,15 @@ int setup_listen_socket(const sockaddr_t *sa) { setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof(option)); #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) - if(sa->sa.sa_family == AF_INET6) + + if(sa->sa.sa_family == AF_INET6) { setsockopt(nfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof(option)); + } + #endif if(get_config_string - (lookup_config(config_tree, "BindToInterface"), &iface)) { + (lookup_config(config_tree, "BindToInterface"), &iface)) { #if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE) struct ifreq ifr; @@ -179,9 +194,10 @@ int setup_listen_socket(const sockaddr_t *sa) { if(setsockopt(nfd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr))) { closesocket(nfd); logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to interface %s: %s", iface, - sockstrerror(sockerrno)); + sockstrerror(sockerrno)); return -1; } + #else logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform", "BindToInterface"); #endif @@ -227,13 +243,14 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) { closesocket(nfd); logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl", - strerror(errno)); + strerror(errno)); return -1; } } #elif defined(WIN32) { unsigned long arg = 1; + if(ioctlsocket(nfd, FIONBIO, &arg) != 0) { closesocket(nfd); logger(DEBUG_ALWAYS, LOG_ERR, "Call to `%s' failed: %s", "ioctlsocket", sockstrerror(sockerrno)); @@ -246,15 +263,20 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof(option)); setsockopt(nfd, SOL_SOCKET, SO_BROADCAST, (void *)&option, sizeof(option)); - if(udp_rcvbuf && setsockopt(nfd, SOL_SOCKET, SO_RCVBUF, (void *)&udp_rcvbuf, sizeof(udp_rcvbuf))) + if(udp_rcvbuf && setsockopt(nfd, SOL_SOCKET, SO_RCVBUF, (void *)&udp_rcvbuf, sizeof(udp_rcvbuf))) { logger(DEBUG_ALWAYS, LOG_WARNING, "Can't set UDP SO_RCVBUF to %i: %s", udp_rcvbuf, sockstrerror(sockerrno)); + } - if(udp_sndbuf && setsockopt(nfd, SOL_SOCKET, SO_SNDBUF, (void *)&udp_sndbuf, sizeof(udp_sndbuf))) + if(udp_sndbuf && setsockopt(nfd, SOL_SOCKET, SO_SNDBUF, (void *)&udp_sndbuf, sizeof(udp_sndbuf))) { logger(DEBUG_ALWAYS, LOG_WARNING, "Can't set UDP SO_SNDBUF to %i: %s", udp_sndbuf, sockstrerror(sockerrno)); + } #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) - if(sa->sa.sa_family == AF_INET6) + + if(sa->sa.sa_family == AF_INET6) { setsockopt(nfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof(option)); + } + #endif #if defined(IP_DONTFRAG) && !defined(IP_DONTFRAGMENT) @@ -262,30 +284,38 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { #endif #if defined(IPPROTO_IP) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO) + if(myself->options & OPTION_PMTU_DISCOVERY) { option = IP_PMTUDISC_DO; setsockopt(nfd, IPPROTO_IP, IP_MTU_DISCOVER, (void *)&option, sizeof(option)); } + #elif defined(IPPROTO_IP) && defined(IP_DONTFRAGMENT) + if(myself->options & OPTION_PMTU_DISCOVERY) { option = 1; setsockopt(nfd, IPPROTO_IP, IP_DONTFRAGMENT, (void *)&option, sizeof(option)); } + #endif #if defined(IPPROTO_IPV6) && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO) + if(myself->options & OPTION_PMTU_DISCOVERY) { option = IPV6_PMTUDISC_DO; setsockopt(nfd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, (void *)&option, sizeof(option)); } + #elif defined(IPPROTO_IPV6) && defined(IPV6_DONTFRAG) + if(myself->options & OPTION_PMTU_DISCOVERY) { option = 1; setsockopt(nfd, IPPROTO_IPV6, IPV6_DONTFRAG, (void *)&option, sizeof(option)); } + #endif - if (!bind_to_interface(nfd)) { + if(!bind_to_interface(nfd)) { closesocket(nfd); return -1; } @@ -308,10 +338,13 @@ static void retry_outgoing_handler(void *data) { void retry_outgoing(outgoing_t *outgoing) { outgoing->timeout += 5; - if(outgoing->timeout > maxtimeout) + if(outgoing->timeout > maxtimeout) { outgoing->timeout = maxtimeout; + } - timeout_add(&outgoing->ev, retry_outgoing_handler, outgoing, &(struct timeval){outgoing->timeout, rand() % 100000}); + timeout_add(&outgoing->ev, retry_outgoing_handler, outgoing, &(struct timeval) { + outgoing->timeout, rand() % 100000 + }); logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Trying to re-establish outgoing connection in %d seconds", outgoing->timeout); } @@ -358,14 +391,19 @@ static void do_outgoing_pipe(connection_t *c, char *command) { setenv("REMOTEPORT", port, true); setenv("NODE", c->name, true); setenv("NAME", myself->name, true); - if(netname) + + if(netname) { setenv("NETNAME", netname, true); + } int result = system(command); - if(result < 0) + + if(result < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not execute %s: %s", command, strerror(errno)); - else if(result) + } else if(result) { logger(DEBUG_ALWAYS, LOG_ERR, "%s exited with non-zero status %d", command, result); + } + exit(result); #else logger(DEBUG_ALWAYS, LOG_ERR, "Proxy type exec not supported on this platform!"); @@ -374,10 +412,12 @@ static void do_outgoing_pipe(connection_t *c, char *command) { } static void handle_meta_write(connection_t *c) { - if(c->outbuf.len <= c->outbuf.offset) + if(c->outbuf.len <= c->outbuf.offset) { return; + } ssize_t outlen = send(c->socket, c->outbuf.data + c->outbuf.offset, c->outbuf.len - c->outbuf.offset, 0); + if(outlen <= 0) { if(!sockerrno || sockerrno == EPIPE) { logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection closed by %s (%s)", c->name, c->hostname); @@ -393,8 +433,10 @@ static void handle_meta_write(connection_t *c) { } buffer_read(&c->outbuf, outlen); - if(!c->outbuf.len) + + if(!c->outbuf.len) { io_set(&c->io, IO_READ); + } } static void handle_meta_io(void *data, int flags) { @@ -414,20 +456,25 @@ static void handle_meta_io(void *data, int flags) { | Successful | (success) | (success) | (success) | +------------+-----------+-------------+-----------+ */ - if (send(c->socket, NULL, 0, 0) != 0) { - if (sockwouldblock(sockerrno)) + if(send(c->socket, NULL, 0, 0) != 0) { + if(sockwouldblock(sockerrno)) { return; + } + int socket_error; - if (!socknotconn(sockerrno)) + + if(!socknotconn(sockerrno)) { socket_error = sockerrno; - else { + } else { socklen_t len = sizeof(socket_error); getsockopt(c->socket, SOL_SOCKET, SO_ERROR, (void *)&socket_error, &len); } - if (socket_error) { + + if(socket_error) { logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Error while connecting to %s (%s): %s", c->name, c->hostname, sockstrerror(socket_error)); terminate_connection(c, false); } + return; } @@ -435,10 +482,11 @@ static void handle_meta_io(void *data, int flags) { finish_connecting(c); } - if(flags & IO_WRITE) + if(flags & IO_WRITE) { handle_meta_write(c); - else + } else { handle_meta_connection_data(c); + } } static void free_known_addresses(struct addrinfo *ai) { @@ -454,6 +502,7 @@ bool do_outgoing_connection(outgoing_t *outgoing) { int result; begin: + if(!outgoing->ai && !outgoing->kai) { if(!outgoing->cfg) { logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not set up a meta connection to %s", outgoing->name); @@ -464,12 +513,14 @@ begin: get_config_string(outgoing->cfg, &address); space = strchr(address, ' '); + if(space) { port = xstrdup(space + 1); *space = 0; } else { - if(!get_config_string(lookup_config(outgoing->config_tree, "Port"), &port)) + if(!get_config_string(lookup_config(outgoing->config_tree, "Port"), &port)) { port = xstrdup("655"); + } } outgoing->ai = str2addrinfo(address, port, SOCK_STREAM); @@ -481,12 +532,16 @@ begin: } if(!outgoing->aip) { - if(outgoing->ai) + if(outgoing->ai) { freeaddrinfo(outgoing->ai); + } + outgoing->ai = NULL; - if(outgoing->kai) + if(outgoing->kai) { free_known_addresses(outgoing->kai); + } + outgoing->kai = NULL; goto begin; @@ -509,10 +564,12 @@ begin: do_outgoing_pipe(c, proxyhost); } else { proxyai = str2addrinfo(proxyhost, proxyport, SOCK_STREAM); + if(!proxyai) { free_connection(c); goto begin; } + logger(DEBUG_CONNECTIONS, LOG_INFO, "Using proxy at %s port %s", proxyhost, proxyport); c->socket = socket(proxyai->ai_family, SOCK_STREAM, IPPROTO_TCP); configure_tcp(c); @@ -531,8 +588,11 @@ begin: if(proxytype != PROXY_EXEC) { #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) int option = 1; - if(c->address.sa.sa_family == AF_INET6) + + if(c->address.sa.sa_family == AF_INET6) { setsockopt(c->socket, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof(option)); + } + #endif bind_to_interface(c->socket); @@ -546,8 +606,10 @@ begin: } else if(proxytype == PROXY_EXEC) { result = 0; } else { - if(!proxyai) + if(!proxyai) { abort(); + } + result = connect(c->socket, proxyai->ai_addr, proxyai->ai_addrlen); freeaddrinfo(proxyai); } @@ -574,7 +636,7 @@ begin: connection_add(c); - io_add(&c->io, handle_meta_io, c, c->socket, IO_READ|IO_WRITE); + io_add(&c->io, handle_meta_io, c, c->socket, IO_READ | IO_WRITE); return true; } @@ -585,18 +647,22 @@ static struct addrinfo *get_known_addresses(node_t *n) { struct addrinfo *oai = NULL; for splay_each(edge_t, e, n->edge_tree) { - if(!e->reverse) + if(!e->reverse) { continue; + } bool found = false; + for(struct addrinfo *aip = ai; aip; aip = aip->ai_next) { if(!sockaddrcmp(&e->reverse->address, (sockaddr_t *)aip->ai_addr)) { found = true; break; } } - if(found) + + if(found) { continue; + } oai = ai; ai = xzalloc(sizeof(*ai)); @@ -619,6 +685,7 @@ void setup_outgoing_connection(outgoing_t *outgoing) { if(n && n->connection) { logger(DEBUG_CONNECTIONS, LOG_INFO, "Already connected to %s", outgoing->name); + if(!n->connection->outgoing) { n->connection->outgoing = outgoing; return; @@ -632,8 +699,10 @@ void setup_outgoing_connection(outgoing_t *outgoing) { outgoing->cfg = lookup_config(outgoing->config_tree, "Address"); if(!outgoing->cfg) { - if(n) + if(n) { outgoing->aip = outgoing->kai = get_known_addresses(n); + } + if(!outgoing->kai) { logger(DEBUG_ALWAYS, LOG_DEBUG, "No address known for %s", outgoing->name); goto remove; @@ -681,10 +750,11 @@ void handle_new_meta_connection(void *data, int flags) { static int samehost_burst; static int samehost_burst_time; - if(now.tv_sec - samehost_burst_time > samehost_burst) + if(now.tv_sec - samehost_burst_time > samehost_burst) { samehost_burst = 0; - else + } else { samehost_burst -= now.tv_sec - samehost_burst_time; + } samehost_burst_time = now.tv_sec; samehost_burst++; @@ -702,10 +772,11 @@ void handle_new_meta_connection(void *data, int flags) { static int connection_burst; static int connection_burst_time; - if(now.tv_sec - connection_burst_time > connection_burst) + if(now.tv_sec - connection_burst_time > connection_burst) { connection_burst = 0; - else + } else { connection_burst -= now.tv_sec - connection_burst_time; + } connection_burst_time = now.tv_sec; connection_burst++; @@ -786,17 +857,21 @@ void handle_new_unix_connection(void *data, int flags) { static void free_outgoing(outgoing_t *outgoing) { timeout_del(&outgoing->ev); - if(outgoing->ai) + if(outgoing->ai) { freeaddrinfo(outgoing->ai); + } - if(outgoing->kai) + if(outgoing->kai) { free_known_addresses(outgoing->kai); + } - if(outgoing->config_tree) + if(outgoing->config_tree) { exit_configuration(&outgoing->config_tree); + } - if(outgoing->name) + if(outgoing->name) { free(outgoing->name); + } free(outgoing); } @@ -807,8 +882,9 @@ void try_outgoing_connections(void) { if(!outgoing_list) { outgoing_list = list_alloc((list_action_t)free_outgoing); } else { - for list_each(outgoing_t, outgoing, outgoing_list) + for list_each(outgoing_t, outgoing, outgoing_list) { outgoing->timeout = -1; + } } /* Make sure there is one outgoing_t in the list for each ConnectTo. */ @@ -819,8 +895,8 @@ void try_outgoing_connections(void) { if(!check_id(name)) { logger(DEBUG_ALWAYS, LOG_ERR, - "Invalid name for outgoing connection in %s line %d", - cfg->file, cfg->line); + "Invalid name for outgoing connection in %s line %d", + cfg->file, cfg->line); free(name); continue; } @@ -861,6 +937,7 @@ void try_outgoing_connections(void) { /* Delete outgoing_ts for which there is no ConnectTo. */ for list_each(outgoing_t, outgoing, outgoing_list) - if(outgoing->timeout == -1) + if(outgoing->timeout == -1) { list_delete_node(outgoing_list, node); + } } diff --git a/src/netutl.c b/src/netutl.c index 69714ea..7371923 100644 --- a/src/netutl.c +++ b/src/netutl.c @@ -84,16 +84,24 @@ void sockaddr2str(const sockaddr_t *sa, char **addrstr, char **portstr) { int err; if(sa->sa.sa_family == AF_UNSPEC) { - if(addrstr) + if(addrstr) { *addrstr = xstrdup("unspec"); - if(portstr) + } + + if(portstr) { *portstr = xstrdup("unspec"); + } + return; } else if(sa->sa.sa_family == AF_UNKNOWN) { - if(addrstr) + if(addrstr) { *addrstr = xstrdup(sa->unknown.address); - if(portstr) + } + + if(portstr) { *portstr = xstrdup(sa->unknown.port); + } + return; } @@ -106,13 +114,17 @@ void sockaddr2str(const sockaddr_t *sa, char **addrstr, char **portstr) { scopeid = strchr(address, '%'); - if(scopeid) - *scopeid = '\0'; /* Descope. */ + if(scopeid) { + *scopeid = '\0'; /* Descope. */ + } - if(addrstr) + if(addrstr) { *addrstr = xstrdup(address); - if(portstr) + } + + if(portstr) { *portstr = xstrdup(port); + } } char *sockaddr2hostname(const sockaddr_t *sa) { @@ -130,7 +142,8 @@ char *sockaddr2hostname(const sockaddr_t *sa) { } err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof(address), port, sizeof port, - hostnames ? 0 : (NI_NUMERICHOST | NI_NUMERICSERV)); + hostnames ? 0 : (NI_NUMERICHOST | NI_NUMERICSERV)); + if(err) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while looking up hostname: %s", err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err)); } @@ -145,26 +158,27 @@ int sockaddrcmp_noport(const sockaddr_t *a, const sockaddr_t *b) { result = a->sa.sa_family - b->sa.sa_family; - if(result) + if(result) { return result; + } - switch (a->sa.sa_family) { - case AF_UNSPEC: - return 0; + switch(a->sa.sa_family) { + case AF_UNSPEC: + return 0; - case AF_UNKNOWN: - return strcmp(a->unknown.address, b->unknown.address); + case AF_UNKNOWN: + return strcmp(a->unknown.address, b->unknown.address); - case AF_INET: - return memcmp(&a->in.sin_addr, &b->in.sin_addr, sizeof(a->in.sin_addr)); + case AF_INET: + return memcmp(&a->in.sin_addr, &b->in.sin_addr, sizeof(a->in.sin_addr)); - case AF_INET6: - return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)); + case AF_INET6: + return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)); - default: - logger(DEBUG_ALWAYS, LOG_ERR, "sockaddrcmp() was called with unknown address family %d, exitting!", - a->sa.sa_family); - abort(); + default: + logger(DEBUG_ALWAYS, LOG_ERR, "sockaddrcmp() was called with unknown address family %d, exitting!", + a->sa.sa_family); + abort(); } } @@ -173,41 +187,45 @@ int sockaddrcmp(const sockaddr_t *a, const sockaddr_t *b) { result = a->sa.sa_family - b->sa.sa_family; - if(result) + if(result) { return result; + } - switch (a->sa.sa_family) { - case AF_UNSPEC: - return 0; + switch(a->sa.sa_family) { + case AF_UNSPEC: + return 0; - case AF_UNKNOWN: - result = strcmp(a->unknown.address, b->unknown.address); + case AF_UNKNOWN: + result = strcmp(a->unknown.address, b->unknown.address); - if(result) - return result; + if(result) { + return result; + } - return strcmp(a->unknown.port, b->unknown.port); + return strcmp(a->unknown.port, b->unknown.port); - case AF_INET: - result = memcmp(&a->in.sin_addr, &b->in.sin_addr, sizeof(a->in.sin_addr)); + case AF_INET: + result = memcmp(&a->in.sin_addr, &b->in.sin_addr, sizeof(a->in.sin_addr)); - if(result) - return result; + if(result) { + return result; + } - return memcmp(&a->in.sin_port, &b->in.sin_port, sizeof(a->in.sin_port)); + return memcmp(&a->in.sin_port, &b->in.sin_port, sizeof(a->in.sin_port)); - case AF_INET6: - result = memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)); + case AF_INET6: + result = memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)); - if(result) - return result; + if(result) { + return result; + } - return memcmp(&a->in6.sin6_port, &b->in6.sin6_port, sizeof(a->in6.sin6_port)); + return memcmp(&a->in6.sin6_port, &b->in6.sin6_port, sizeof(a->in6.sin6_port)); - default: - logger(DEBUG_ALWAYS, LOG_ERR, "sockaddrcmp() was called with unknown address family %d, exitting!", - a->sa.sa_family); - abort(); + default: + logger(DEBUG_ALWAYS, LOG_ERR, "sockaddrcmp() was called with unknown address family %d, exitting!", + a->sa.sa_family); + abort(); } } @@ -237,19 +255,25 @@ void sockaddrunmap(sockaddr_t *sa) { void sockaddr_setport(sockaddr_t *sa, const char *port) { uint16_t portnum = htons(atoi(port)); - if(!portnum) + + if(!portnum) { return; + } + switch(sa->sa.sa_family) { - case AF_INET: - sa->in.sin_port = portnum; - break; - case AF_INET6: - sa->in6.sin6_port = portnum; - break; - case AF_UNKNOWN: - free(sa->unknown.port); - sa->unknown.port = xstrdup(port); - default: - return; + case AF_INET: + sa->in.sin_port = portnum; + break; + + case AF_INET6: + sa->in6.sin6_port = portnum; + break; + + case AF_UNKNOWN: + free(sa->unknown.port); + sa->unknown.port = xstrdup(port); + + default: + return; } } diff --git a/src/netutl.h b/src/netutl.h index 90aa54d..ca5466f 100644 --- a/src/netutl.h +++ b/src/netutl.h @@ -25,10 +25,10 @@ extern bool hostnames; -extern struct addrinfo *str2addrinfo(const char *, const char *, int) __attribute__ ((__malloc__)); +extern struct addrinfo *str2addrinfo(const char *, const char *, int) __attribute__((__malloc__)); extern sockaddr_t str2sockaddr(const char *, const char *); extern void sockaddr2str(const sockaddr_t *, char **, char **); -extern char *sockaddr2hostname(const sockaddr_t *) __attribute__ ((__malloc__)); +extern char *sockaddr2hostname(const sockaddr_t *) __attribute__((__malloc__)); extern int sockaddrcmp(const sockaddr_t *, const sockaddr_t *); extern int sockaddrcmp_noport(const sockaddr_t *, const sockaddr_t *); extern void sockaddrunmap(sockaddr_t *); diff --git a/src/node.c b/src/node.c index b4ddecb..c00124d 100644 --- a/src/node.c +++ b/src/node.c @@ -48,8 +48,11 @@ static int node_id_compare(const node_t *a, const node_t *b) { static int node_udp_compare(const node_t *a, const node_t *b) { int result = sockaddrcmp(&a->address, &b->address); - if (result) + + if(result) { return result; + } + return (a->name && b->name) ? strcmp(a->name, b->name) : 0; } @@ -68,7 +71,10 @@ void exit_nodes(void) { node_t *new_node(void) { node_t *n = xzalloc(sizeof(*n)); - if(replaywin) n->late = xzalloc(replaywin); + if(replaywin) { + n->late = xzalloc(replaywin); + } + n->subnet_tree = new_subnet_tree(); n->edge_tree = new_edge_tree(); n->mtu = MTU; @@ -78,11 +84,13 @@ node_t *new_node(void) { } void free_node(node_t *n) { - if(n->subnet_tree) + if(n->subnet_tree) { free_subnet_tree(n->subnet_tree); + } - if(n->edge_tree) + if(n->edge_tree) { free_edge_tree(n->edge_tree); + } sockaddrfree(&n->address); @@ -98,21 +106,24 @@ void free_node(node_t *n) { timeout_del(&n->udp_ping_timeout); - if(n->hostname) + if(n->hostname) { free(n->hostname); + } - if(n->name) + if(n->name) { free(n->name); + } - if(n->late) + if(n->late) { free(n->late); + } free(n); } void node_add(node_t *n) { unsigned char buf[64]; - sha512(n->name, strlen(n->name),buf); + sha512(n->name, strlen(n->name), buf); memcpy(&n->id, buf, sizeof(n->id)); splay_insert(node_tree, n); @@ -122,11 +133,13 @@ void node_add(node_t *n) { void node_del(node_t *n) { splay_delete(node_udp_tree, n); - for splay_each(subnet_t, s, n->subnet_tree) + for splay_each(subnet_t, s, n->subnet_tree) { subnet_del(n, s); + } - for splay_each(edge_t, e, n->edge_tree) + for splay_each(edge_t, e, n->edge_tree) { edge_del(e); + } splay_delete(node_id_tree, n); splay_delete(node_tree, n); @@ -161,12 +174,14 @@ void update_node_udp(node_t *n, const sockaddr_t *sa) { if(sa) { n->address = *sa; n->sock = 0; + for(int i = 0; i < listen_sockets; i++) { if(listen_socket[i].sa.sa.sa_family == sa->sa.sa_family) { n->sock = i; break; } } + splay_insert(node_udp_tree, n); free(n->hostname); n->hostname = sockaddr2hostname(&n->address); @@ -185,19 +200,22 @@ void update_node_udp(node_t *n, const sockaddr_t *sa) { bool dump_nodes(connection_t *c) { for splay_each(node_t, n, node_tree) { char id[2 * sizeof(n->id) + 1]; - for (size_t c = 0; c < sizeof(n->id); ++c) + + for(size_t c = 0; c < sizeof(n->id); ++c) { snprintf(id + 2 * c, 3, "%02x", n->id.x[c]); + } + id[sizeof(id) - 1] = 0; send_request(c, "%d %d %s %s %s %d %d %d %d %x %x %s %s %d %d %d %d %ld", CONTROL, REQ_DUMP_NODES, - n->name, id, n->hostname ?: "unknown port unknown", + n->name, id, n->hostname ? : "unknown port unknown", #ifdef DISABLE_LEGACY - 0, 0, 0, + 0, 0, 0, #else - cipher_get_nid(n->outcipher), digest_get_nid(n->outdigest), (int)digest_length(n->outdigest), + cipher_get_nid(n->outcipher), digest_get_nid(n->outdigest), (int)digest_length(n->outdigest), #endif - n->outcompression, n->options, bitfield_to_int(&n->status, sizeof(n->status)), - n->nexthop ? n->nexthop->name : "-", n->via ? n->via->name ?: "-" : "-", n->distance, - n->mtu, n->minmtu, n->maxmtu, (long)n->last_state_change); + n->outcompression, n->options, bitfield_to_int(&n->status, sizeof(n->status)), + n->nexthop ? n->nexthop->name : "-", n->via ? n->via->name ? : "-" : "-", n->distance, + n->mtu, n->minmtu, n->maxmtu, (long)n->last_state_change); } return send_request(c, "%d %d", CONTROL, REQ_DUMP_NODES); @@ -206,7 +224,7 @@ bool dump_nodes(connection_t *c) { bool dump_traffic(connection_t *c) { for splay_each(node_t, n, node_tree) send_request(c, "%d %d %s %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, CONTROL, REQ_DUMP_TRAFFIC, - n->name, n->in_packets, n->in_bytes, n->out_packets, n->out_bytes); + n->name, n->in_packets, n->in_bytes, n->out_packets, n->out_bytes); return send_request(c, "%d %d", CONTROL, REQ_DUMP_TRAFFIC); } diff --git a/src/node.h b/src/node.h index ad8b728..153dc11 100644 --- a/src/node.h +++ b/src/node.h @@ -29,19 +29,19 @@ #include "subnet.h" typedef struct node_status_t { - unsigned int unused_active:1; /* 1 if active (not used for nodes) */ - unsigned int validkey:1; /* 1 if we currently have a valid key for him */ - unsigned int waitingforkey:1; /* 1 if we already sent out a request */ - unsigned int visited:1; /* 1 if this node has been visited by one of the graph algorithms */ - unsigned int reachable:1; /* 1 if this node is reachable in the graph */ - unsigned int indirect:1; /* 1 if this node is not directly reachable by us */ - unsigned int sptps:1; /* 1 if this node supports SPTPS */ - unsigned int udp_confirmed:1; /* 1 if the address is one that we received UDP traffic on */ - unsigned int send_locally:1; /* 1 if the next UDP packet should be sent on the local network */ - unsigned int udppacket:1; /* 1 if the most recently received packet was UDP */ - unsigned int validkey_in:1; /* 1 if we have sent a valid key to him */ - unsigned int has_address:1; /* 1 if we know an external address for this node */ - unsigned int unused:20; + unsigned int unused_active: 1; /* 1 if active (not used for nodes) */ + unsigned int validkey: 1; /* 1 if we currently have a valid key for him */ + unsigned int waitingforkey: 1; /* 1 if we already sent out a request */ + unsigned int visited: 1; /* 1 if this node has been visited by one of the graph algorithms */ + unsigned int reachable: 1; /* 1 if this node is reachable in the graph */ + unsigned int indirect: 1; /* 1 if this node is not directly reachable by us */ + unsigned int sptps: 1; /* 1 if this node supports SPTPS */ + unsigned int udp_confirmed: 1; /* 1 if the address is one that we received UDP traffic on */ + unsigned int send_locally: 1; /* 1 if the next UDP packet should be sent on the local network */ + unsigned int udppacket: 1; /* 1 if the most recently received packet was UDP */ + unsigned int validkey_in: 1; /* 1 if we have sent a valid key to him */ + unsigned int has_address: 1; /* 1 if we know an external address for this node */ + unsigned int unused: 20; } node_status_t; typedef struct node_t { @@ -88,7 +88,7 @@ typedef struct node_t { uint32_t prev_received_seqno; uint32_t prev_received; uint32_t farfuture; /* Packets in a row that have arrived from the far future */ - unsigned char* late; /* Bitfield marking late packets */ + unsigned char *late; /* Bitfield marking late packets */ struct timeval udp_reply_sent; /* Last time a (gratuitous) UDP probe reply was sent */ struct timeval udp_ping_sent; /* Last time a UDP probe was sent */ @@ -99,7 +99,7 @@ typedef struct node_t { struct timeval mtu_info_sent; /* Last time a MTU_INFO message was sent */ struct timeval udp_info_sent; /* Last time a UDP_INFO message was sent */ - length_t maxrecentlen; /* Maximum size of recently received packets */ + length_t maxrecentlen; /* Maximum size of recently received packets */ length_t mtu; /* Maximum size of packets to send to this node */ length_t minmtu; /* Probed minimum MTU */ @@ -117,7 +117,7 @@ extern splay_tree_t *node_tree; extern void init_nodes(void); extern void exit_nodes(void); -extern node_t *new_node(void) __attribute__ ((__malloc__)); +extern node_t *new_node(void) __attribute__((__malloc__)); extern void free_node(node_t *); extern void node_add(node_t *); extern void node_del(node_t *); diff --git a/src/nolegacy/crypto.c b/src/nolegacy/crypto.c index f1113b4..44692fd 100644 --- a/src/nolegacy/crypto.c +++ b/src/nolegacy/crypto.c @@ -27,8 +27,11 @@ static int random_fd = -1; static void random_init(void) { random_fd = open("/dev/urandom", O_RDONLY); - if(random_fd < 0) + + if(random_fd < 0) { random_fd = open("/dev/random", O_RDONLY); + } + if(random_fd < 0) { fprintf(stderr, "Could not open source of random numbers: %s\n", strerror(errno)); abort(); @@ -42,12 +45,16 @@ static void random_exit(void) { void randomize(void *out, size_t outlen) { while(outlen) { size_t len = read(random_fd, out, outlen); + if(len <= 0) { - if(errno == EAGAIN || errno == EINTR) + if(errno == EAGAIN || errno == EINTR) { continue; + } + fprintf(stderr, "Could not read random numbers: %s\n", strerror(errno)); abort(); } + out += len; outlen -= len; } diff --git a/src/nolegacy/prf.c b/src/nolegacy/prf.c index 1937f67..ce80f8c 100644 --- a/src/nolegacy/prf.c +++ b/src/nolegacy/prf.c @@ -23,8 +23,9 @@ #include "../ed25519/sha512.h" static void memxor(char *buf, char c, size_t len) { - for(size_t i = 0; i < len; i++) + for(size_t i = 0; i < len; i++) { buf[i] ^= c; + } } static const size_t mdlen = 64; @@ -38,30 +39,39 @@ static bool hmac_sha512(const char *key, size_t keylen, const char *msg, size_t memcpy(tmp, key, keylen); memset(tmp + keylen, 0, blklen - keylen); } else { - if(sha512(key, keylen, tmp) != 0) + if(sha512(key, keylen, tmp) != 0) { return false; + } + memset(tmp + mdlen, 0, blklen - mdlen); } - if(sha512_init(&md) != 0) + if(sha512_init(&md) != 0) { return false; + } // ipad memxor(tmp, 0x36, blklen); - if(sha512_update(&md, tmp, blklen) != 0) + + if(sha512_update(&md, tmp, blklen) != 0) { return false; + } // message - if(sha512_update(&md, msg, msglen) != 0) + if(sha512_update(&md, msg, msglen) != 0) { return false; + } - if(sha512_final(&md, tmp + blklen) != 0) + if(sha512_final(&md, tmp + blklen) != 0) { return false; + } // opad memxor(tmp, 0x36 ^ 0x5c, blklen); - if(sha512(tmp, sizeof(tmp), out) != 0) + + if(sha512(tmp, sizeof(tmp), out) != 0) { return false; + } return true; } @@ -84,18 +94,23 @@ bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char while(outlen > 0) { /* Inner HMAC */ - if(!hmac_sha512(secret, secretlen, data, sizeof(data), data)) + if(!hmac_sha512(secret, secretlen, data, sizeof(data), data)) { return false; + } /* Outer HMAC */ if(outlen >= mdlen) { - if(!hmac_sha512(secret, secretlen, data, sizeof(data), out)) + if(!hmac_sha512(secret, secretlen, data, sizeof(data), out)) { return false; + } + out += mdlen; outlen -= mdlen; } else { - if(!hmac_sha512(secret, secretlen, data, sizeof(data), hash)) + if(!hmac_sha512(secret, secretlen, data, sizeof(data), hash)) { return false; + } + memcpy(out, hash, outlen); out += outlen; outlen = 0; diff --git a/src/openssl/cipher.c b/src/openssl/cipher.c index d5cafa4..d51ec0d 100644 --- a/src/openssl/cipher.c +++ b/src/openssl/cipher.c @@ -36,14 +36,17 @@ static cipher_t *cipher_open(const EVP_CIPHER *evp_cipher) { cipher_t *cipher = xzalloc(sizeof(*cipher)); cipher->cipher = evp_cipher; cipher->ctx = EVP_CIPHER_CTX_new(); - if(!cipher->ctx) + + if(!cipher->ctx) { abort(); + } return cipher; } cipher_t *cipher_open_by_name(const char *name) { const EVP_CIPHER *evp_cipher = EVP_get_cipherbyname(name); + if(!evp_cipher) { logger(DEBUG_ALWAYS, LOG_ERR, "Unknown cipher name '%s'!", name); return NULL; @@ -54,6 +57,7 @@ cipher_t *cipher_open_by_name(const char *name) { cipher_t *cipher_open_by_nid(int nid) { const EVP_CIPHER *evp_cipher = EVP_get_cipherbynid(nid); + if(!evp_cipher) { logger(DEBUG_ALWAYS, LOG_ERR, "Unknown cipher nid %d!", nid); return NULL; @@ -63,16 +67,18 @@ cipher_t *cipher_open_by_nid(int nid) { } void cipher_close(cipher_t *cipher) { - if(!cipher) + if(!cipher) { return; + } EVP_CIPHER_CTX_free(cipher->ctx); free(cipher); } size_t cipher_keylength(const cipher_t *cipher) { - if(!cipher || !cipher->cipher) + if(!cipher || !cipher->cipher) { return 0; + } return EVP_CIPHER_key_length(cipher->cipher) + EVP_CIPHER_iv_length(cipher->cipher); } @@ -85,8 +91,9 @@ uint64_t cipher_budget(const cipher_t *cipher) { is limited to what can be represented with a 64 bits integer. */ - if(!cipher || !cipher->cipher) - return UINT64_MAX; // NULL cipher + if(!cipher || !cipher->cipher) { + return UINT64_MAX; // NULL cipher + } int ivlen = EVP_CIPHER_iv_length(cipher->cipher); int blklen = EVP_CIPHER_block_size(cipher->cipher); @@ -96,8 +103,9 @@ uint64_t cipher_budget(const cipher_t *cipher) { } size_t cipher_blocksize(const cipher_t *cipher) { - if(!cipher || !cipher->cipher) + if(!cipher || !cipher->cipher) { return 1; + } return EVP_CIPHER_block_size(cipher->cipher); } @@ -105,13 +113,15 @@ size_t cipher_blocksize(const cipher_t *cipher) { bool cipher_set_key(cipher_t *cipher, void *key, bool encrypt) { bool result; - if(encrypt) + if(encrypt) { result = EVP_EncryptInit_ex(cipher->ctx, cipher->cipher, NULL, (unsigned char *)key, (unsigned char *)key + EVP_CIPHER_key_length(cipher->cipher)); - else + } else { result = EVP_DecryptInit_ex(cipher->ctx, cipher->cipher, NULL, (unsigned char *)key, (unsigned char *)key + EVP_CIPHER_key_length(cipher->cipher)); + } - if(result) + if(result) { return true; + } logger(DEBUG_ALWAYS, LOG_ERR, "Error while setting key: %s", ERR_error_string(ERR_get_error(), NULL)); return false; @@ -120,13 +130,15 @@ bool cipher_set_key(cipher_t *cipher, void *key, bool encrypt) { bool cipher_set_key_from_rsa(cipher_t *cipher, void *key, size_t len, bool encrypt) { bool result; - if(encrypt) + if(encrypt) { result = EVP_EncryptInit_ex(cipher->ctx, cipher->cipher, NULL, (unsigned char *)key + len - EVP_CIPHER_key_length(cipher->cipher), (unsigned char *)key + len - EVP_CIPHER_iv_length(cipher->cipher) - EVP_CIPHER_key_length(cipher->cipher)); - else + } else { result = EVP_DecryptInit_ex(cipher->ctx, cipher->cipher, NULL, (unsigned char *)key + len - EVP_CIPHER_key_length(cipher->cipher), (unsigned char *)key + len - EVP_CIPHER_iv_length(cipher->cipher) - EVP_CIPHER_key_length(cipher->cipher)); + } - if(result) + if(result) { return true; + } logger(DEBUG_ALWAYS, LOG_ERR, "Error while setting key: %s", ERR_error_string(ERR_get_error(), NULL)); return false; @@ -135,16 +147,24 @@ bool cipher_set_key_from_rsa(cipher_t *cipher, void *key, size_t len, bool encry bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) { if(oneshot) { int len, pad; + if(EVP_EncryptInit_ex(cipher->ctx, NULL, NULL, NULL, NULL) - && EVP_EncryptUpdate(cipher->ctx, (unsigned char *)outdata, &len, indata, inlen) - && EVP_EncryptFinal_ex(cipher->ctx, (unsigned char *)outdata + len, &pad)) { - if(outlen) *outlen = len + pad; + && EVP_EncryptUpdate(cipher->ctx, (unsigned char *)outdata, &len, indata, inlen) + && EVP_EncryptFinal_ex(cipher->ctx, (unsigned char *)outdata + len, &pad)) { + if(outlen) { + *outlen = len + pad; + } + return true; } } else { int len; + if(EVP_EncryptUpdate(cipher->ctx, outdata, &len, indata, inlen)) { - if(outlen) *outlen = len; + if(outlen) { + *outlen = len; + } + return true; } } @@ -156,16 +176,24 @@ bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) { if(oneshot) { int len, pad; + if(EVP_DecryptInit_ex(cipher->ctx, NULL, NULL, NULL, NULL) - && EVP_DecryptUpdate(cipher->ctx, (unsigned char *)outdata, &len, indata, inlen) - && EVP_DecryptFinal_ex(cipher->ctx, (unsigned char *)outdata + len, &pad)) { - if(outlen) *outlen = len + pad; + && EVP_DecryptUpdate(cipher->ctx, (unsigned char *)outdata, &len, indata, inlen) + && EVP_DecryptFinal_ex(cipher->ctx, (unsigned char *)outdata + len, &pad)) { + if(outlen) { + *outlen = len + pad; + } + return true; } } else { int len; + if(EVP_EncryptUpdate(cipher->ctx, outdata, &len, indata, inlen)) { - if(outlen) *outlen = len; + if(outlen) { + *outlen = len; + } + return true; } } @@ -175,8 +203,9 @@ bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou } int cipher_get_nid(const cipher_t *cipher) { - if(!cipher || !cipher->cipher) + if(!cipher || !cipher->cipher) { return 0; + } return EVP_CIPHER_nid(cipher->cipher); } diff --git a/src/openssl/crypto.c b/src/openssl/crypto.c index 5b866b0..6894d87 100644 --- a/src/openssl/crypto.c +++ b/src/openssl/crypto.c @@ -31,8 +31,11 @@ static int random_fd = -1; static void random_init(void) { random_fd = open("/dev/urandom", O_RDONLY); - if(random_fd < 0) + + if(random_fd < 0) { random_fd = open("/dev/random", O_RDONLY); + } + if(random_fd < 0) { fprintf(stderr, "Could not open source of random numbers: %s\n", strerror(errno)); abort(); @@ -46,12 +49,16 @@ static void random_exit(void) { void randomize(void *out, size_t outlen) { while(outlen) { size_t len = read(random_fd, out, outlen); + if(len <= 0) { - if(errno == EAGAIN || errno == EINTR) + if(errno == EAGAIN || errno == EINTR) { continue; + } + fprintf(stderr, "Could not read random numbers: %s\n", strerror(errno)); abort(); } + out += len; outlen -= len; } diff --git a/src/openssl/digest.c b/src/openssl/digest.c index 65df7cb..9c3ab1e 100644 --- a/src/openssl/digest.c +++ b/src/openssl/digest.c @@ -34,10 +34,11 @@ static digest_t *digest_open(const EVP_MD *evp_md, int maclength) { int digestlen = EVP_MD_size(digest->digest); - if(maclength > digestlen || maclength < 0) + if(maclength > digestlen || maclength < 0) { digest->maclength = digestlen; - else + } else { digest->maclength = maclength; + } return digest; } @@ -72,8 +73,9 @@ bool digest_set_key(digest_t *digest, const void *key, size_t len) { } void digest_close(digest_t *digest) { - if(!digest) + if(!digest) { return; + } free(digest->key); free(digest); @@ -90,12 +92,14 @@ bool digest_create(digest_t *digest, const void *indata, size_t inlen, void *out } } else { EVP_MD_CTX *ctx = EVP_MD_CTX_create(); - if(!ctx) + + if(!ctx) { abort(); + } if(!EVP_DigestInit(ctx, digest->digest) - || !EVP_DigestUpdate(ctx, indata, inlen) - || !EVP_DigestFinal(ctx, tmpdata, NULL)) { + || !EVP_DigestUpdate(ctx, indata, inlen) + || !EVP_DigestFinal(ctx, tmpdata, NULL)) { logger(DEBUG_ALWAYS, LOG_DEBUG, "Error creating digest: %s", ERR_error_string(ERR_get_error(), NULL)); EVP_MD_CTX_destroy(ctx); return false; @@ -116,22 +120,25 @@ bool digest_verify(digest_t *digest, const void *indata, size_t inlen, const voi } int digest_get_nid(const digest_t *digest) { - if(!digest || !digest->digest) + if(!digest || !digest->digest) { return 0; + } return EVP_MD_type(digest->digest); } size_t digest_keylength(const digest_t *digest) { - if(!digest || !digest->digest) + if(!digest || !digest->digest) { return 0; + } return EVP_MD_size(digest->digest); } size_t digest_length(const digest_t *digest) { - if(!digest) + if(!digest) { return 0; + } return digest->maclength; } diff --git a/src/openssl/prf.c b/src/openssl/prf.c index 4f5a52b..d87c5c6 100644 --- a/src/openssl/prf.c +++ b/src/openssl/prf.c @@ -32,8 +32,9 @@ static bool prf_xor(int nid, const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, ssize_t outlen) { digest_t *digest = digest_open_by_nid(nid, -1); - if(!digest) + if(!digest) { return false; + } if(!digest_set_key(digest, secret, secretlen)) { digest_close(digest); @@ -66,8 +67,9 @@ static bool prf_xor(int nid, const char *secret, size_t secretlen, char *seed, s } /* XOR the results of the outer HMAC into the out buffer */ - for(int i = 0; i < len && i < outlen; i++) + for(int i = 0; i < len && i < outlen; i++) { *out++ ^= hash[i]; + } outlen -= len; } diff --git a/src/openssl/rsa.c b/src/openssl/rsa.c index 3543df3..e1ae4f6 100644 --- a/src/openssl/rsa.c +++ b/src/openssl/rsa.c @@ -32,9 +32,12 @@ typedef RSA rsa_t; #ifndef HAVE_RSA_SET0_KEY int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) { - BN_free(r->n); r->n = n; - BN_free(r->e); r->e = e; - BN_free(r->d); r->d = d; + BN_free(r->n); + r->n = n; + BN_free(r->e); + r->e = e; + BN_free(r->d); + r->d = d; return 1; } #endif @@ -50,9 +53,11 @@ rsa_t *rsa_set_hex_public_key(char *n, char *e) { } rsa_t *rsa = RSA_new(); - if(!rsa) + + if(!rsa) { return NULL; - + } + RSA_set0_key(rsa, bn_n, bn_e, NULL); return rsa; @@ -71,8 +76,10 @@ rsa_t *rsa_set_hex_private_key(char *n, char *e, char *d) { } rsa_t *rsa = RSA_new(); - if(!rsa) + + if(!rsa) { return NULL; + } RSA_set0_key(rsa, bn_n, bn_e, bn_d); @@ -89,8 +96,9 @@ rsa_t *rsa_read_pem_public_key(FILE *fp) { rsa = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL); } - if(!rsa) + if(!rsa) { logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA public key: %s", ERR_error_string(ERR_get_error(), NULL)); + } return rsa; } @@ -98,8 +106,9 @@ rsa_t *rsa_read_pem_public_key(FILE *fp) { rsa_t *rsa_read_pem_private_key(FILE *fp) { rsa_t *rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL); - if(!rsa) + if(!rsa) { logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA private key: %s", ERR_error_string(ERR_get_error(), NULL)); + } return rsa; } @@ -109,16 +118,18 @@ size_t rsa_size(rsa_t *rsa) { } bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) { - if(RSA_public_encrypt(len, in, out, rsa, RSA_NO_PADDING) == len) + if(RSA_public_encrypt(len, in, out, rsa, RSA_NO_PADDING) == len) { return true; + } logger(DEBUG_ALWAYS, LOG_ERR, "Unable to perform RSA encryption: %s", ERR_error_string(ERR_get_error(), NULL)); return false; } bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) { - if(RSA_private_decrypt(len, in, out, rsa, RSA_NO_PADDING) == len) + if(RSA_private_decrypt(len, in, out, rsa, RSA_NO_PADDING) == len) { return true; + } logger(DEBUG_ALWAYS, LOG_ERR, "Unable to perform RSA decryption: %s", ERR_error_string(ERR_get_error(), NULL)); return false; @@ -129,6 +140,7 @@ bool rsa_active(rsa_t *rsa) { } void rsa_free(rsa_t *rsa) { - if(rsa) + if(rsa) { RSA_free(rsa); + } } diff --git a/src/openssl/rsagen.c b/src/openssl/rsagen.c index 78a22d9..c854697 100644 --- a/src/openssl/rsagen.c +++ b/src/openssl/rsagen.c @@ -32,36 +32,37 @@ typedef RSA rsa_t; /* This function prettyprints the key generation process */ static int indicator(int a, int b, BN_GENCB *cb) { - switch (a) { - case 0: - fprintf(stderr, "."); - break; - - case 1: - fprintf(stderr, "+"); - break; + switch(a) { + case 0: + fprintf(stderr, "."); + break; - case 2: - fprintf(stderr, "-"); - break; + case 1: + fprintf(stderr, "+"); + break; - case 3: - switch (b) { - case 0: - fprintf(stderr, " p\n"); - break; + case 2: + fprintf(stderr, "-"); + break; - case 1: - fprintf(stderr, " q\n"); - break; + case 3: + switch(b) { + case 0: + fprintf(stderr, " p\n"); + break; - default: - fprintf(stderr, "?"); - } + case 1: + fprintf(stderr, " q\n"); break; default: fprintf(stderr, "?"); + } + + break; + + default: + fprintf(stderr, "?"); } return 1; @@ -84,8 +85,9 @@ rsa_t *rsa_generate(size_t bits, unsigned long exponent) { rsa_t *rsa = RSA_new(); BN_GENCB *cb = BN_GENCB_new(); - if(!bn_e || !rsa || !cb) + if(!bn_e || !rsa || !cb) { abort(); + } BN_set_word(bn_e, exponent); BN_GENCB_set(cb, indicator, NULL); diff --git a/src/prf.h b/src/prf.h index 6f5448b..9e64989 100644 --- a/src/prf.h +++ b/src/prf.h @@ -20,6 +20,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -extern bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen) __attribute__ ((__warn_unused_result__)); +extern bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen) __attribute__((__warn_unused_result__)); #endif diff --git a/src/process.c b/src/process.c index 153dc67..c6cb536 100644 --- a/src/process.c +++ b/src/process.c @@ -57,6 +57,7 @@ static bool install_service(void) { SERVICE_DESCRIPTION description = {"Virtual Private Network daemon"}; manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + if(!manager) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not open service manager: %s", winerror(GetLastError())); return false; @@ -72,24 +73,28 @@ static bool install_service(void) { char *space = strchr(*argp, ' '); strncat(command, " ", sizeof(command) - strlen(command)); - if(space) + if(space) { strncat(command, "\"", sizeof(command) - strlen(command)); + } strncat(command, *argp, sizeof(command) - strlen(command)); - if(space) + if(space) { strncat(command, "\"", sizeof(command) - strlen(command)); + } } service = CreateService(manager, identname, identname, - SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, - command, NULL, NULL, NULL, NULL, NULL); + SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, + command, NULL, NULL, NULL, NULL, NULL); if(!service) { DWORD lasterror = GetLastError(); logger(DEBUG_ALWAYS, LOG_ERR, "Could not create %s service: %s", identname, winerror(lasterror)); - if(lasterror != ERROR_SERVICE_EXISTS) + + if(lasterror != ERROR_SERVICE_EXISTS) { return false; + } } if(service) { @@ -99,10 +104,11 @@ static bool install_service(void) { service = OpenService(manager, identname, SERVICE_ALL_ACCESS); } - if(!StartService(service, 0, NULL)) + if(!StartService(service, 0, NULL)) { logger(DEBUG_ALWAYS, LOG_WARNING, "Could not start %s service: %s", identname, winerror(GetLastError())); - else + } else { logger(DEBUG_ALWAYS, LOG_INFO, "%s service started", identname); + } return true; } @@ -111,29 +117,35 @@ io_t stop_io; DWORD WINAPI controlhandler(DWORD request, DWORD type, LPVOID boe, LPVOID bah) { switch(request) { - case SERVICE_CONTROL_INTERROGATE: - SetServiceStatus(statushandle, &status); - return NO_ERROR; - case SERVICE_CONTROL_STOP: - logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s request", "SERVICE_CONTROL_STOP"); - break; - case SERVICE_CONTROL_SHUTDOWN: - logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s request", "SERVICE_CONTROL_SHUTDOWN"); - break; - default: - logger(DEBUG_ALWAYS, LOG_WARNING, "Got unexpected request %d", (int)request); - return ERROR_CALL_NOT_IMPLEMENTED; + case SERVICE_CONTROL_INTERROGATE: + SetServiceStatus(statushandle, &status); + return NO_ERROR; + + case SERVICE_CONTROL_STOP: + logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s request", "SERVICE_CONTROL_STOP"); + break; + + case SERVICE_CONTROL_SHUTDOWN: + logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s request", "SERVICE_CONTROL_SHUTDOWN"); + break; + + default: + logger(DEBUG_ALWAYS, LOG_WARNING, "Got unexpected request %d", (int)request); + return ERROR_CALL_NOT_IMPLEMENTED; } status.dwWaitHint = 1000; status.dwCurrentState = SERVICE_STOP_PENDING; SetServiceStatus(statushandle, &status); - if (WSASetEvent(stop_io.event) == FALSE) + + if(WSASetEvent(stop_io.event) == FALSE) { abort(); + } + return NO_ERROR; } -VOID WINAPI run_service(DWORD argc, LPTSTR* argv) { +VOID WINAPI run_service(DWORD argc, LPTSTR *argv) { extern int main2(int argc, char **argv); status.dwServiceType = SERVICE_WIN32; @@ -144,7 +156,7 @@ VOID WINAPI run_service(DWORD argc, LPTSTR* argv) { statushandle = RegisterServiceCtrlHandlerEx(identname, controlhandler, NULL); - if (!statushandle) { + if(!statushandle) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "RegisterServiceCtrlHandlerEx", winerror(GetLastError())); } else { status.dwWaitHint = 30000; @@ -174,9 +186,9 @@ bool init_service(void) { if(!StartServiceCtrlDispatcher(services)) { if(GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) { return false; - } - else + } else { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "StartServiceCtrlDispatcher", winerror(GetLastError())); + } } return true; @@ -200,27 +212,33 @@ bool detach(void) { if(do_detach) { #ifndef HAVE_MINGW + if(daemon(1, 0)) { logger(DEBUG_ALWAYS, LOG_ERR, "Couldn't detach from terminal: %s", strerror(errno)); return false; } + #else - if(!statushandle) + + if(!statushandle) { exit(!install_service()); + } + #endif } - if(use_logfile) + if(use_logfile) { logmode = LOGMODE_FILE; - else if(use_syslog || do_detach) + } else if(use_syslog || do_detach) { logmode = LOGMODE_SYSLOG; - else + } else { logmode = LOGMODE_STDERR; + } openlogger(identname, logmode); logger(DEBUG_ALWAYS, LOG_NOTICE, "tincd %s (%s %s) starting, debug level %d", - BUILD_VERSION, BUILD_DATE, BUILD_TIME, debug_level); + BUILD_VERSION, BUILD_DATE, BUILD_TIME, debug_level); return true; } diff --git a/src/protocol.c b/src/protocol.c index 79d5273..941459c 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -35,26 +35,26 @@ bool experimental = true; /* Jumptable for the request handlers */ static bool (*request_handlers[])(connection_t *, const char *) = { - id_h, metakey_h, challenge_h, chal_reply_h, ack_h, - status_h, error_h, termreq_h, - ping_h, pong_h, - add_subnet_h, del_subnet_h, - add_edge_h, del_edge_h, - key_changed_h, req_key_h, ans_key_h, tcppacket_h, control_h, - NULL, NULL, /* Not "real" requests (yet) */ - sptps_tcppacket_h, - udp_info_h, mtu_info_h, + id_h, metakey_h, challenge_h, chal_reply_h, ack_h, + status_h, error_h, termreq_h, + ping_h, pong_h, + add_subnet_h, del_subnet_h, + add_edge_h, del_edge_h, + key_changed_h, req_key_h, ans_key_h, tcppacket_h, control_h, + NULL, NULL, /* Not "real" requests (yet) */ + sptps_tcppacket_h, + udp_info_h, mtu_info_h, }; /* Request names */ static char (*request_name[]) = { - "ID", "METAKEY", "CHALLENGE", "CHAL_REPLY", "ACK", - "STATUS", "ERROR", "TERMREQ", - "PING", "PONG", - "ADD_SUBNET", "DEL_SUBNET", - "ADD_EDGE", "DEL_EDGE", "KEY_CHANGED", "REQ_KEY", "ANS_KEY", "PACKET", "CONTROL", - "REQ_PUBKEY", "ANS_PUBKEY", "SPTPS_PACKET", "UDP_INFO", "MTU_INFO", + "ID", "METAKEY", "CHALLENGE", "CHAL_REPLY", "ACK", + "STATUS", "ERROR", "TERMREQ", + "PING", "PONG", + "ADD_SUBNET", "DEL_SUBNET", + "ADD_EDGE", "DEL_EDGE", "KEY_CHANGED", "REQ_KEY", "ANS_KEY", "PACKET", "CONTROL", + "REQ_PUBKEY", "ANS_PUBKEY", "SPTPS_PACKET", "UDP_INFO", "MTU_INFO", }; static splay_tree_t *past_request_tree; @@ -78,7 +78,7 @@ bool send_request(connection_t *c, const char *format, ...) { if(len < 0 || len > sizeof(request) - 1) { logger(DEBUG_ALWAYS, LOG_ERR, "Output buffer overflow while sending request to %s (%s)", - c->name, c->hostname); + c->name, c->hostname); return false; } @@ -89,8 +89,9 @@ bool send_request(connection_t *c, const char *format, ...) { if(c == everyone) { broadcast_meta(NULL, request, len); return true; - } else + } else { return send_meta(c, request, len); + } } void forward_request(connection_t *from, const char *request) { @@ -106,8 +107,10 @@ void forward_request(connection_t *from, const char *request) { bool receive_request(connection_t *c, const char *request) { if(c->outgoing && proxytype == PROXY_HTTP && c->allow_request == ID) { - if(!request[0] || request[0] == '\r') + if(!request[0] || request[0] == '\r') { return true; + } + if(!strncasecmp(request, "HTTP/1.1 ", 9)) { if(!strncmp(request + 9, "200", 3)) { logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Proxy request granted"); @@ -137,8 +140,10 @@ bool receive_request(connection_t *c, const char *request) { if(!request_handlers[reqno](c, request)) { /* Something went wrong. Probably scriptkiddies. Terminate. */ - if(reqno != TERMREQ) + if(reqno != TERMREQ) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while processing %s from %s (%s)", request_name[reqno], c->name, c->hostname); + } + return false; } } else { @@ -154,8 +159,9 @@ static int past_request_compare(const past_request_t *a, const past_request_t *b } static void free_past_request(past_request_t *r) { - if(r->request) + if(r->request) { free((char *)r->request); + } free(r); } @@ -166,17 +172,21 @@ static void age_past_requests(void *data) { int left = 0, deleted = 0; for splay_each(past_request_t, p, past_request_tree) { - if(p->firstseen + pinginterval <= now.tv_sec) + if(p->firstseen + pinginterval <= now.tv_sec) { splay_delete_node(past_request_tree, node), deleted++; - else + } else { left++; + } } - if(left || deleted) + if(left || deleted) { logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Aging past requests: deleted %d, left %d", deleted, left); + } if(left) - timeout_set(&past_request_timeout, &(struct timeval){10, rand() % 100000}); + timeout_set(&past_request_timeout, &(struct timeval) { + 10, rand() % 100000 + }); } bool seen_request(const char *request) { @@ -192,7 +202,9 @@ bool seen_request(const char *request) { new->request = xstrdup(request); new->firstseen = now.tv_sec; splay_insert(past_request_tree, new); - timeout_add(&past_request_timeout, age_past_requests, NULL, &(struct timeval){10, rand() % 100000}); + timeout_add(&past_request_timeout, age_past_requests, NULL, &(struct timeval) { + 10, rand() % 100000 + }); return false; } } diff --git a/src/protocol.h b/src/protocol.h index c0e6f4f..390349c 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -80,7 +80,7 @@ extern ecdsa_t *invitation_key; /* Basic functions */ -extern bool send_request(struct connection_t *, const char *, ...) __attribute__ ((__format__(printf, 2, 3))); +extern bool send_request(struct connection_t *, const char *, ...) __attribute__((__format__(printf, 2, 3))); extern void forward_request(struct connection_t *, const char *); extern bool receive_request(struct connection_t *, const char *); @@ -109,7 +109,7 @@ extern void send_key_changed(void); extern bool send_req_key(struct node_t *); extern bool send_ans_key(struct node_t *); extern bool send_tcppacket(struct connection_t *, const struct vpn_packet_t *); -extern bool send_sptps_tcppacket(struct connection_t *, const char*, int); +extern bool send_sptps_tcppacket(struct connection_t *, const char *, int); extern bool send_udp_info(struct node_t *, struct node_t *); extern bool send_mtu_info(struct node_t *, struct node_t *, int); diff --git a/src/protocol_auth.c b/src/protocol_auth.c index 2cface2..68dd071 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -52,87 +52,105 @@ ecdsa_t *invitation_key = NULL; static bool send_proxyrequest(connection_t *c) { switch(proxytype) { - case PROXY_HTTP: { - char *host; - char *port; - - sockaddr2str(&c->address, &host, &port); - send_request(c, "CONNECT %s:%s HTTP/1.1\r\n\r", host, port); - free(host); - free(port); - return true; + case PROXY_HTTP: { + char *host; + char *port; + + sockaddr2str(&c->address, &host, &port); + send_request(c, "CONNECT %s:%s HTTP/1.1\r\n\r", host, port); + free(host); + free(port); + return true; + } + + case PROXY_SOCKS4: { + if(c->address.sa.sa_family != AF_INET) { + logger(DEBUG_ALWAYS, LOG_ERR, "Cannot connect to an IPv6 host through a SOCKS 4 proxy!"); + return false; } - case PROXY_SOCKS4: { - if(c->address.sa.sa_family != AF_INET) { - logger(DEBUG_ALWAYS, LOG_ERR, "Cannot connect to an IPv6 host through a SOCKS 4 proxy!"); - return false; - } - char s4req[9 + (proxyuser ? strlen(proxyuser) : 0)]; - s4req[0] = 4; - s4req[1] = 1; - memcpy(s4req + 2, &c->address.in.sin_port, 2); - memcpy(s4req + 4, &c->address.in.sin_addr, 4); - if(proxyuser) - memcpy(s4req + 8, proxyuser, strlen(proxyuser)); - s4req[sizeof(s4req) - 1] = 0; - c->tcplen = 8; - return send_meta(c, s4req, sizeof(s4req)); + + char s4req[9 + (proxyuser ? strlen(proxyuser) : 0)]; + s4req[0] = 4; + s4req[1] = 1; + memcpy(s4req + 2, &c->address.in.sin_port, 2); + memcpy(s4req + 4, &c->address.in.sin_addr, 4); + + if(proxyuser) { + memcpy(s4req + 8, proxyuser, strlen(proxyuser)); } - case PROXY_SOCKS5: { - int len = 3 + 6 + (c->address.sa.sa_family == AF_INET ? 4 : 16); - c->tcplen = 2; - if(proxypass) - len += 3 + strlen(proxyuser) + strlen(proxypass); - char s5req[len]; - int i = 0; - s5req[i++] = 5; - s5req[i++] = 1; - if(proxypass) { - s5req[i++] = 2; - s5req[i++] = 1; - s5req[i++] = strlen(proxyuser); - memcpy(s5req + i, proxyuser, strlen(proxyuser)); - i += strlen(proxyuser); - s5req[i++] = strlen(proxypass); - memcpy(s5req + i, proxypass, strlen(proxypass)); - i += strlen(proxypass); - c->tcplen += 2; - } else { - s5req[i++] = 0; - } - s5req[i++] = 5; + + s4req[sizeof(s4req) - 1] = 0; + c->tcplen = 8; + return send_meta(c, s4req, sizeof(s4req)); + } + + case PROXY_SOCKS5: { + int len = 3 + 6 + (c->address.sa.sa_family == AF_INET ? 4 : 16); + c->tcplen = 2; + + if(proxypass) { + len += 3 + strlen(proxyuser) + strlen(proxypass); + } + + char s5req[len]; + int i = 0; + s5req[i++] = 5; + s5req[i++] = 1; + + if(proxypass) { + s5req[i++] = 2; s5req[i++] = 1; + s5req[i++] = strlen(proxyuser); + memcpy(s5req + i, proxyuser, strlen(proxyuser)); + i += strlen(proxyuser); + s5req[i++] = strlen(proxypass); + memcpy(s5req + i, proxypass, strlen(proxypass)); + i += strlen(proxypass); + c->tcplen += 2; + } else { s5req[i++] = 0; - if(c->address.sa.sa_family == AF_INET) { - s5req[i++] = 1; - memcpy(s5req + i, &c->address.in.sin_addr, 4); - i += 4; - memcpy(s5req + i, &c->address.in.sin_port, 2); - i += 2; - c->tcplen += 10; - } else if(c->address.sa.sa_family == AF_INET6) { - s5req[i++] = 3; - memcpy(s5req + i, &c->address.in6.sin6_addr, 16); - i += 16; - memcpy(s5req + i, &c->address.in6.sin6_port, 2); - i += 2; - c->tcplen += 22; - } else { - logger(DEBUG_ALWAYS, LOG_ERR, "Address family %x not supported for SOCKS 5 proxies!", c->address.sa.sa_family); - return false; - } - if(i > len) - abort(); - return send_meta(c, s5req, sizeof(s5req)); } - case PROXY_SOCKS4A: - logger(DEBUG_ALWAYS, LOG_ERR, "Proxy type not implemented yet"); - return false; - case PROXY_EXEC: - return true; - default: - logger(DEBUG_ALWAYS, LOG_ERR, "Unknown proxy type"); + + s5req[i++] = 5; + s5req[i++] = 1; + s5req[i++] = 0; + + if(c->address.sa.sa_family == AF_INET) { + s5req[i++] = 1; + memcpy(s5req + i, &c->address.in.sin_addr, 4); + i += 4; + memcpy(s5req + i, &c->address.in.sin_port, 2); + i += 2; + c->tcplen += 10; + } else if(c->address.sa.sa_family == AF_INET6) { + s5req[i++] = 3; + memcpy(s5req + i, &c->address.in6.sin6_addr, 16); + i += 16; + memcpy(s5req + i, &c->address.in6.sin6_port, 2); + i += 2; + c->tcplen += 22; + } else { + logger(DEBUG_ALWAYS, LOG_ERR, "Address family %x not supported for SOCKS 5 proxies!", c->address.sa.sa_family); return false; + } + + if(i > len) { + abort(); + } + + return send_meta(c, s5req, sizeof(s5req)); + } + + case PROXY_SOCKS4A: + logger(DEBUG_ALWAYS, LOG_ERR, "Proxy type not implemented yet"); + return false; + + case PROXY_EXEC: + return true; + + default: + logger(DEBUG_ALWAYS, LOG_ERR, "Unknown proxy type"); + return false; } } @@ -142,15 +160,17 @@ bool send_id(connection_t *c) { int minor = 0; if(experimental) { - if(c->outgoing && !read_ecdsa_public_key(c)) + if(c->outgoing && !read_ecdsa_public_key(c)) { minor = 1; - else + } else { minor = myself->connection->protocol_minor; + } } if(proxytype && c->outgoing) - if(!send_proxyrequest(c)) + if(!send_proxyrequest(c)) { return false; + } return send_request(c, "%d %s %d.%d", ID, myself->connection->name, myself->connection->protocol_major, minor); } @@ -164,12 +184,14 @@ static bool finalize_invitation(connection_t *c, const char *data, uint16_t len) // Create a new host config file char filename[PATH_MAX]; snprintf(filename, sizeof(filename), "%s" SLASH "hosts" SLASH "%s", confbase, c->name); + if(!access(filename, F_OK)) { logger(DEBUG_ALWAYS, LOG_ERR, "Host config file for %s (%s) already exists!\n", c->name, c->hostname); return false; } FILE *f = fopen(filename, "w"); + if(!f) { logger(DEBUG_ALWAYS, LOG_ERR, "Error trying to create %s: %s\n", filename, strerror(errno)); return false; @@ -185,7 +207,7 @@ static bool finalize_invitation(connection_t *c, const char *data, uint16_t len) char *address, *port; environment_init(&env); - environment_add(&env, "NODE=%s", c->name); + environment_add(&env, "NODE=%s", c->name); sockaddr2str(&c->address, &address, &port); environment_add(&env, "REMOTEADDRESS=%s", address); environment_add(&env, "NAME=%s", myself->name); @@ -201,14 +223,17 @@ static bool finalize_invitation(connection_t *c, const char *data, uint16_t len) static bool receive_invitation_sptps(void *handle, uint8_t type, const void *data, uint16_t len) { connection_t *c = handle; - if(type == 128) + if(type == 128) { return true; + } - if(type == 1 && c->status.invitation_used) + if(type == 1 && c->status.invitation_used) { return finalize_invitation(c, data, len); + } - if(type != 0 || len != 18 || c->status.invitation_used) + if(type != 0 || len != 18 || c->status.invitation_used) { return false; + } // Recover the filename from the cookie and the key char *fingerprint = ecdsa_get_base64_public_key(invitation_key); @@ -226,15 +251,18 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat // Atomically rename the invitation file if(rename(filename, usedname)) { - if(errno == ENOENT) + if(errno == ENOENT) { logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s tried to use non-existing invitation %s\n", c->hostname, cookie); - else + } else { logger(DEBUG_ALWAYS, LOG_ERR, "Error trying to rename invitation %s\n", cookie); + } + return false; } // Check the timestamp of the invitation struct stat st; + if(stat(usedname, &st)) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not stat %s", usedname); return false; @@ -247,6 +275,7 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat // Open the renamed file FILE *f = fopen(usedname, "r"); + if(!f) { logger(DEBUG_ALWAYS, LOG_ERR, "Error trying to open invitation %s\n", cookie); return false; @@ -255,16 +284,20 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat // Read the new node's Name from the file char buf[1024]; fgets(buf, sizeof(buf), f); - if(*buf) + + if(*buf) { buf[strlen(buf) - 1] = 0; + } len = strcspn(buf, " \t="); char *name = buf + len; name += strspn(name, " \t"); + if(*name == '=') { name++; name += strspn(name, " \t"); } + buf[len] = 0; if(!*buf || !*name || strcasecmp(buf, "Name") || !check_id(name)) { @@ -279,8 +312,11 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat // Send the node the contents of the invitation file rewind(f); size_t result; - while((result = fread(buf, 1, sizeof(buf), f))) + + while((result = fread(buf, 1, sizeof(buf), f))) { sptps_send_record(&c->sptps, 0, buf, result); + } + sptps_send_record(&c->sptps, 1, buf, 0); fclose(f); unlink(usedname); @@ -296,7 +332,7 @@ bool id_h(connection_t *c, const char *request) { if(sscanf(request, "%*d " MAX_STRING " %2d.%3d", name, &c->protocol_major, &c->protocol_minor) < 2) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ID", c->name, - c->hostname); + c->hostname); return false; } @@ -320,6 +356,7 @@ bool id_h(connection_t *c, const char *request) { } c->ecdsa = ecdsa_set_base64_public_key(name + 1); + if(!c->ecdsa) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad invitation from %s", c->hostname); return false; @@ -327,10 +364,15 @@ bool id_h(connection_t *c, const char *request) { c->status.invitation = true; char *mykey = ecdsa_get_base64_public_key(invitation_key); - if(!mykey) + + if(!mykey) { return false; - if(!send_request(c, "%d %s", ACK, mykey)) + } + + if(!send_request(c, "%d %s", ACK, mykey)) { return false; + } + free(mykey); c->protocol_minor = 2; @@ -342,7 +384,7 @@ bool id_h(connection_t *c, const char *request) { if(!check_id(name)) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ID", c->name, - c->hostname, "invalid name"); + c->hostname, "invalid name"); return false; } @@ -351,12 +393,14 @@ bool id_h(connection_t *c, const char *request) { if(c->outgoing) { if(strcmp(c->name, name)) { logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s is %s instead of %s", c->hostname, name, - c->name); + c->name); return false; } } else { - if(c->name) + if(c->name) { free(c->name); + } + c->name = xstrdup(name); } @@ -364,19 +408,22 @@ bool id_h(connection_t *c, const char *request) { if(c->protocol_major != myself->connection->protocol_major) { logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s (%s) uses incompatible version %d.%d", - c->name, c->hostname, c->protocol_major, c->protocol_minor); + c->name, c->hostname, c->protocol_major, c->protocol_minor); return false; } if(bypass_security) { - if(!c->config_tree) + if(!c->config_tree) { init_configuration(&c->config_tree); + } + c->allow_request = ACK; return send_ack(c); } - if(!experimental) + if(!experimental) { c->protocol_minor = 0; + } if(!c->config_tree) { init_configuration(&c->config_tree); @@ -386,19 +433,22 @@ bool id_h(connection_t *c, const char *request) { return false; } - if(experimental) + if(experimental) { read_ecdsa_public_key(c); - /* Ignore failures if no key known yet */ + } + + /* Ignore failures if no key known yet */ } - if(c->protocol_minor && !ecdsa_active(c->ecdsa)) + if(c->protocol_minor && !ecdsa_active(c->ecdsa)) { c->protocol_minor = 1; + } /* Forbid version rollback for nodes whose Ed25519 key we know */ if(ecdsa_active(c->ecdsa) && c->protocol_minor < 1) { logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s (%s) tries to roll back protocol version to %d.%d", - c->name, c->hostname, c->protocol_major, c->protocol_minor); + c->name, c->hostname, c->protocol_major, c->protocol_minor); return false; } @@ -408,10 +458,11 @@ bool id_h(connection_t *c, const char *request) { c->allow_request = ACK; char label[25 + strlen(myself->name) + strlen(c->name)]; - if(c->outgoing) + if(c->outgoing) { snprintf(label, sizeof(label), "tinc TCP key expansion %s %s", myself->name, c->name); - else + } else { snprintf(label, sizeof(label), "tinc TCP key expansion %s %s", c->name, myself->name); + } return sptps_start(&c->sptps, c, c->outgoing, false, myself->connection->ecdsa, c->ecdsa, label, sizeof(label), send_meta_sptps, receive_meta_sptps); } else { @@ -423,13 +474,15 @@ bool send_metakey(connection_t *c) { #ifdef DISABLE_LEGACY return false; #else + if(!myself->connection->rsa) { logger(DEBUG_CONNECTIONS, LOG_ERR, "Peer %s (%s) uses legacy protocol which we don't support", c->name, c->hostname); return false; } - if(!read_rsa_public_key(c)) + if(!read_rsa_public_key(c)) { return false; + } /* We need to use a stream mode for the meta protocol. Use AES for this, but try to match the key size with the one from the cipher selected @@ -437,19 +490,24 @@ bool send_metakey(connection_t *c) { */ int keylen = cipher_keylength(myself->incipher); - if(keylen <= 16) + + if(keylen <= 16) { c->outcipher = cipher_open_by_name("aes-128-cfb"); - else if(keylen <= 24) + } else if(keylen <= 24) { c->outcipher = cipher_open_by_name("aes-192-cfb"); - else + } else { c->outcipher = cipher_open_by_name("aes-256-cfb"); - if(!c) + } + + if(!c) { return false; + } c->outbudget = cipher_budget(c->outcipher); - if(!(c->outdigest = digest_open_by_name("sha256", -1))) + if(!(c->outdigest = digest_open_by_name("sha256", -1))) { return false; + } const size_t len = rsa_size(c->rsa); char key[len]; @@ -472,8 +530,9 @@ bool send_metakey(connection_t *c) { key[0] &= 0x7F; - if(!cipher_set_key_from_rsa(c->outcipher, key, len, true)) + if(!cipher_set_key_from_rsa(c->outcipher, key, len, true)) { return false; + } if(debug_level >= DEBUG_SCARY_THINGS) { bin2hex(key, hexkey, len); @@ -499,9 +558,9 @@ bool send_metakey(connection_t *c) { /* Send the meta key */ bool result = send_request(c, "%d %d %d %d %d %s", METAKEY, - cipher_get_nid(c->outcipher), - digest_get_nid(c->outdigest), c->outmaclength, - c->outcompression, hexkey); + cipher_get_nid(c->outcipher), + digest_get_nid(c->outdigest), c->outmaclength, + c->outcompression, hexkey); c->status.encryptout = true; return result; @@ -512,8 +571,10 @@ bool metakey_h(connection_t *c, const char *request) { #ifdef DISABLE_LEGACY return false; #else - if(!myself->connection->rsa) + + if(!myself->connection->rsa) { return false; + } char hexkey[MAX_STRING_SIZE]; int cipher, digest, maclength, compression; @@ -586,8 +647,9 @@ bool send_challenge(connection_t *c) { const size_t len = rsa_size(c->rsa); char buffer[len * 2 + 1]; - if(!c->hischallenge) + if(!c->hischallenge) { c->hischallenge = xrealloc(c->hischallenge, len); + } /* Copy random data to the buffer */ @@ -607,8 +669,10 @@ bool challenge_h(connection_t *c, const char *request) { #ifdef DISABLE_LEGACY return false; #else - if(!myself->connection->rsa) + + if(!myself->connection->rsa) { return false; + } char buffer[MAX_STRING_SIZE]; const size_t len = rsa_size(myself->connection->rsa); @@ -633,8 +697,9 @@ bool challenge_h(connection_t *c, const char *request) { /* Calculate the hash from the challenge we received */ - if(!digest_create(c->indigest, buffer, len, digest)) + if(!digest_create(c->indigest, buffer, len, digest)) { return false; + } /* Convert the hash to a hexadecimal formatted string */ @@ -656,7 +721,7 @@ bool chal_reply_h(connection_t *c, const char *request) { if(sscanf(request, "%*d " MAX_STRING, hishash) != 1) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "CHAL_REPLY", c->name, - c->hostname); + c->hostname); return false; } @@ -700,8 +765,9 @@ static bool send_upgrade(connection_t *c) { char *pubkey = ecdsa_get_base64_public_key(myself->connection->ecdsa); - if(!pubkey) + if(!pubkey) { return false; + } bool result = send_request(c, "%d %s", ACK, pubkey); free(pubkey); @@ -710,8 +776,9 @@ static bool send_upgrade(connection_t *c) { } bool send_ack(connection_t *c) { - if(c->protocol_minor == 1) + if(c->protocol_minor == 1) { return send_upgrade(c); + } /* ACK message contains rest of the information the other end needs to create node_t and edge_t structures. */ @@ -726,22 +793,28 @@ bool send_ack(connection_t *c) { /* Check some options */ - if((get_config_bool(lookup_config(c->config_tree, "IndirectData"), &choice) && choice) || myself->options & OPTION_INDIRECT) + if((get_config_bool(lookup_config(c->config_tree, "IndirectData"), &choice) && choice) || myself->options & OPTION_INDIRECT) { c->options |= OPTION_INDIRECT; + } - if((get_config_bool(lookup_config(c->config_tree, "TCPOnly"), &choice) && choice) || myself->options & OPTION_TCPONLY) + if((get_config_bool(lookup_config(c->config_tree, "TCPOnly"), &choice) && choice) || myself->options & OPTION_TCPONLY) { c->options |= OPTION_TCPONLY | OPTION_INDIRECT; + } - if(myself->options & OPTION_PMTU_DISCOVERY) + if(myself->options & OPTION_PMTU_DISCOVERY) { c->options |= OPTION_PMTU_DISCOVERY; + } choice = myself->options & OPTION_CLAMP_MSS; get_config_bool(lookup_config(c->config_tree, "ClampMSS"), &choice); - if(choice) + + if(choice) { c->options |= OPTION_CLAMP_MSS; + } - if(!get_config_int(lookup_config(c->config_tree, "Weight"), &c->estimated_weight)) + if(!get_config_int(lookup_config(c->config_tree, "Weight"), &c->estimated_weight)) { get_config_int(lookup_config(config_tree, "Weight"), &c->estimated_weight); + } return send_request(c, "%d %s %d %x", ACK, myport, c->estimated_weight, (c->options & 0xffffff) | (experimental ? (PROT_MINOR << 24) : 0)); } @@ -761,18 +834,21 @@ static void send_everything(connection_t *c) { } if(tunnelserver) { - for splay_each(subnet_t, s, myself->subnet_tree) + for splay_each(subnet_t, s, myself->subnet_tree) { send_add_subnet(c, s); + } return; } for splay_each(node_t, n, node_tree) { - for splay_each(subnet_t, s, n->subnet_tree) + for splay_each(subnet_t, s, n->subnet_tree) { send_add_subnet(c, s); + } - for splay_each(edge_t, e, n->edge_tree) + for splay_each(edge_t, e, n->edge_tree) { send_add_edge(c, e); + } } } @@ -788,16 +864,19 @@ static bool upgrade_h(connection_t *c, const char *request) { char *knownkey = ecdsa_get_base64_public_key(c->ecdsa); bool different = strcmp(knownkey, pubkey); free(knownkey); + if(different) { logger(DEBUG_ALWAYS, LOG_ERR, "Already have an Ed25519 public key from %s (%s) which is different from the one presented now!", c->name, c->hostname); return false; } + logger(DEBUG_ALWAYS, LOG_INFO, "Already have Ed25519 public key from %s (%s), ignoring.", c->name, c->hostname); c->allow_request = TERMREQ; return send_termreq(c); } c->ecdsa = ecdsa_set_base64_public_key(pubkey); + if(!c->ecdsa) { logger(DEBUG_ALWAYS, LOG_INFO, "Got bad Ed25519 public key from %s (%s), not upgrading.", c->name, c->hostname); return false; @@ -806,14 +885,18 @@ static bool upgrade_h(connection_t *c, const char *request) { logger(DEBUG_ALWAYS, LOG_INFO, "Got Ed25519 public key from %s (%s), upgrading!", c->name, c->hostname); append_config_file(c->name, "Ed25519PublicKey", pubkey); c->allow_request = TERMREQ; - if(c->outgoing) + + if(c->outgoing) { c->outgoing->timeout = 0; + } + return send_termreq(c); } bool ack_h(connection_t *c, const char *request) { - if(c->protocol_minor == 1) + if(c->protocol_minor == 1) { return upgrade_h(c, request); + } char hisport[MAX_STRING_SIZE]; int weight, mtu; @@ -823,7 +906,7 @@ bool ack_h(connection_t *c, const char *request) { if(sscanf(request, "%*d " MAX_STRING " %d %x", hisport, &weight, &options) != 3) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ACK", c->name, - c->hostname); + c->hostname); return false; } @@ -841,10 +924,11 @@ bool ack_h(connection_t *c, const char *request) { logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Established a second connection with %s (%s), closing old connection", n->connection->name, n->connection->hostname); if(n->connection->outgoing) { - if(c->outgoing) + if(c->outgoing) { logger(DEBUG_ALWAYS, LOG_WARNING, "Two outgoing connections to the same node!"); - else + } else { c->outgoing = n->connection->outgoing; + } n->connection->outgoing = NULL; } @@ -857,23 +941,28 @@ bool ack_h(connection_t *c, const char *request) { n->connection = c; c->node = n; + if(!(c->options & options & OPTION_PMTU_DISCOVERY)) { c->options &= ~OPTION_PMTU_DISCOVERY; options &= ~OPTION_PMTU_DISCOVERY; } + c->options |= options; - if(get_config_int(lookup_config(c->config_tree, "PMTU"), &mtu) && mtu < n->mtu) + if(get_config_int(lookup_config(c->config_tree, "PMTU"), &mtu) && mtu < n->mtu) { n->mtu = mtu; + } - if(get_config_int(lookup_config(config_tree, "PMTU"), &mtu) && mtu < n->mtu) + if(get_config_int(lookup_config(config_tree, "PMTU"), &mtu) && mtu < n->mtu) { n->mtu = mtu; + } if(get_config_bool(lookup_config(c->config_tree, "ClampMSS"), &choice)) { - if(choice) + if(choice) { c->options |= OPTION_CLAMP_MSS; - else + } else { c->options &= ~OPTION_CLAMP_MSS; + } } /* Activate this connection */ @@ -881,7 +970,7 @@ bool ack_h(connection_t *c, const char *request) { c->allow_request = ALL; logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection with %s (%s) activated", c->name, - c->hostname); + c->hostname); /* Send him everything we know */ @@ -896,12 +985,14 @@ bool ack_h(connection_t *c, const char *request) { sockaddr_setport(&c->edge->address, hisport); sockaddr_t local_sa; socklen_t local_salen = sizeof(local_sa); - if (getsockname(c->socket, &local_sa.sa, &local_salen) < 0) + + if(getsockname(c->socket, &local_sa.sa, &local_salen) < 0) { logger(DEBUG_ALWAYS, LOG_WARNING, "Could not get local socket address for connection with %s", c->name); - else { + } else { sockaddr_setport(&local_sa, myport); c->edge->local_address = local_sa; } + c->edge->weight = (weight + c->estimated_weight) / 2; c->edge->connection = c; c->edge->options = c->options; @@ -910,10 +1001,11 @@ bool ack_h(connection_t *c, const char *request) { /* Notify everyone of the new edge */ - if(tunnelserver) + if(tunnelserver) { send_add_edge(c, c->edge); - else + } else { send_add_edge(everyone, c->edge); + } /* Run MST and SSSP algorithms */ diff --git a/src/protocol_edge.c b/src/protocol_edge.c index 92089b1..18b6bef 100644 --- a/src/protocol_edge.c +++ b/src/protocol_edge.c @@ -45,14 +45,14 @@ bool send_add_edge(connection_t *c, const edge_t *e) { sockaddr2str(&e->local_address, &local_address, &local_port); x = send_request(c, "%d %x %s %s %s %s %x %d %s %s", ADD_EDGE, rand(), - e->from->name, e->to->name, address, port, - e->options, e->weight, local_address, local_port); + e->from->name, e->to->name, address, port, + e->options, e->weight, local_address, local_port); free(local_address); free(local_port); } else { x = send_request(c, "%d %x %s %s %s %s %x %d", ADD_EDGE, rand(), - e->from->name, e->to->name, address, port, - e->options, e->weight); + e->from->name, e->to->name, address, port, + e->options, e->weight); } free(address); @@ -75,10 +75,11 @@ bool add_edge_h(connection_t *c, const char *request) { int weight; int parameter_count = sscanf(request, "%*d %*x "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" %x %d "MAX_STRING" "MAX_STRING, - from_name, to_name, to_address, to_port, &options, &weight, address_local, port_local); - if (parameter_count != 6 && parameter_count != 8) { + from_name, to_name, to_address, to_port, &options, &weight, address_local, port_local); + + if(parameter_count != 6 && parameter_count != 8) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ADD_EDGE", c->name, - c->hostname); + c->hostname); return false; } @@ -86,12 +87,13 @@ bool add_edge_h(connection_t *c, const char *request) { if(!check_id(from_name) || !check_id(to_name)) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ADD_EDGE", c->name, - c->hostname, "invalid name"); + c->hostname, "invalid name"); return false; } - if(seen_request(request)) + if(seen_request(request)) { return true; + } /* Lookup nodes */ @@ -99,12 +101,12 @@ bool add_edge_h(connection_t *c, const char *request) { to = lookup_node(to_name); if(tunnelserver && - from != myself && from != c->node && - to != myself && to != c->node) { + from != myself && from != c->node && + to != myself && to != c->node) { /* ignore indirect edge registrations for tunnelserver */ logger(DEBUG_PROTOCOL, LOG_WARNING, - "Ignoring indirect %s from %s (%s)", - "ADD_EDGE", c->name, c->hostname); + "Ignoring indirect %s from %s (%s)", + "ADD_EDGE", c->name, c->hostname); return true; } @@ -124,8 +126,10 @@ bool add_edge_h(connection_t *c, const char *request) { /* Convert addresses */ address = str2sockaddr(to_address, to_port); - if(parameter_count >= 8) + + if(parameter_count >= 8) { local_address = str2sockaddr(address_local, port_local); + } /* Check if edge already exists */ @@ -137,7 +141,7 @@ bool add_edge_h(connection_t *c, const char *request) { // local_address.sa.sa_family will be 255 (AF_UNKNOWN) if we got it from newer versions // but for edge which does not have local_address bool new_local_address = local_address.sa.sa_family && local_address.sa.sa_family != AF_UNKNOWN && - sockaddrcmp(&e->local_address, &local_address); + sockaddrcmp(&e->local_address, &local_address); if(e->weight == weight && e->options == options && !new_address && !new_local_address) { sockaddrfree(&address); @@ -147,7 +151,7 @@ bool add_edge_h(connection_t *c, const char *request) { if(from == myself) { logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself which does not match existing entry", - "ADD_EDGE", c->name, c->hostname); + "ADD_EDGE", c->name, c->hostname); send_add_edge(c, e); sockaddrfree(&address); sockaddrfree(&local_address); @@ -155,7 +159,7 @@ bool add_edge_h(connection_t *c, const char *request) { } logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) which does not match existing entry", - "ADD_EDGE", c->name, c->hostname); + "ADD_EDGE", c->name, c->hostname); e->options = options; @@ -180,7 +184,7 @@ bool add_edge_h(connection_t *c, const char *request) { } } else if(from == myself) { logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself which does not exist", - "ADD_EDGE", c->name, c->hostname); + "ADD_EDGE", c->name, c->hostname); contradicting_add_edge++; e = new_edge(); e->from = from; @@ -203,8 +207,9 @@ bool add_edge_h(connection_t *c, const char *request) { /* Tell the rest about the new edge */ - if(!tunnelserver) + if(!tunnelserver) { forward_request(c, request); + } /* Run MST before or after we tell the rest? */ @@ -215,7 +220,7 @@ bool add_edge_h(connection_t *c, const char *request) { bool send_del_edge(connection_t *c, const edge_t *e) { return send_request(c, "%d %x %s %s", DEL_EDGE, rand(), - e->from->name, e->to->name); + e->from->name, e->to->name); } bool del_edge_h(connection_t *c, const char *request) { @@ -226,7 +231,7 @@ bool del_edge_h(connection_t *c, const char *request) { if(sscanf(request, "%*d %*x "MAX_STRING" "MAX_STRING, from_name, to_name) != 2) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "DEL_EDGE", c->name, - c->hostname); + c->hostname); return false; } @@ -234,12 +239,13 @@ bool del_edge_h(connection_t *c, const char *request) { if(!check_id(from_name) || !check_id(to_name)) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "DEL_EDGE", c->name, - c->hostname, "invalid name"); + c->hostname, "invalid name"); return false; } - if(seen_request(request)) + if(seen_request(request)) { return true; + } /* Lookup nodes */ @@ -247,24 +253,24 @@ bool del_edge_h(connection_t *c, const char *request) { to = lookup_node(to_name); if(tunnelserver && - from != myself && from != c->node && - to != myself && to != c->node) { + from != myself && from != c->node && + to != myself && to != c->node) { /* ignore indirect edge registrations for tunnelserver */ logger(DEBUG_PROTOCOL, LOG_WARNING, - "Ignoring indirect %s from %s (%s)", - "DEL_EDGE", c->name, c->hostname); + "Ignoring indirect %s from %s (%s)", + "DEL_EDGE", c->name, c->hostname); return true; } if(!from) { logger(DEBUG_PROTOCOL, LOG_ERR, "Got %s from %s (%s) which does not appear in the edge tree", - "DEL_EDGE", c->name, c->hostname); + "DEL_EDGE", c->name, c->hostname); return true; } if(!to) { logger(DEBUG_PROTOCOL, LOG_ERR, "Got %s from %s (%s) which does not appear in the edge tree", - "DEL_EDGE", c->name, c->hostname); + "DEL_EDGE", c->name, c->hostname); return true; } @@ -274,13 +280,13 @@ bool del_edge_h(connection_t *c, const char *request) { if(!e) { logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) which does not appear in the edge tree", - "DEL_EDGE", c->name, c->hostname); + "DEL_EDGE", c->name, c->hostname); return true; } if(e->from == myself) { logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself", - "DEL_EDGE", c->name, c->hostname); + "DEL_EDGE", c->name, c->hostname); contradicting_del_edge++; send_add_edge(c, e); /* Send back a correction */ return true; @@ -288,8 +294,9 @@ bool del_edge_h(connection_t *c, const char *request) { /* Tell the rest about the deleted edge */ - if(!tunnelserver) + if(!tunnelserver) { forward_request(c, request); + } /* Delete the edge */ @@ -303,9 +310,12 @@ bool del_edge_h(connection_t *c, const char *request) { if(!to->status.reachable) { e = lookup_edge(to, myself); + if(e) { - if(!tunnelserver) + if(!tunnelserver) { send_del_edge(everyone, e); + } + edge_del(e); } } diff --git a/src/protocol_key.c b/src/protocol_key.c index 6e31b5e..a7de07e 100644 --- a/src/protocol_key.c +++ b/src/protocol_key.c @@ -42,16 +42,19 @@ void send_key_changed(void) { /* Immediately send new keys to directly connected nodes to keep UDP mappings alive */ for list_each(connection_t, c, connection_list) - if(c->edge && c->node && c->node->status.reachable && !c->node->status.sptps) + if(c->edge && c->node && c->node->status.reachable && !c->node->status.sptps) { send_ans_key(c->node); + } + #endif /* Force key exchange for connections using SPTPS */ if(experimental) { for splay_each(node_t, n, node_tree) - if(n->status.reachable && n->status.validkey && n->status.sptps) + if(n->status.reachable && n->status.validkey && n->status.sptps) { sptps_force_kex(&n->sptps); + } } } @@ -61,18 +64,19 @@ bool key_changed_h(connection_t *c, const char *request) { if(sscanf(request, "%*d %*x " MAX_STRING, name) != 1) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "KEY_CHANGED", - c->name, c->hostname); + c->name, c->hostname); return false; } - if(seen_request(request)) + if(seen_request(request)) { return true; + } n = lookup_node(name); if(!n) { logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist", - "KEY_CHANGED", c->name, c->hostname, name); + "KEY_CHANGED", c->name, c->hostname, name); return true; } @@ -83,8 +87,9 @@ bool key_changed_h(connection_t *c, const char *request) { /* Tell the others */ - if(!tunnelserver) + if(!tunnelserver) { forward_request(c, request); + } return true; } @@ -128,14 +133,16 @@ static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, no /* If this is a SPTPS packet, see if sending UDP info helps. Note that we only do this if we're the destination or the static relay; otherwise every hop would initiate its own UDP info message, resulting in elevated chatter. */ - if((reqno == REQ_KEY || reqno == SPTPS_PACKET) && to->via == myself) + if((reqno == REQ_KEY || reqno == SPTPS_PACKET) && to->via == myself) { send_udp_info(myself, from); + } if(reqno == SPTPS_PACKET) { /* This is a SPTPS data packet. */ char buf[MAX_STRING_SIZE]; int len; + if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s) to %s (%s): %s", "SPTPS_PACKET", from->name, from->hostname, to->name, to->hostname, "invalid SPTPS data"); return true; @@ -155,8 +162,10 @@ static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, no logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname); send_req_key(from); } + return true; } + send_mtu_info(myself, from, MTU); } @@ -165,74 +174,78 @@ static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, no /* Requests that are not SPTPS data packets are forwarded as-is. */ - if (to != myself) + if(to != myself) { return send_request(to->nexthop->connection, "%s", request); + } /* The request is for us */ switch(reqno) { - case REQ_PUBKEY: { - if(!node_read_ecdsa_public_key(from)) { - /* Request their key *before* we send our key back. Otherwise the first SPTPS packet from them will get dropped. */ - logger(DEBUG_PROTOCOL, LOG_DEBUG, "Preemptively requesting Ed25519 key for %s (%s)", from->name, from->hostname); - send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY); - } - char *pubkey = ecdsa_get_base64_public_key(myself->connection->ecdsa); - send_request(from->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, from->name, ANS_PUBKEY, pubkey); - free(pubkey); - return true; + case REQ_PUBKEY: { + if(!node_read_ecdsa_public_key(from)) { + /* Request their key *before* we send our key back. Otherwise the first SPTPS packet from them will get dropped. */ + logger(DEBUG_PROTOCOL, LOG_DEBUG, "Preemptively requesting Ed25519 key for %s (%s)", from->name, from->hostname); + send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY); } - case ANS_PUBKEY: { - if(node_read_ecdsa_public_key(from)) { - logger(DEBUG_PROTOCOL, LOG_WARNING, "Got ANS_PUBKEY from %s (%s) even though we already have his pubkey", from->name, from->hostname); - return true; - } + char *pubkey = ecdsa_get_base64_public_key(myself->connection->ecdsa); + send_request(from->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, from->name, ANS_PUBKEY, pubkey); + free(pubkey); + return true; + } - char pubkey[MAX_STRING_SIZE]; - if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, pubkey) != 1 || !(from->ecdsa = ecdsa_set_base64_public_key(pubkey))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_PUBKEY", from->name, from->hostname, "invalid pubkey"); - return true; - } + case ANS_PUBKEY: { + if(node_read_ecdsa_public_key(from)) { + logger(DEBUG_PROTOCOL, LOG_WARNING, "Got ANS_PUBKEY from %s (%s) even though we already have his pubkey", from->name, from->hostname); + return true; + } + + char pubkey[MAX_STRING_SIZE]; - logger(DEBUG_PROTOCOL, LOG_INFO, "Learned Ed25519 public key from %s (%s)", from->name, from->hostname); - append_config_file(from->name, "Ed25519PublicKey", pubkey); + if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, pubkey) != 1 || !(from->ecdsa = ecdsa_set_base64_public_key(pubkey))) { + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_PUBKEY", from->name, from->hostname, "invalid pubkey"); return true; } - case REQ_KEY: { - if(!node_read_ecdsa_public_key(from)) { - logger(DEBUG_PROTOCOL, LOG_DEBUG, "No Ed25519 key known for %s (%s)", from->name, from->hostname); - send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY); - return true; - } + logger(DEBUG_PROTOCOL, LOG_INFO, "Learned Ed25519 public key from %s (%s)", from->name, from->hostname); + append_config_file(from->name, "Ed25519PublicKey", pubkey); + return true; + } - if(from->sptps.label) - logger(DEBUG_ALWAYS, LOG_DEBUG, "Got REQ_KEY from %s while we already started a SPTPS session!", from->name); + case REQ_KEY: { + if(!node_read_ecdsa_public_key(from)) { + logger(DEBUG_PROTOCOL, LOG_DEBUG, "No Ed25519 key known for %s (%s)", from->name, from->hostname); + send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY); + return true; + } - char buf[MAX_STRING_SIZE]; - int len; + if(from->sptps.label) { + logger(DEBUG_ALWAYS, LOG_DEBUG, "Got REQ_KEY from %s while we already started a SPTPS session!", from->name); + } - if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_SPTPS_START", from->name, from->hostname, "invalid SPTPS data"); - return true; - } + char buf[MAX_STRING_SIZE]; + int len; - char label[25 + strlen(from->name) + strlen(myself->name)]; - snprintf(label, sizeof(label), "tinc UDP key expansion %s %s", from->name, myself->name); - sptps_stop(&from->sptps); - from->status.validkey = false; - from->status.waitingforkey = true; - from->last_req_key = now.tv_sec; - sptps_start(&from->sptps, from, false, true, myself->connection->ecdsa, from->ecdsa, label, sizeof(label), send_sptps_data_myself, receive_sptps_record); - sptps_receive_data(&from->sptps, buf, len); - send_mtu_info(myself, from, MTU); + if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) { + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_SPTPS_START", from->name, from->hostname, "invalid SPTPS data"); return true; } - default: - logger(DEBUG_ALWAYS, LOG_ERR, "Unknown extended REQ_KEY request from %s (%s): %s", from->name, from->hostname, request); - return true; + char label[25 + strlen(from->name) + strlen(myself->name)]; + snprintf(label, sizeof(label), "tinc UDP key expansion %s %s", from->name, myself->name); + sptps_stop(&from->sptps); + from->status.validkey = false; + from->status.waitingforkey = true; + from->last_req_key = now.tv_sec; + sptps_start(&from->sptps, from, false, true, myself->connection->ecdsa, from->ecdsa, label, sizeof(label), send_sptps_data_myself, receive_sptps_record); + sptps_receive_data(&from->sptps, buf, len); + send_mtu_info(myself, from, MTU); + return true; + } + + default: + logger(DEBUG_ALWAYS, LOG_ERR, "Unknown extended REQ_KEY request from %s (%s): %s", from->name, from->hostname, request); + return true; } } @@ -244,7 +257,7 @@ bool req_key_h(connection_t *c, const char *request) { if(sscanf(request, "%*d " MAX_STRING " " MAX_STRING " %d", from_name, to_name, &reqno) < 2) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "REQ_KEY", c->name, - c->hostname); + c->hostname); return false; } @@ -257,7 +270,7 @@ bool req_key_h(connection_t *c, const char *request) { if(!from) { logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list", - "REQ_KEY", c->name, c->hostname, from_name); + "REQ_KEY", c->name, c->hostname, from_name); return true; } @@ -265,7 +278,7 @@ bool req_key_h(connection_t *c, const char *request) { if(!to) { logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list", - "REQ_KEY", c->name, c->hostname, to_name); + "REQ_KEY", c->name, c->hostname, to_name); return true; } @@ -273,24 +286,27 @@ bool req_key_h(connection_t *c, const char *request) { if(to == myself) { /* Yes */ /* Is this an extended REQ_KEY message? */ - if(experimental && reqno) + if(experimental && reqno) { return req_key_ext_h(c, request, from, to, reqno); + } /* No, just send our key back */ send_ans_key(from); } else { - if(tunnelserver) + if(tunnelserver) { return true; + } if(!to->status.reachable) { logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable", - "REQ_KEY", c->name, c->hostname, to_name); + "REQ_KEY", c->name, c->hostname, to_name); return true; } /* Is this an extended REQ_KEY message? */ - if(experimental && reqno) + if(experimental && reqno) { return req_key_ext_h(c, request, from, to, reqno); + } send_request(to->nexthop->connection, "%s", request); } @@ -299,8 +315,9 @@ bool req_key_h(connection_t *c, const char *request) { } bool send_ans_key(node_t *to) { - if(to->status.sptps) + if(to->status.sptps) { abort(); + } #ifdef DISABLE_LEGACY return false; @@ -315,18 +332,26 @@ bool send_ans_key(node_t *to) { if(myself->incipher) { to->incipher = cipher_open_by_nid(cipher_get_nid(myself->incipher)); - if(!to->incipher) + + if(!to->incipher) { abort(); - if(!cipher_set_key(to->incipher, key, false)) + } + + if(!cipher_set_key(to->incipher, key, false)) { abort(); + } } if(myself->indigest) { to->indigest = digest_open_by_nid(digest_get_nid(myself->indigest), digest_length(myself->indigest)); - if(!to->indigest) + + if(!to->indigest) { abort(); - if(!digest_set_key(to->indigest, key, keylen)) + } + + if(!digest_set_key(to->indigest, key, keylen)) { abort(); + } } to->incompression = myself->incompression; @@ -337,16 +362,19 @@ bool send_ans_key(node_t *to) { mykeyused = true; to->received_seqno = 0; to->received = 0; - if(replaywin) memset(to->late, 0, replaywin); + + if(replaywin) { + memset(to->late, 0, replaywin); + } to->status.validkey_in = true; return send_request(to->nexthop->connection, "%d %s %s %s %d %d %d %d", ANS_KEY, - myself->name, to->name, key, - cipher_get_nid(to->incipher), - digest_get_nid(to->indigest), - (int)digest_length(to->indigest), - to->incompression); + myself->name, to->name, key, + cipher_get_nid(to->incipher), + digest_get_nid(to->indigest), + (int)digest_length(to->indigest), + to->incompression); #endif } @@ -360,10 +388,10 @@ bool ans_key_h(connection_t *c, const char *request) { node_t *from, *to; if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %d "MAX_STRING" "MAX_STRING, - from_name, to_name, key, &cipher, &digest, &maclength, - &compression, address, port) < 7) { + from_name, to_name, key, &cipher, &digest, &maclength, + &compression, address, port) < 7) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ANS_KEY", c->name, - c->hostname); + c->hostname); return false; } @@ -376,7 +404,7 @@ bool ans_key_h(connection_t *c, const char *request) { if(!from) { logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list", - "ANS_KEY", c->name, c->hostname, from_name); + "ANS_KEY", c->name, c->hostname, from_name); return true; } @@ -384,19 +412,20 @@ bool ans_key_h(connection_t *c, const char *request) { if(!to) { logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list", - "ANS_KEY", c->name, c->hostname, to_name); + "ANS_KEY", c->name, c->hostname, to_name); return true; } /* Forward it if necessary */ if(to != myself) { - if(tunnelserver) + if(tunnelserver) { return true; + } if(!to->status.reachable) { logger(DEBUG_ALWAYS, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable", - "ANS_KEY", c->name, c->hostname, to_name); + "ANS_KEY", c->name, c->hostname, to_name); return true; } @@ -418,7 +447,10 @@ bool ans_key_h(connection_t *c, const char *request) { cipher_close(from->outcipher); digest_close(from->outdigest); #endif - if (!from->status.sptps) from->status.validkey = false; + + if(!from->status.sptps) { + from->status.validkey = false; + } if(compression < 0 || compression > 11) { logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname); @@ -432,6 +464,7 @@ bool ans_key_h(connection_t *c, const char *request) { if(from->status.sptps) { char buf[strlen(key)]; int len = b64decode(key, buf, strlen(key)); + if(!len || !sptps_receive_data(&from->sptps, buf, len)) { /* Uh-oh. It might be that the tunnel is stuck in some corrupted state, so let's restart SPTPS in case that helps. But don't do that too often @@ -442,6 +475,7 @@ bool ans_key_h(connection_t *c, const char *request) { logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode handshake TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname); send_req_key(from); } + return true; } @@ -498,10 +532,13 @@ bool ans_key_h(connection_t *c, const char *request) { /* Update our copy of the origin's packet key */ - if(from->outcipher && !cipher_set_key(from->outcipher, key, true)) + if(from->outcipher && !cipher_set_key(from->outcipher, key, true)) { return false; - if(from->outdigest && !digest_set_key(from->outdigest, key, keylen)) + } + + if(from->outdigest && !digest_set_key(from->outdigest, key, keylen)) { return false; + } from->status.validkey = true; from->sent_seqno = 0; diff --git a/src/protocol_misc.c b/src/protocol_misc.c index 05a4ada..a8b30ff 100644 --- a/src/protocol_misc.c +++ b/src/protocol_misc.c @@ -41,8 +41,9 @@ int udp_info_interval = 5; /* Status and error notification routines */ bool send_status(connection_t *c, int statusno, const char *statusstring) { - if(!statusstring) + if(!statusstring) { statusstring = "Status"; + } return send_request(c, "%d %d %s", STATUS, statusno, statusstring); } @@ -53,19 +54,20 @@ bool status_h(connection_t *c, const char *request) { if(sscanf(request, "%*d %d " MAX_STRING, &statusno, statusstring) != 2) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "STATUS", - c->name, c->hostname); + c->name, c->hostname); return false; } logger(DEBUG_STATUS, LOG_NOTICE, "Status message from %s (%s): %d: %s", - c->name, c->hostname, statusno, statusstring); + c->name, c->hostname, statusno, statusstring); return true; } bool send_error(connection_t *c, int err, const char *errstring) { - if(!errstring) + if(!errstring) { errstring = "Error"; + } return send_request(c, "%d %d %s", ERROR, err, errstring); } @@ -76,12 +78,12 @@ bool error_h(connection_t *c, const char *request) { if(sscanf(request, "%*d %d " MAX_STRING, &err, errorstring) != 2) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ERROR", - c->name, c->hostname); + c->name, c->hostname); return false; } logger(DEBUG_ERROR, LOG_NOTICE, "Error message from %s (%s): %d: %s", - c->name, c->hostname, err, errorstring); + c->name, c->hostname, err, errorstring); return false; } @@ -117,8 +119,11 @@ bool pong_h(connection_t *c, const char *request) { if(c->outgoing) { c->outgoing->timeout = 0; c->outgoing->cfg = NULL; - if(c->outgoing->ai) + + if(c->outgoing->ai) { freeaddrinfo(c->outgoing->ai); + } + c->outgoing->ai = NULL; c->outgoing->aip = NULL; } @@ -132,11 +137,13 @@ bool send_tcppacket(connection_t *c, const vpn_packet_t *packet) { /* If there already is a lot of data in the outbuf buffer, discard this packet. We use a very simple Random Early Drop algorithm. */ - if(2.0 * c->outbuf.len / (float)maxoutbufsize - 1 > (float)rand()/(float)RAND_MAX) + if(2.0 * c->outbuf.len / (float)maxoutbufsize - 1 > (float)rand() / (float)RAND_MAX) { return true; + } - if(!send_request(c, "%d %d", PACKET, packet->len)) + if(!send_request(c, "%d %d", PACKET, packet->len)) { return false; + } return send_meta(c, (char *)DATA(packet), packet->len); } @@ -146,7 +153,7 @@ bool tcppacket_h(connection_t *c, const char *request) { if(sscanf(request, "%*d %hd", &len) != 1) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "PACKET", c->name, - c->hostname); + c->hostname); return false; } @@ -157,26 +164,28 @@ bool tcppacket_h(connection_t *c, const char *request) { return true; } -bool send_sptps_tcppacket(connection_t *c, const char* packet, int len) { +bool send_sptps_tcppacket(connection_t *c, const char *packet, int len) { /* If there already is a lot of data in the outbuf buffer, discard this packet. We use a very simple Random Early Drop algorithm. */ - if(2.0 * c->outbuf.len / (float)maxoutbufsize - 1 > (float)rand()/(float)RAND_MAX) + if(2.0 * c->outbuf.len / (float)maxoutbufsize - 1 > (float)rand() / (float)RAND_MAX) { return true; + } - if(!send_request(c, "%d %d", SPTPS_PACKET, len)) + if(!send_request(c, "%d %d", SPTPS_PACKET, len)) { return false; + } send_meta_raw(c, packet, len); return true; } -bool sptps_tcppacket_h(connection_t *c, const char* request) { +bool sptps_tcppacket_h(connection_t *c, const char *request) { short int len; if(sscanf(request, "%*d %hd", &len) != 1) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "SPTPS_PACKET", c->name, - c->hostname); + c->hostname); return false; } @@ -194,7 +203,7 @@ bool send_udp_info(node_t *from, node_t *to) { farther than the static relay. */ to = (to->via == myself) ? to->nexthop : to->via; - if (to == NULL) { + if(to == NULL) { logger(DEBUG_ALWAYS, LOG_ERR, "Something went wrong when selecting relay - possible fake UDP_INFO"); return false; } @@ -202,27 +211,35 @@ bool send_udp_info(node_t *from, node_t *to) { /* Skip cases where sending UDP info messages doesn't make sense. This is done here in order to avoid repeating the same logic in multiple callsites. */ - if(to == myself) + if(to == myself) { return true; + } - if(!to->status.reachable) + if(!to->status.reachable) { return true; + } if(from == myself) { - if(to->connection) + if(to->connection) { return true; + } struct timeval elapsed; + timersub(&now, &to->udp_info_sent, &elapsed); - if(elapsed.tv_sec < udp_info_interval) + + if(elapsed.tv_sec < udp_info_interval) { return true; + } } - if((myself->options | from->options | to->options) & OPTION_TCPONLY) + if((myself->options | from->options | to->options) & OPTION_TCPONLY) { return true; + } - if((to->nexthop->options >> 24) < 5) + if((to->nexthop->options >> 24) < 5) { return true; + } char *from_address, *from_port; /* If we're the originator, the address we use is irrelevant @@ -236,13 +253,14 @@ bool send_udp_info(node_t *from, node_t *to) { free(from_address); free(from_port); - if(from == myself) + if(from == myself) { to->udp_info_sent = now; + } return x; } -bool udp_info_h(connection_t *c, const char* request) { +bool udp_info_h(connection_t *c, const char *request) { char from_name[MAX_STRING_SIZE]; char to_name[MAX_STRING_SIZE]; char from_address[MAX_STRING_SIZE]; @@ -259,6 +277,7 @@ bool udp_info_h(connection_t *c, const char* request) { } node_t *from = lookup_node(from_name); + if(!from) { logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list", "UDP_INFO", c->name, c->hostname, from_name); return true; @@ -274,11 +293,14 @@ bool udp_info_h(connection_t *c, const char* request) { to guess its address than it is itself. */ if(!from->connection && !from->status.udp_confirmed) { sockaddr_t from_addr = str2sockaddr(from_address, from_port); - if(sockaddrcmp(&from_addr, &from->address)) + + if(sockaddrcmp(&from_addr, &from->address)) { update_node_udp(from, &from_addr); + } } node_t *to = lookup_node(to_name); + if(!to) { logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list", "UDP_INFO", c->name, c->hostname, to_name); return true; @@ -295,28 +317,36 @@ bool send_mtu_info(node_t *from, node_t *to, int mtu) { /* Skip cases where sending MTU info messages doesn't make sense. This is done here in order to avoid repeating the same logic in multiple callsites. */ - if(to == myself) + if(to == myself) { return true; + } - if(!to->status.reachable) + if(!to->status.reachable) { return true; + } if(from == myself) { - if(to->connection) + if(to->connection) { return true; + } struct timeval elapsed; + timersub(&now, &to->mtu_info_sent, &elapsed); - if(elapsed.tv_sec < mtu_info_interval) + + if(elapsed.tv_sec < mtu_info_interval) { return true; + } } - if((to->nexthop->options >> 24) < 6) + if((to->nexthop->options >> 24) < 6) { return true; + } /* We will send the passed-in MTU value, unless we believe ours is better. */ node_t *via = (from->via == myself) ? from->nexthop : from->via; + if(from->minmtu == from->maxmtu && from->via == myself) { /* We have a direct measurement. Override the value entirely. Note that we only do that if we are sitting as a static relay in the path; @@ -331,8 +361,9 @@ bool send_mtu_info(node_t *from, node_t *to, int mtu) { mtu = MIN(mtu, via->nexthop->minmtu); } - if(from == myself) + if(from == myself) { to->mtu_info_sent = now; + } /* If none of the conditions above match in the steady state, it means we're using TCP, so the MTU is irrelevant. That said, it is still important to honor the MTU that was passed in, @@ -341,7 +372,7 @@ bool send_mtu_info(node_t *from, node_t *to, int mtu) { return send_request(to->nexthop->connection, "%d %s %s %d", MTU_INFO, from->name, to->name, mtu); } -bool mtu_info_h(connection_t *c, const char* request) { +bool mtu_info_h(connection_t *c, const char *request) { char from_name[MAX_STRING_SIZE]; char to_name[MAX_STRING_SIZE]; int mtu; @@ -364,6 +395,7 @@ bool mtu_info_h(connection_t *c, const char* request) { } node_t *from = lookup_node(from_name); + if(!from) { logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list", "MTU_INFO", c->name, c->hostname, from_name); return true; @@ -378,6 +410,7 @@ bool mtu_info_h(connection_t *c, const char* request) { } node_t *to = lookup_node(to_name); + if(!to) { logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list", "MTU_INFO", c->name, c->hostname, to_name); return true; diff --git a/src/protocol_subnet.c b/src/protocol_subnet.c index bc13c21..3e82e47 100644 --- a/src/protocol_subnet.c +++ b/src/protocol_subnet.c @@ -35,8 +35,9 @@ bool send_add_subnet(connection_t *c, const subnet_t *subnet) { char netstr[MAXNETSTR]; - if(!net2str(netstr, sizeof(netstr), subnet)) + if(!net2str(netstr, sizeof(netstr), subnet)) { return false; + } return send_request(c, "%d %x %s %s", ADD_SUBNET, rand(), subnet->owner->name, netstr); } @@ -49,7 +50,7 @@ bool add_subnet_h(connection_t *c, const char *request) { if(sscanf(request, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ADD_SUBNET", c->name, - c->hostname); + c->hostname); return false; } @@ -57,7 +58,7 @@ bool add_subnet_h(connection_t *c, const char *request) { if(!check_id(name)) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ADD_SUBNET", c->name, - c->hostname, "invalid name"); + c->hostname, "invalid name"); return false; } @@ -65,12 +66,13 @@ bool add_subnet_h(connection_t *c, const char *request) { if(!str2net(&s, subnetstr)) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ADD_SUBNET", c->name, - c->hostname, "invalid subnet string"); + c->hostname, "invalid subnet string"); return false; } - if(seen_request(request)) + if(seen_request(request)) { return true; + } /* Check if the owner of the new subnet is in the connection list */ @@ -79,7 +81,7 @@ bool add_subnet_h(connection_t *c, const char *request) { if(tunnelserver && owner != myself && owner != c->node) { /* in case of tunnelserver, ignore indirect subnet registrations */ logger(DEBUG_PROTOCOL, LOG_WARNING, "Ignoring indirect %s from %s (%s) for %s", - "ADD_SUBNET", c->name, c->hostname, subnetstr); + "ADD_SUBNET", c->name, c->hostname, subnetstr); return true; } @@ -91,14 +93,15 @@ bool add_subnet_h(connection_t *c, const char *request) { /* Check if we already know this subnet */ - if(lookup_subnet(owner, &s)) + if(lookup_subnet(owner, &s)) { return true; + } /* If we don't know this subnet, but we are the owner, retaliate with a DEL_SUBNET */ if(owner == myself) { logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself", - "ADD_SUBNET", c->name, c->hostname); + "ADD_SUBNET", c->name, c->hostname); s.owner = myself; send_del_subnet(c, &s); return true; @@ -108,7 +111,7 @@ bool add_subnet_h(connection_t *c, const char *request) { if(tunnelserver) { logger(DEBUG_ALWAYS, LOG_WARNING, "Ignoring unauthorized %s from %s (%s): %s", - "ADD_SUBNET", c->name, c->hostname, subnetstr); + "ADD_SUBNET", c->name, c->hostname, subnetstr); return true; } @@ -116,7 +119,7 @@ bool add_subnet_h(connection_t *c, const char *request) { if(strictsubnets) { logger(DEBUG_ALWAYS, LOG_WARNING, "Ignoring unauthorized %s from %s (%s): %s", - "ADD_SUBNET", c->name, c->hostname, subnetstr); + "ADD_SUBNET", c->name, c->hostname, subnetstr); forward_request(c, request); return true; } @@ -126,18 +129,21 @@ bool add_subnet_h(connection_t *c, const char *request) { *(new = new_subnet()) = s; subnet_add(owner, new); - if(owner->status.reachable) + if(owner->status.reachable) { subnet_update(owner, new, true); + } /* Tell the rest */ - if(!tunnelserver) + if(!tunnelserver) { forward_request(c, request); + } /* Fast handoff of roaming MAC addresses */ - if(s.type == SUBNET_MAC && owner != myself && (old = lookup_subnet(myself, &s)) && old->expires) + if(s.type == SUBNET_MAC && owner != myself && (old = lookup_subnet(myself, &s)) && old->expires) { old->expires = 1; + } return true; } @@ -145,8 +151,9 @@ bool add_subnet_h(connection_t *c, const char *request) { bool send_del_subnet(connection_t *c, const subnet_t *s) { char netstr[MAXNETSTR]; - if(!net2str(netstr, sizeof(netstr), s)) + if(!net2str(netstr, sizeof(netstr), s)) { return false; + } return send_request(c, "%d %x %s %s", DEL_SUBNET, rand(), s->owner->name, netstr); } @@ -159,7 +166,7 @@ bool del_subnet_h(connection_t *c, const char *request) { if(sscanf(request, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "DEL_SUBNET", c->name, - c->hostname); + c->hostname); return false; } @@ -167,7 +174,7 @@ bool del_subnet_h(connection_t *c, const char *request) { if(!check_id(name)) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "DEL_SUBNET", c->name, - c->hostname, "invalid name"); + c->hostname, "invalid name"); return false; } @@ -175,12 +182,13 @@ bool del_subnet_h(connection_t *c, const char *request) { if(!str2net(&s, subnetstr)) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "DEL_SUBNET", c->name, - c->hostname, "invalid subnet string"); + c->hostname, "invalid subnet string"); return false; } - if(seen_request(request)) + if(seen_request(request)) { return true; + } /* Check if the owner of the subnet being deleted is in the connection list */ @@ -189,13 +197,13 @@ bool del_subnet_h(connection_t *c, const char *request) { if(tunnelserver && owner != myself && owner != c->node) { /* in case of tunnelserver, ignore indirect subnet deletion */ logger(DEBUG_PROTOCOL, LOG_WARNING, "Ignoring indirect %s from %s (%s) for %s", - "DEL_SUBNET", c->name, c->hostname, subnetstr); + "DEL_SUBNET", c->name, c->hostname, subnetstr); return true; } if(!owner) { logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for %s which is not in our node tree", - "DEL_SUBNET", c->name, c->hostname, name); + "DEL_SUBNET", c->name, c->hostname, name); return true; } @@ -207,9 +215,12 @@ bool del_subnet_h(connection_t *c, const char *request) { if(!find) { logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for %s which does not appear in his subnet tree", - "DEL_SUBNET", c->name, c->hostname, name); - if(strictsubnets) + "DEL_SUBNET", c->name, c->hostname, name); + + if(strictsubnets) { forward_request(c, request); + } + return true; } @@ -217,25 +228,30 @@ bool del_subnet_h(connection_t *c, const char *request) { if(owner == myself) { logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself", - "DEL_SUBNET", c->name, c->hostname); + "DEL_SUBNET", c->name, c->hostname); send_add_subnet(c, find); return true; } - if(tunnelserver) + if(tunnelserver) { return true; + } /* Tell the rest */ - if(!tunnelserver) + if(!tunnelserver) { forward_request(c, request); - if(strictsubnets) + } + + if(strictsubnets) { return true; + } /* Finally, delete it. */ - if(owner->status.reachable) + if(owner->status.reachable) { subnet_update(owner, find, false); + } subnet_del(owner, find); diff --git a/src/raw_socket_device.c b/src/raw_socket_device.c index 18fbdde..0ac970c 100644 --- a/src/raw_socket_device.c +++ b/src/raw_socket_device.c @@ -39,17 +39,19 @@ static bool setup_device(void) { struct ifreq ifr; struct sockaddr_ll sa; - if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) + if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) { iface = xstrdup("eth0"); + } - if(!get_config_string(lookup_config(config_tree, "Device"), &device)) + if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { device = xstrdup(iface); + } device_info = "raw socket"; if((device_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", device_info, - strerror(errno)); + strerror(errno)); return false; } @@ -60,10 +62,11 @@ static bool setup_device(void) { #endif strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ); + if(ioctl(device_fd, SIOCGIFINDEX, &ifr)) { close(device_fd); logger(DEBUG_ALWAYS, LOG_ERR, "Can't find interface %s: %s", iface, - strerror(errno)); + strerror(errno)); return false; } @@ -83,10 +86,13 @@ static bool setup_device(void) { } static void close_device(void) { - close(device_fd); device_fd = -1; + close(device_fd); + device_fd = -1; - free(device); device = NULL; - free(iface); iface = NULL; + free(device); + device = NULL; + free(iface); + iface = NULL; device_info = NULL; } @@ -95,25 +101,25 @@ static bool read_packet(vpn_packet_t *packet) { if((inlen = read(device_fd, DATA(packet), MTU)) <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); + device, strerror(errno)); return false; } packet->len = inlen; logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, - device_info); + device_info); return true; } static bool write_packet(vpn_packet_t *packet) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + packet->len, device_info); if(write(device_fd, DATA(packet), packet->len) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, - strerror(errno)); + strerror(errno)); return false; } diff --git a/src/route.c b/src/route.c index 05dc4f4..a130e69 100644 --- a/src/route.c +++ b/src/route.c @@ -72,11 +72,13 @@ static uint16_t inet_checksum(void *data, int len, uint16_t prevsum) { len -= 2; } - if(len) + if(len) { checksum += *(uint8_t *)p; + } - while(checksum >> 16) + while(checksum >> 16) { checksum = (checksum & 0xFFFF) + (checksum >> 16); + } return ~checksum; } @@ -86,8 +88,9 @@ static bool ratelimit(int frequency) { static int count = 0; if(lasttime == now.tv_sec) { - if(count >= frequency) + if(count >= frequency) { return true; + } } else { lasttime = now.tv_sec; count = 0; @@ -101,8 +104,9 @@ static bool checklength(node_t *source, vpn_packet_t *packet, length_t length) { if(packet->len < length) { logger(DEBUG_TRAFFIC, LOG_WARNING, "Got too short packet from %s (%s)", source->name, source->hostname); return false; - } else + } else { return true; + } } static void swap_mac_addresses(vpn_packet_t *packet) { @@ -122,8 +126,9 @@ static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_ struct in_addr ip_dst; uint32_t oldlen; - if(ratelimit(3)) + if(ratelimit(3)) { return; + } /* Swap Ethernet source and destination addresses */ @@ -140,32 +145,38 @@ static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_ /* Try to reply with an IP address assigned to the local machine */ - if (type == ICMP_TIME_EXCEEDED && code == ICMP_EXC_TTL) { + if(type == ICMP_TIME_EXCEEDED && code == ICMP_EXC_TTL) { int sockfd = socket(AF_INET, SOCK_DGRAM, 0); - if (sockfd != -1) { + + if(sockfd != -1) { struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr = ip.ip_src; - if (!connect(sockfd, (const struct sockaddr*) &addr, sizeof(addr))) { + + if(!connect(sockfd, (const struct sockaddr *) &addr, sizeof(addr))) { memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; socklen_t addrlen = sizeof(addr); - if (!getsockname(sockfd, (struct sockaddr*) &addr, &addrlen) && addrlen <= sizeof(addr)) { + + if(!getsockname(sockfd, (struct sockaddr *) &addr, &addrlen) && addrlen <= sizeof(addr)) { ip_dst = addr.sin_addr; } } + close(sockfd); } } oldlen = packet->len - ether_size; - if(type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) + if(type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) { icmp.icmp_nextmtu = htons(packet->len - ether_size); + } - if(oldlen >= IP_MSS - ip_size - icmp_size) + if(oldlen >= IP_MSS - ip_size - icmp_size) { oldlen = IP_MSS - ip_size - icmp_size; + } /* Copy first part of original contents to ICMP message */ @@ -220,8 +231,9 @@ static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, length_ uint32_t next; } pseudo; - if(ratelimit(3)) + if(ratelimit(3)) { return; + } /* Swap Ethernet source and destination addresses */ @@ -238,32 +250,38 @@ static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, length_ /* Try to reply with an IP address assigned to the local machine */ - if (type == ICMP6_TIME_EXCEEDED && code == ICMP6_TIME_EXCEED_TRANSIT) { + if(type == ICMP6_TIME_EXCEEDED && code == ICMP6_TIME_EXCEED_TRANSIT) { int sockfd = socket(AF_INET6, SOCK_DGRAM, 0); - if (sockfd != -1) { + + if(sockfd != -1) { struct sockaddr_in6 addr; memset(&addr, 0, sizeof(addr)); addr.sin6_family = AF_INET6; addr.sin6_addr = ip6.ip6_src; - if (!connect(sockfd, (const struct sockaddr*) &addr, sizeof(addr))) { + + if(!connect(sockfd, (const struct sockaddr *) &addr, sizeof(addr))) { memset(&addr, 0, sizeof(addr)); addr.sin6_family = AF_INET6; socklen_t addrlen = sizeof(addr); - if (!getsockname(sockfd, (struct sockaddr*) &addr, &addrlen) && addrlen <= sizeof(addr)) { + + if(!getsockname(sockfd, (struct sockaddr *) &addr, &addrlen) && addrlen <= sizeof(addr)) { pseudo.ip6_src = addr.sin6_addr; } } + close(sockfd); } } pseudo.length = packet->len - ether_size; - if(type == ICMP6_PACKET_TOO_BIG) + if(type == ICMP6_PACKET_TOO_BIG) { icmp6.icmp6_mtu = htonl(pseudo.length); + } - if(pseudo.length >= IP_MSS - ip6_size - icmp6_size) + if(pseudo.length >= IP_MSS - ip6_size - icmp6_size) { pseudo.length = IP_MSS - ip6_size - icmp6_size; + } /* Copy first part of original contents to ICMP message */ @@ -316,56 +334,68 @@ static bool do_decrement_ttl(node_t *source, vpn_packet_t *packet) { ethlen += 4; } - switch (type) { - case ETH_P_IP: - if(!checklength(source, packet, ethlen + ip_size)) - return false; + switch(type) { + case ETH_P_IP: + if(!checklength(source, packet, ethlen + ip_size)) { + return false; + } - if(DATA(packet)[ethlen + 8] <= 1) { - if(DATA(packet)[ethlen + 11] != IPPROTO_ICMP || DATA(packet)[ethlen + 32] != ICMP_TIME_EXCEEDED) - route_ipv4_unreachable(source, packet, ethlen, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL); - return false; + if(DATA(packet)[ethlen + 8] <= 1) { + if(DATA(packet)[ethlen + 11] != IPPROTO_ICMP || DATA(packet)[ethlen + 32] != ICMP_TIME_EXCEEDED) { + route_ipv4_unreachable(source, packet, ethlen, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL); } - uint16_t old = DATA(packet)[ethlen + 8] << 8 | DATA(packet)[ethlen + 9]; - DATA(packet)[ethlen + 8]--; - uint16_t new = DATA(packet)[ethlen + 8] << 8 | DATA(packet)[ethlen + 9]; + return false; + } - uint32_t checksum = DATA(packet)[ethlen + 10] << 8 | DATA(packet)[ethlen + 11]; - checksum += old + (~new & 0xFFFF); - while(checksum >> 16) - checksum = (checksum & 0xFFFF) + (checksum >> 16); - DATA(packet)[ethlen + 10] = checksum >> 8; - DATA(packet)[ethlen + 11] = checksum & 0xff; + uint16_t old = DATA(packet)[ethlen + 8] << 8 | DATA(packet)[ethlen + 9]; + DATA(packet)[ethlen + 8]--; + uint16_t new = DATA(packet)[ethlen + 8] << 8 | DATA(packet)[ethlen + 9]; - return true; + uint32_t checksum = DATA(packet)[ethlen + 10] << 8 | DATA(packet)[ethlen + 11]; + checksum += old + (~new & 0xFFFF); - case ETH_P_IPV6: - if(!checklength(source, packet, ethlen + ip6_size)) - return false; + while(checksum >> 16) { + checksum = (checksum & 0xFFFF) + (checksum >> 16); + } + + DATA(packet)[ethlen + 10] = checksum >> 8; + DATA(packet)[ethlen + 11] = checksum & 0xff; + + return true; - if(DATA(packet)[ethlen + 7] <= 1) { - if(DATA(packet)[ethlen + 6] != IPPROTO_ICMPV6 || DATA(packet)[ethlen + 40] != ICMP6_TIME_EXCEEDED) - route_ipv6_unreachable(source, packet, ethlen, ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT); - return false; + case ETH_P_IPV6: + if(!checklength(source, packet, ethlen + ip6_size)) { + return false; + } + + if(DATA(packet)[ethlen + 7] <= 1) { + if(DATA(packet)[ethlen + 6] != IPPROTO_ICMPV6 || DATA(packet)[ethlen + 40] != ICMP6_TIME_EXCEEDED) { + route_ipv6_unreachable(source, packet, ethlen, ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT); } - DATA(packet)[ethlen + 7]--; + return false; + } - return true; + DATA(packet)[ethlen + 7]--; - default: - return true; + return true; + + default: + return true; } } static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *packet) { - if(!source || !via || !(via->options & OPTION_CLAMP_MSS)) + if(!source || !via || !(via->options & OPTION_CLAMP_MSS)) { return; + } uint16_t mtu = source->mtu; - if(via != myself && via->mtu < mtu) + + if(via != myself && via->mtu < mtu) { mtu = via->mtu; + } /* Find TCP header */ int start = ether_size; @@ -376,52 +406,61 @@ static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *pac type = DATA(packet)[16] << 8 | DATA(packet)[17]; } - if(type == ETH_P_IP && DATA(packet)[start + 9] == 6) + if(type == ETH_P_IP && DATA(packet)[start + 9] == 6) { start += (DATA(packet)[start] & 0xf) * 4; - else if(type == ETH_P_IPV6 && DATA(packet)[start + 6] == 6) + } else if(type == ETH_P_IPV6 && DATA(packet)[start + 6] == 6) { start += 40; - else + } else { return; + } - if(packet->len <= start + 20) + if(packet->len <= start + 20) { return; + } /* Use data offset field to calculate length of options field */ int len = ((DATA(packet)[start + 12] >> 4) - 5) * 4; - if(packet->len < start + 20 + len) + if(packet->len < start + 20 + len) { return; + } /* Search for MSS option header */ for(int i = 0; i < len;) { - if(DATA(packet)[start + 20 + i] == 0) + if(DATA(packet)[start + 20 + i] == 0) { break; + } if(DATA(packet)[start + 20 + i] == 1) { i++; continue; } - if(i > len - 2 || i > len - DATA(packet)[start + 21 + i]) + if(i > len - 2 || i > len - DATA(packet)[start + 21 + i]) { break; + } if(DATA(packet)[start + 20 + i] != 2) { - if(DATA(packet)[start + 21 + i] < 2) + if(DATA(packet)[start + 21 + i] < 2) { break; + } + i += DATA(packet)[start + 21 + i]; continue; } - if(DATA(packet)[start + 21] != 4) + if(DATA(packet)[start + 21] != 4) { break; + } /* Found it */ uint16_t oldmss = DATA(packet)[start + 22 + i] << 8 | DATA(packet)[start + 23 + i]; uint16_t newmss = mtu - start - 20; uint32_t csum = DATA(packet)[start + 16] << 8 | DATA(packet)[start + 17]; - if(oldmss <= newmss) + if(oldmss <= newmss) { break; + } logger(DEBUG_TRAFFIC, LOG_INFO, "Clamping MSS of packet from %s to %s to %d", source->name, via->name, newmss); @@ -447,23 +486,29 @@ static void age_subnets(void *data) { if(s->expires && s->expires < now.tv_sec) { if(debug_level >= DEBUG_TRAFFIC) { char netstr[MAXNETSTR]; - if(net2str(netstr, sizeof(netstr), s)) + + if(net2str(netstr, sizeof(netstr), s)) { logger(DEBUG_TRAFFIC, LOG_INFO, "Subnet %s expired", netstr); + } } for list_each(connection_t, c, connection_list) - if(c->edge) + if(c->edge) { send_del_subnet(c, s); + } subnet_del(myself, s); } else { - if(s->expires) + if(s->expires) { left = true; + } } } if(left) - timeout_set(&age_subnets_timeout, &(struct timeval){10, rand() % 100000}); + timeout_set(&age_subnets_timeout, &(struct timeval) { + 10, rand() % 100000 + }); } static void learn_mac(mac_t *address) { @@ -473,8 +518,8 @@ static void learn_mac(mac_t *address) { if(!subnet) { logger(DEBUG_TRAFFIC, LOG_INFO, "Learned new MAC address %x:%x:%x:%x:%x:%x", - address->x[0], address->x[1], address->x[2], address->x[3], - address->x[4], address->x[5]); + address->x[0], address->x[1], address->x[2], address->x[3], + address->x[4], address->x[5]); subnet = new_subnet(); subnet->type = SUBNET_MAC; @@ -487,20 +532,25 @@ static void learn_mac(mac_t *address) { /* And tell all other tinc daemons it's our MAC */ for list_each(connection_t, c, connection_list) - if(c->edge) + if(c->edge) { send_add_subnet(c, subnet); + } - timeout_add(&age_subnets_timeout, age_subnets, NULL, &(struct timeval){10, rand() % 100000}); + timeout_add(&age_subnets_timeout, age_subnets, NULL, &(struct timeval) { + 10, rand() % 100000 + }); } else { - if(subnet->expires) + if(subnet->expires) { subnet->expires = now.tv_sec + macexpire; + } } } static void route_broadcast(node_t *source, vpn_packet_t *packet) { if(decrement_ttl && source != myself) - if(!do_decrement_ttl(source, packet)) + if(!do_decrement_ttl(source, packet)) { return; + } broadcast_packet(source, packet); } @@ -518,8 +568,9 @@ static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t et fragment.priority = packet->priority; fragment.offset = DEFAULT_PACKET_OFFSET; - if(ip.ip_hl != ip_size / 4) + if(ip.ip_hl != ip_size / 4) { return; + } todo = ntohs(ip.ip_len) - ip_size; @@ -557,8 +608,9 @@ static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t et } static void route_ipv4(node_t *source, vpn_packet_t *packet) { - if(!checklength(source, packet, ether_size + ip_size)) + if(!checklength(source, packet, ether_size + ip_size)) { return; + } subnet_t *subnet; node_t *via; @@ -569,17 +621,17 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet) { if(!subnet) { logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet from %s (%s): unknown IPv4 destination address %d.%d.%d.%d", - source->name, source->hostname, - dest.x[0], - dest.x[1], - dest.x[2], - dest.x[3]); + source->name, source->hostname, + dest.x[0], + dest.x[1], + dest.x[2], + dest.x[3]); route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_UNKNOWN); return; } - if (!subnet->owner) { + if(!subnet->owner) { route_broadcast(source, packet); return; } @@ -589,18 +641,22 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet) { return; } - if(!subnet->owner->status.reachable) + if(!subnet->owner->status.reachable) { return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_UNREACH); + } - if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) + if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) { return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO); + } if(decrement_ttl && source != myself && subnet->owner != myself) - if(!do_decrement_ttl(source, packet)) + if(!do_decrement_ttl(source, packet)) { return; + } - if(priorityinheritance) + if(priorityinheritance) { packet->priority = DATA(packet)[15]; + } via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; @@ -609,11 +665,13 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet) { return; } - if(directonly && subnet->owner != via) + if(directonly && subnet->owner != via) { return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO); + } if(via && packet->len > MAX(via->mtu, 590) && via != myself) { logger(DEBUG_TRAFFIC, LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu); + if(DATA(packet)[20] & 0x40) { packet->len = MAX(via->mtu, 590); route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED); @@ -632,8 +690,9 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet) { static void route_neighborsol(node_t *source, vpn_packet_t *packet); static void route_ipv6(node_t *source, vpn_packet_t *packet) { - if(!checklength(source, packet, ether_size + ip6_size)) + if(!checklength(source, packet, ether_size + ip6_size)) { return; + } if(DATA(packet)[20] == IPPROTO_ICMPV6 && checklength(source, packet, ether_size + ip6_size + icmp6_size) && DATA(packet)[54] == ND_NEIGHBOR_SOLICIT) { route_neighborsol(source, packet); @@ -649,21 +708,21 @@ static void route_ipv6(node_t *source, vpn_packet_t *packet) { if(!subnet) { logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet from %s (%s): unknown IPv6 destination address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx", - source->name, source->hostname, - ntohs(dest.x[0]), - ntohs(dest.x[1]), - ntohs(dest.x[2]), - ntohs(dest.x[3]), - ntohs(dest.x[4]), - ntohs(dest.x[5]), - ntohs(dest.x[6]), - ntohs(dest.x[7])); + source->name, source->hostname, + ntohs(dest.x[0]), + ntohs(dest.x[1]), + ntohs(dest.x[2]), + ntohs(dest.x[3]), + ntohs(dest.x[4]), + ntohs(dest.x[5]), + ntohs(dest.x[6]), + ntohs(dest.x[7])); route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR); return; } - if (!subnet->owner) { + if(!subnet->owner) { route_broadcast(source, packet); return; } @@ -673,18 +732,22 @@ static void route_ipv6(node_t *source, vpn_packet_t *packet) { return; } - if(!subnet->owner->status.reachable) + if(!subnet->owner->status.reachable) { return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE); + } - if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) + if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) { return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN); + } if(decrement_ttl && source != myself && subnet->owner != myself) - if(!do_decrement_ttl(source, packet)) + if(!do_decrement_ttl(source, packet)) { return; + } - if(priorityinheritance) + if(priorityinheritance) { packet->priority = ((DATA(packet)[14] & 0x0f) << 4) | (DATA(packet)[15] >> 4); + } via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; @@ -693,8 +756,9 @@ static void route_ipv6(node_t *source, vpn_packet_t *packet) { return; } - if(directonly && subnet->owner != via) + if(directonly && subnet->owner != via) { return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN); + } if(via && packet->len > MAX(via->mtu, 1294) && via != myself) { logger(DEBUG_TRAFFIC, LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu); @@ -725,8 +789,9 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { uint32_t next; } pseudo; - if(!checklength(source, packet, ether_size + ip6_size + ns_size)) + if(!checklength(source, packet, ether_size + ip6_size + ns_size)) { return; + } has_opt = packet->len >= ether_size + ip6_size + ns_size + opt_size + ETH_ALEN; @@ -739,18 +804,21 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { memcpy(&ip6, DATA(packet) + ether_size, ip6_size); memcpy(&ns, DATA(packet) + ether_size + ip6_size, ns_size); - if(has_opt) + + if(has_opt) { memcpy(&opt, DATA(packet) + ether_size + ip6_size + ns_size, opt_size); + } /* First, snatch the source address from the neighbor solicitation packet */ - if(overwrite_mac) + if(overwrite_mac) { memcpy(mymac.x, DATA(packet) + ETH_ALEN, ETH_ALEN); + } /* Check if this is a valid neighbor solicitation request */ if(ns.nd_ns_hdr.icmp6_type != ND_NEIGHBOR_SOLICIT || - (has_opt && opt.nd_opt_type != ND_OPT_SOURCE_LINKADDR)) { + (has_opt && opt.nd_opt_type != ND_OPT_SOURCE_LINKADDR)) { logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet: received unknown type neighbor solicitation request"); return; } @@ -759,16 +827,20 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { pseudo.ip6_src = ip6.ip6_src; pseudo.ip6_dst = ip6.ip6_dst; - if(has_opt) + + if(has_opt) { pseudo.length = htonl(ns_size + opt_size + ETH_ALEN); - else + } else { pseudo.length = htonl(ns_size); + } + pseudo.next = htonl(IPPROTO_ICMPV6); /* Generate checksum */ checksum = inet_checksum(&pseudo, sizeof(pseudo), ~0); checksum = inet_checksum(&ns, ns_size, checksum); + if(has_opt) { checksum = inet_checksum(&opt, opt_size, checksum); checksum = inet_checksum(DATA(packet) + ether_size + ip6_size + ns_size + opt_size, ETH_ALEN, checksum); @@ -785,26 +857,28 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { if(!subnet) { logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet: neighbor solicitation request for unknown address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx", - ntohs(((uint16_t *) &ns.nd_ns_target)[0]), - ntohs(((uint16_t *) &ns.nd_ns_target)[1]), - ntohs(((uint16_t *) &ns.nd_ns_target)[2]), - ntohs(((uint16_t *) &ns.nd_ns_target)[3]), - ntohs(((uint16_t *) &ns.nd_ns_target)[4]), - ntohs(((uint16_t *) &ns.nd_ns_target)[5]), - ntohs(((uint16_t *) &ns.nd_ns_target)[6]), - ntohs(((uint16_t *) &ns.nd_ns_target)[7])); + ntohs(((uint16_t *) &ns.nd_ns_target)[0]), + ntohs(((uint16_t *) &ns.nd_ns_target)[1]), + ntohs(((uint16_t *) &ns.nd_ns_target)[2]), + ntohs(((uint16_t *) &ns.nd_ns_target)[3]), + ntohs(((uint16_t *) &ns.nd_ns_target)[4]), + ntohs(((uint16_t *) &ns.nd_ns_target)[5]), + ntohs(((uint16_t *) &ns.nd_ns_target)[6]), + ntohs(((uint16_t *) &ns.nd_ns_target)[7])); return; } /* Check if it is for our own subnet */ - if(subnet->owner == myself) - return; /* silently ignore */ + if(subnet->owner == myself) { + return; /* silently ignore */ + } if(decrement_ttl) - if(!do_decrement_ttl(source, packet)) + if(!do_decrement_ttl(source, packet)) { return; + } /* Create neighbor advertation reply */ @@ -814,8 +888,9 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { ip6.ip6_dst = ip6.ip6_src; /* swap destination and source protocoll address */ ip6.ip6_src = ns.nd_ns_target; - if(has_opt) - memcpy(DATA(packet) + ether_size + ip6_size + ns_size + opt_size, DATA(packet) + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */ + if(has_opt) { + memcpy(DATA(packet) + ether_size + ip6_size + ns_size + opt_size, DATA(packet) + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */ + } ns.nd_ns_cksum = 0; ns.nd_ns_type = ND_NEIGHBOR_ADVERT; @@ -826,16 +901,20 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { pseudo.ip6_src = ip6.ip6_src; pseudo.ip6_dst = ip6.ip6_dst; - if(has_opt) + + if(has_opt) { pseudo.length = htonl(ns_size + opt_size + ETH_ALEN); - else + } else { pseudo.length = htonl(ns_size); + } + pseudo.next = htonl(IPPROTO_ICMPV6); /* Generate checksum */ checksum = inet_checksum(&pseudo, sizeof(pseudo), ~0); checksum = inet_checksum(&ns, ns_size, checksum); + if(has_opt) { checksum = inet_checksum(&opt, opt_size, checksum); checksum = inet_checksum(DATA(packet) + ether_size + ip6_size + ns_size + opt_size, ETH_ALEN, checksum); @@ -847,8 +926,10 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { memcpy(DATA(packet) + ether_size, &ip6, ip6_size); memcpy(DATA(packet) + ether_size + ip6_size, &ns, ns_size); - if(has_opt) + + if(has_opt) { memcpy(DATA(packet) + ether_size + ip6_size + ns_size, &opt, opt_size); + } send_packet(source, packet); } @@ -860,8 +941,9 @@ static void route_arp(node_t *source, vpn_packet_t *packet) { subnet_t *subnet; struct in_addr addr; - if(!checklength(source, packet, ether_size + arp_size)) + if(!checklength(source, packet, ether_size + arp_size)) { return; + } if(source != myself) { logger(DEBUG_TRAFFIC, LOG_WARNING, "Got ARP request from %s (%s) while in router mode!", source->name, source->hostname); @@ -870,8 +952,9 @@ static void route_arp(node_t *source, vpn_packet_t *packet) { /* First, snatch the source address from the ARP packet */ - if(overwrite_mac) + if(overwrite_mac) { memcpy(mymac.x, DATA(packet) + ETH_ALEN, ETH_ALEN); + } /* Copy headers from packet to structs on the stack */ @@ -880,7 +963,7 @@ static void route_arp(node_t *source, vpn_packet_t *packet) { /* Check if this is a valid ARP request */ if(ntohs(arp.arp_hrd) != ARPHRD_ETHER || ntohs(arp.arp_pro) != ETH_P_IP || - arp.arp_hln != ETH_ALEN || arp.arp_pln != sizeof(addr) || ntohs(arp.arp_op) != ARPOP_REQUEST) { + arp.arp_hln != ETH_ALEN || arp.arp_pln != sizeof(addr) || ntohs(arp.arp_op) != ARPOP_REQUEST) { logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet: received unknown type ARP request"); return; } @@ -891,19 +974,21 @@ static void route_arp(node_t *source, vpn_packet_t *packet) { if(!subnet) { logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet: ARP request for unknown address %d.%d.%d.%d", - arp.arp_tpa[0], arp.arp_tpa[1], arp.arp_tpa[2], - arp.arp_tpa[3]); + arp.arp_tpa[0], arp.arp_tpa[1], arp.arp_tpa[2], + arp.arp_tpa[3]); return; } /* Check if it is for our own subnet */ - if(subnet->owner == myself) - return; /* silently ignore */ + if(subnet->owner == myself) { + return; /* silently ignore */ + } if(decrement_ttl) - if(!do_decrement_ttl(source, packet)) + if(!do_decrement_ttl(source, packet)) { return; + } memcpy(&addr, arp.arp_tpa, sizeof(addr)); /* save protocol addr */ memcpy(arp.arp_tpa, arp.arp_spa, sizeof(addr)); /* swap destination and source protocol address */ @@ -948,28 +1033,32 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { return; } - if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) + if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) { return; + } if(decrement_ttl && source != myself && subnet->owner != myself) - if(!do_decrement_ttl(source, packet)) + if(!do_decrement_ttl(source, packet)) { return; + } uint16_t type = DATA(packet)[12] << 8 | DATA(packet)[13]; if(priorityinheritance) { - if(type == ETH_P_IP && packet->len >= ether_size + ip_size) + if(type == ETH_P_IP && packet->len >= ether_size + ip_size) { packet->priority = DATA(packet)[15]; - else if(type == ETH_P_IPV6 && packet->len >= ether_size + ip6_size) + } else if(type == ETH_P_IPV6 && packet->len >= ether_size + ip6_size) { packet->priority = ((DATA(packet)[14] & 0x0f) << 4) | (DATA(packet)[15] >> 4); + } } // Handle packets larger than PMTU node_t *via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; - if(directonly && subnet->owner != via) + if(directonly && subnet->owner != via) { return; + } if(via && packet->len > via->mtu && via != myself) { logger(DEBUG_TRAFFIC, LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu); @@ -987,6 +1076,7 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { } else { fragment_ipv4_packet(via, packet, ethlen); } + return; } else if(type == ETH_P_IPV6 && packet->len > 1280 + ethlen) { packet->len = via->mtu; @@ -1004,60 +1094,67 @@ static void send_pcap(vpn_packet_t *packet) { pcap = false; for list_each(connection_t, c, connection_list) { - if(!c->status.pcap) + if(!c->status.pcap) { continue; + } pcap = true; int len = packet->len; - if(c->outmaclength && c->outmaclength < len) + + if(c->outmaclength && c->outmaclength < len) { len = c->outmaclength; + } - if(send_request(c, "%d %d %d", CONTROL, REQ_PCAP, len)) + if(send_request(c, "%d %d %d", CONTROL, REQ_PCAP, len)) { send_meta(c, (char *)DATA(packet), len); + } } } void route(node_t *source, vpn_packet_t *packet) { - if(pcap) + if(pcap) { send_pcap(packet); + } if(forwarding_mode == FMODE_KERNEL && source != myself) { send_packet(myself, packet); return; } - if(!checklength(source, packet, ether_size)) + if(!checklength(source, packet, ether_size)) { return; + } uint16_t type = DATA(packet)[12] << 8 | DATA(packet)[13]; - switch (routing_mode) { - case RMODE_ROUTER: - switch (type) { - case ETH_P_ARP: - route_arp(source, packet); - break; - - case ETH_P_IP: - route_ipv4(source, packet); - break; - - case ETH_P_IPV6: - route_ipv6(source, packet); - break; + switch(routing_mode) { + case RMODE_ROUTER: + switch(type) { + case ETH_P_ARP: + route_arp(source, packet); + break; - default: - logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet from %s (%s): unknown type %hx", source->name, source->hostname, type); - break; - } + case ETH_P_IP: + route_ipv4(source, packet); break; - case RMODE_SWITCH: - route_mac(source, packet); + case ETH_P_IPV6: + route_ipv6(source, packet); break; - case RMODE_HUB: - route_broadcast(source, packet); + default: + logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet from %s (%s): unknown type %hx", source->name, source->hostname, type); break; + } + + break; + + case RMODE_SWITCH: + route_mac(source, packet); + break; + + case RMODE_HUB: + route_broadcast(source, packet); + break; } } diff --git a/src/rsa.h b/src/rsa.h index dc849ae..a31ec24 100644 --- a/src/rsa.h +++ b/src/rsa.h @@ -25,12 +25,12 @@ typedef struct rsa rsa_t; #endif extern void rsa_free(rsa_t *rsa); -extern rsa_t *rsa_set_hex_public_key(char *n, char *e) __attribute__ ((__malloc__)); -extern rsa_t *rsa_set_hex_private_key(char *n, char *e, char *d) __attribute__ ((__malloc__)); -extern rsa_t *rsa_read_pem_public_key(FILE *fp) __attribute__ ((__malloc__)); -extern rsa_t *rsa_read_pem_private_key(FILE *fp) __attribute__ ((__malloc__)); +extern rsa_t *rsa_set_hex_public_key(char *n, char *e) __attribute__((__malloc__)); +extern rsa_t *rsa_set_hex_private_key(char *n, char *e, char *d) __attribute__((__malloc__)); +extern rsa_t *rsa_read_pem_public_key(FILE *fp) __attribute__((__malloc__)); +extern rsa_t *rsa_read_pem_private_key(FILE *fp) __attribute__((__malloc__)); extern size_t rsa_size(rsa_t *rsa); -extern bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) __attribute__ ((__warn_unused_result__)); -extern bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) __attribute__ ((__warn_unused_result__)); +extern bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) __attribute__((__warn_unused_result__)); +extern bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) __attribute__((__warn_unused_result__)); #endif diff --git a/src/rsagen.h b/src/rsagen.h index 83349f9..a661607 100644 --- a/src/rsagen.h +++ b/src/rsagen.h @@ -22,8 +22,8 @@ #include "rsa.h" -extern rsa_t *rsa_generate(size_t bits, unsigned long exponent) __attribute__ ((__malloc__)); -extern bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp) __attribute__ ((__warn_unused_result__)); -extern bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp) __attribute__ ((__warn_unused_result__)); +extern rsa_t *rsa_generate(size_t bits, unsigned long exponent) __attribute__((__malloc__)); +extern bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp) __attribute__((__warn_unused_result__)); +extern bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp) __attribute__((__warn_unused_result__)); #endif diff --git a/src/script.c b/src/script.c index 80c58c0..81216a3 100644 --- a/src/script.c +++ b/src/script.c @@ -30,8 +30,11 @@ #ifdef HAVE_PUTENV static void unputenv(const char *p) { const char *e = strchr(p, '='); - if(!e) + + if(!e) { return; + } + int len = e - p; #ifndef HAVE_UNSETENV #ifdef HAVE_MINGW @@ -48,12 +51,14 @@ static void unputenv(const char *p) { // We must keep what we putenv() around in memory. // To do this without memory leaks, keep things in a list and reuse if possible. static list_t list = {}; + for list_each(char, data, &list) { if(!strcmp(data, var)) { putenv(data); return; } } + char *data = xstrdup(var); list_insert_tail(&list, data); putenv(data); @@ -97,21 +102,32 @@ void environment_init(environment_t *env) { env->size = min_env_size; env->entries = xzalloc(env->size * sizeof(*env->entries)); - if(netname) + if(netname) { environment_add(env, "NETNAME=%s", netname); - if(myname) + } + + if(myname) { environment_add(env, "NAME=%s", myname); - if(device) + } + + if(device) { environment_add(env, "DEVICE=%s", device); - if(iface) + } + + if(iface) { environment_add(env, "INTERFACE=%s", iface); - if(debug_level >= 0) + } + + if(debug_level >= 0) { environment_add(env, "DEBUG=%d", debug_level); + } } void environment_exit(environment_t *env) { - for(int i = 0; i < env->n; i++) + for(int i = 0; i < env->n; i++) { free(env->entries[i]); + } + free(env->entries); } @@ -124,8 +140,9 @@ bool execute_script(const char *name, environment_t *env) { /* First check if there is a script */ #ifdef HAVE_MINGW + if(!*scriptextension) { - const char *pathext = getenv("PATHEXT") ?: ".COM;.EXE;.BAT;.CMD"; + const char *pathext = getenv("PATHEXT") ? : ".COM;.EXE;.BAT;.CMD"; size_t pathlen = strlen(pathext); size_t scriptlen = strlen(scriptname); char fullname[scriptlen + pathlen + 1]; @@ -134,8 +151,10 @@ bool execute_script(const char *name, environment_t *env) { const char *p = pathext; bool found = false; + while(p && *p) { const char *q = strchr(p, ';'); + if(q) { memcpy(ext, p, q - p); ext[q - p] = 0; @@ -143,29 +162,37 @@ bool execute_script(const char *name, environment_t *env) { } else { strncpy(ext, p, pathlen + 1); } - if((found = !access(fullname, F_OK))) + + if((found = !access(fullname, F_OK))) { break; + } + p = q; } - if(!found) + + if(!found) { return true; + } } else #endif - if(access(scriptname, F_OK)) - return true; + if(access(scriptname, F_OK)) { + return true; + } logger(DEBUG_STATUS, LOG_INFO, "Executing script %s", name); /* Set environment */ - for(int i = 0; i < env->n; i++) + for(int i = 0; i < env->n; i++) { putenv(env->entries[i]); + } - if(scriptinterpreter) + if(scriptinterpreter) { xasprintf(&command, "%s \"%s\"", scriptinterpreter, scriptname); - else + } else { xasprintf(&command, "\"%s\"", scriptname); + } int status = system(command); @@ -173,25 +200,28 @@ bool execute_script(const char *name, environment_t *env) { /* Unset environment */ - for(int i = 0; i < env->n; i++) + for(int i = 0; i < env->n; i++) { unputenv(env->entries[i]); + } if(status != -1) { #ifdef WEXITSTATUS + if(WIFEXITED(status)) { /* Child exited by itself */ if(WEXITSTATUS(status)) { logger(DEBUG_ALWAYS, LOG_ERR, "Script %s exited with non-zero status %d", - name, WEXITSTATUS(status)); + name, WEXITSTATUS(status)); return false; } } else if(WIFSIGNALED(status)) { /* Child was killed by a signal */ logger(DEBUG_ALWAYS, LOG_ERR, "Script %s was killed by signal %d (%s)", - name, WTERMSIG(status), strsignal(WTERMSIG(status))); + name, WTERMSIG(status), strsignal(WTERMSIG(status))); return false; } else { /* Something strange happened */ logger(DEBUG_ALWAYS, LOG_ERR, "Script %s terminated abnormally", name); return false; } + #endif } else { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "system", strerror(errno)); diff --git a/src/solaris/device.c b/src/solaris/device.c index 7ca2e7e..9480dda 100644 --- a/src/solaris/device.c +++ b/src/solaris/device.c @@ -59,30 +59,33 @@ static bool setup_device(void) { char *type; if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { - if(routing_mode == RMODE_ROUTER) + if(routing_mode == RMODE_ROUTER) { device = xstrdup(DEFAULT_TUN_DEVICE); - else + } else { device = xstrdup(DEFAULT_TAP_DEVICE); + } } if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) { if(!strcasecmp(type, "tun")) /* use default */; - else if(!strcasecmp(type, "tap")) + else if(!strcasecmp(type, "tap")) { device_type = DEVICE_TYPE_TAP; - else { + } else { logger(DEBUG_ALWAYS, LOG_ERR, "Unknown device type %s!", type); return false; } } else { - if(strstr(device, "tap") || routing_mode != RMODE_ROUTER) + if(strstr(device, "tap") || routing_mode != RMODE_ROUTER) { device_type = DEVICE_TYPE_TAP; + } } - if(device_type == DEVICE_TYPE_TUN) + if(device_type == DEVICE_TYPE_TUN) { device_info = "Solaris tun device"; - else + } else { device_info = "Solaris tap device"; + } /* The following is black magic copied from OpenVPN. */ @@ -101,8 +104,10 @@ static bool setup_device(void) { char *ptr = device; get_config_string(lookup_config(config_tree, "Interface"), &ptr); - while(*ptr && !isdigit(*ptr)) + while(*ptr && !isdigit(*ptr)) { ptr++; + } + int ppa = atoi(ptr); /* Assign a new PPA and get its unit number. */ @@ -110,20 +115,24 @@ static bool setup_device(void) { struct strioctl strioc_ppa = { .ic_cmd = TUNNEWPPA, .ic_len = sizeof(ppa), - .ic_dp = (char *)&ppa, + .ic_dp = (char *) &ppa, }; if(!*ptr) { /* no number given, try dynamic */ bool found = false; + while(!found && ppa < 64) { int new_ppa = ioctl(device_fd, I_STR, &strioc_ppa); + if(new_ppa >= 0) { ppa = new_ppa; found = true; break; } + ppa++; } + if(!found) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not find free PPA for %s %s!", device_info, device); return false; @@ -136,6 +145,7 @@ static bool setup_device(void) { } int if_fd; + if((if_fd = open(device, O_RDWR, 0)) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s\n", device, strerror(errno)); return false; @@ -152,6 +162,7 @@ static bool setup_device(void) { /* Remove muxes just in case they are left over from a crashed tincd */ struct lifreq ifr = {}; strncpy(ifr.lifr_name, iface, sizeof(ifr.lifr_name)); + if(ioctl(ip_fd, SIOCGLIFMUXID, &ifr) >= 0) { int muxid = ifr.lifr_arp_muxid; ioctl(ip_fd, I_PUNLINK, muxid); @@ -165,7 +176,7 @@ static bool setup_device(void) { if(ioctl(if_fd, IF_UNITSEL, (char *)&ppa) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not set PPA %d on %s %s!", ppa, device_info, device); return false; - } + } } int arp_fd = -1; @@ -186,6 +197,7 @@ static bool setup_device(void) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not set PPA %d on %s %s!", ppa, device_info, device); return false; } + if(ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not set flags on %s %s!", device_info, device); return false; @@ -199,8 +211,9 @@ static bool setup_device(void) { /* Pop any modules on the stream */ while(true) { - if(ioctl(ip_fd, I_POP, NULL) < 0) + if(ioctl(ip_fd, I_POP, NULL) < 0) { break; + } } /* Push arp module to ip_fd */ @@ -225,7 +238,7 @@ static bool setup_device(void) { struct strioctl strioc_if = { .ic_cmd = SIOCSLIFNAME, .ic_len = sizeof(ifr), - .ic_dp = (char *)&ifr, + .ic_dp = (char *) &ifr, }; if(ioctl(arp_fd, I_STR, &strioc_if) < 0) { @@ -246,12 +259,16 @@ static bool setup_device(void) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not link %s %s to ARP", device_info, device); return false; } + close(arp_fd); } struct lifreq ifr = {}; + strncpy(ifr.lifr_name, iface, sizeof(ifr.lifr_name)); + ifr.lifr_ip_muxid = ip_muxid; + if(device_type == DEVICE_TYPE_TAP) { ifr.lifr_arp_muxid = arp_muxid; } @@ -260,6 +277,7 @@ static bool setup_device(void) { if(device_type == DEVICE_TYPE_TAP) { ioctl(ip_fd, I_PUNLINK, arp_muxid); } + ioctl(ip_fd, I_PUNLINK, ip_muxid); logger(DEBUG_ALWAYS, LOG_ERR, "Could not set multiplexor id for %s %s", device_info, device); return false; @@ -281,6 +299,7 @@ static void close_device(void) { if(iface) { struct lifreq ifr = {}; strncpy(ifr.lifr_name, iface, sizeof(ifr.lifr_name)); + if(ioctl(ip_fd, SIOCGLIFMUXID, &ifr) >= 0) { int muxid = ifr.lifr_arp_muxid; ioctl(ip_fd, I_PUNLINK, muxid); @@ -289,11 +308,15 @@ static void close_device(void) { } } - close(ip_fd); ip_fd = -1; - close(device_fd); device_fd = -1; + close(ip_fd); + ip_fd = -1; + close(device_fd); + device_fd = -1; - free(device); device = NULL; - free(iface); iface = NULL; + free(device); + device = NULL; + free(iface); + iface = NULL; } static bool read_packet(vpn_packet_t *packet) { @@ -302,47 +325,49 @@ static bool read_packet(vpn_packet_t *packet) { int f = 0; switch(device_type) { - case DEVICE_TYPE_TUN: - sbuf.maxlen = MTU - 14; - sbuf.buf = (char *)DATA(packet) + 14; + case DEVICE_TYPE_TUN: + sbuf.maxlen = MTU - 14; + sbuf.buf = (char *)DATA(packet) + 14; - if((result = getmsg(device_fd, NULL, &sbuf, &f)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); - return false; - } + if((result = getmsg(device_fd, NULL, &sbuf, &f)) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); + return false; + } - switch(DATA(packet)[14] >> 4) { - case 4: - DATA(packet)[12] = 0x08; - DATA(packet)[13] = 0x00; - break; - case 6: - DATA(packet)[12] = 0x86; - DATA(packet)[13] = 0xDD; - break; - default: - logger(DEBUG_TRAFFIC, LOG_ERR, "Unknown IP version %d while reading packet from %s %s", DATA(packet)[14] >> 4, device_info, device); - return false; - } + switch(DATA(packet)[14] >> 4) { + case 4: + DATA(packet)[12] = 0x08; + DATA(packet)[13] = 0x00; + break; - memset(DATA(packet), 0, 12); - packet->len = sbuf.len + 14; + case 6: + DATA(packet)[12] = 0x86; + DATA(packet)[13] = 0xDD; break; - case DEVICE_TYPE_TAP: - sbuf.maxlen = MTU; - sbuf.buf = (char *)DATA(packet); + default: + logger(DEBUG_TRAFFIC, LOG_ERR, "Unknown IP version %d while reading packet from %s %s", DATA(packet)[14] >> 4, device_info, device); + return false; + } + + memset(DATA(packet), 0, 12); + packet->len = sbuf.len + 14; + break; - if((result = getmsg(device_fd, NULL, &sbuf, &f)) < 0) { - logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); - return false; - } + case DEVICE_TYPE_TAP: + sbuf.maxlen = MTU; + sbuf.buf = (char *)DATA(packet); - packet->len = sbuf.len; - break; + if((result = getmsg(device_fd, NULL, &sbuf, &f)) < 0) { + logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); + return false; + } - default: - abort(); + packet->len = sbuf.len; + break; + + default: + abort(); } logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, device_info); @@ -356,28 +381,30 @@ static bool write_packet(vpn_packet_t *packet) { struct strbuf sbuf; switch(device_type) { - case DEVICE_TYPE_TUN: - sbuf.len = packet->len - 14; - sbuf.buf = (char *)DATA(packet) + 14; + case DEVICE_TYPE_TUN: + sbuf.len = packet->len - 14; + sbuf.buf = (char *)DATA(packet) + 14; - if(putmsg(device_fd, NULL, &sbuf, 0) < 0) { - logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); - return false; - } - break; + if(putmsg(device_fd, NULL, &sbuf, 0) < 0) { + logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); + return false; + } - case DEVICE_TYPE_TAP: - sbuf.len = packet->len; - sbuf.buf = (char *)DATA(packet); + break; - if(putmsg(device_fd, NULL, &sbuf, 0) < 0) { - logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); - return false; - } - break; + case DEVICE_TYPE_TAP: + sbuf.len = packet->len; + sbuf.buf = (char *)DATA(packet); - default: - abort(); + if(putmsg(device_fd, NULL, &sbuf, 0) < 0) { + logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); + return false; + } + + break; + + default: + abort(); } return true; diff --git a/src/splay_tree.c b/src/splay_tree.c index bd0f06b..2b6186f 100644 --- a/src/splay_tree.c +++ b/src/splay_tree.c @@ -31,8 +31,10 @@ static splay_node_t *splay_top_down(splay_tree_t *tree, const void *data, int *r int c; if(!root) { - if(result) + if(result) { *result = 0; + } + return NULL; } @@ -45,8 +47,9 @@ static splay_node_t *splay_top_down(splay_tree_t *tree, const void *data, int *r child->parent = rightbottom; rightbottom = child; - if((root->left = child->right)) + if((root->left = child->right)) { child->right->parent = root; + } child->right = root; root->parent = child; @@ -55,7 +58,7 @@ static splay_node_t *splay_top_down(splay_tree_t *tree, const void *data, int *r grandchild->parent = NULL; root = grandchild; - } else if (c > 0 && (grandchild = child->right)) { + } else if(c > 0 && (grandchild = child->right)) { leftbottom->right = child; child->parent = leftbottom; leftbottom = child; @@ -89,8 +92,9 @@ static splay_node_t *splay_top_down(splay_tree_t *tree, const void *data, int *r child->parent = leftbottom; leftbottom = child; - if((root->right = child->left)) + if((root->right = child->left)) { child->left->parent = root; + } child->left = root; root->parent = child; @@ -99,7 +103,7 @@ static splay_node_t *splay_top_down(splay_tree_t *tree, const void *data, int *r grandchild->parent = NULL; root = grandchild; - } else if (c < 0 && (grandchild = child->left)) { + } else if(c < 0 && (grandchild = child->left)) { rightbottom->left = child; child->parent = rightbottom; rightbottom = child; @@ -137,6 +141,7 @@ static splay_node_t *splay_top_down(splay_tree_t *tree, const void *data, int *r leftbottom->right = root->left; root->left->parent = leftbottom; } + root->left = left.right; left.right->parent = root; } @@ -146,6 +151,7 @@ static splay_node_t *splay_top_down(splay_tree_t *tree, const void *data, int *r rightbottom->left = root->right; root->right->parent = rightbottom; } + root->right = right.left; right.left->parent = root; } @@ -153,8 +159,10 @@ static splay_node_t *splay_top_down(splay_tree_t *tree, const void *data, int *r /* Return result */ tree->root = root; - if(result) + + if(result) { *result = c; + } return tree->root; } @@ -165,12 +173,16 @@ static void splay_bottom_up(splay_tree_t *tree, splay_node_t *node) { while((parent = node->parent)) { if(!(grandparent = parent->parent)) { /* zig */ if(node == parent->left) { - if((parent->left = node->right)) + if((parent->left = node->right)) { parent->left->parent = parent; + } + node->right = parent; } else { - if((parent->right = node->left)) + if((parent->right = node->left)) { parent->right->parent = parent; + } + node->left = parent; } @@ -180,52 +192,69 @@ static void splay_bottom_up(splay_tree_t *tree, splay_node_t *node) { greatgrandparent = grandparent->parent; if(node == parent->left && parent == grandparent->left) { /* left zig-zig */ - if((grandparent->left = parent->right)) + if((grandparent->left = parent->right)) { grandparent->left->parent = grandparent; + } + parent->right = grandparent; grandparent->parent = parent; - if((parent->left = node->right)) + if((parent->left = node->right)) { parent->left->parent = parent; + } + node->right = parent; parent->parent = node; } else if(node == parent->right && parent == grandparent->right) { /* right zig-zig */ - if((grandparent->right = parent->left)) + if((grandparent->right = parent->left)) { grandparent->right->parent = grandparent; + } + parent->left = grandparent; grandparent->parent = parent; - if((parent->right = node->left)) + if((parent->right = node->left)) { parent->right->parent = parent; + } + node->left = parent; parent->parent = node; } else if(node == parent->right && parent == grandparent->left) { /* left-right zig-zag */ - if((parent->right = node->left)) + if((parent->right = node->left)) { parent->right->parent = parent; + } + node->left = parent; parent->parent = node; - if((grandparent->left = node->right)) + if((grandparent->left = node->right)) { grandparent->left->parent = grandparent; + } + node->right = grandparent; grandparent->parent = node; } else { /* right-left zig-zag */ - if((parent->left = node->right)) + if((parent->left = node->right)) { parent->left->parent = parent; + } + node->right = parent; parent->parent = node; - if((grandparent->right = node->left)) + if((grandparent->right = node->left)) { grandparent->right->parent = grandparent; + } + node->left = grandparent; grandparent->parent = node; } if((node->parent = greatgrandparent)) { - if(grandparent == greatgrandparent->left) + if(grandparent == greatgrandparent->left) { greatgrandparent->left = node; - else + } else { greatgrandparent->right = node; + } } } } @@ -254,8 +283,9 @@ splay_node_t *splay_alloc_node(void) { } void splay_free_node(splay_tree_t *tree, splay_node_t *node) { - if(node->data && tree->delete) + if(node->data && tree->delete) { tree->delete(node->data); + } free(node); } @@ -310,8 +340,10 @@ splay_node_t *splay_search_closest_node_nosplay(const splay_tree_t *tree, const node = tree->root; if(!node) { - if(result) + if(result) { *result = 0; + } + return NULL; } @@ -319,22 +351,26 @@ splay_node_t *splay_search_closest_node_nosplay(const splay_tree_t *tree, const c = tree->compare(data, node->data); if(c < 0) { - if(node->left) + if(node->left) { node = node->left; - else + } else { break; + } } else if(c > 0) { - if(node->right) + if(node->right) { node = node->right; - else + } else { break; + } } else { break; } } - if(result) + if(result) { *result = c; + } + return node; } @@ -348,8 +384,9 @@ splay_node_t *splay_search_closest_smaller_node(splay_tree_t *tree, const void * node = splay_search_closest_node(tree, data, &result); - if(result < 0) + if(result < 0) { node = node->prev; + } return node; } @@ -360,8 +397,9 @@ splay_node_t *splay_search_closest_greater_node(splay_tree_t *tree, const void * node = splay_search_closest_node(tree, data, &result); - if(result > 0) + if(result > 0) { node = node->next; + } return node; } @@ -379,16 +417,18 @@ splay_node_t *splay_insert(splay_tree_t *tree, void *data) { } else { closest = splay_search_closest_node(tree, data, &result); - if(!result) + if(!result) { return NULL; + } new = splay_alloc_node(); new->data = data; - if(result < 0) + if(result < 0) { splay_insert_before(tree, closest, new); - else + } else { splay_insert_after(tree, closest, new); + } } return new; @@ -400,18 +440,20 @@ splay_node_t *splay_insert_node(splay_tree_t *tree, splay_node_t *node) { node->left = node->right = node->parent = node->next = node->prev = NULL; - if(!tree->root) + if(!tree->root) { splay_insert_top(tree, node); - else { + } else { closest = splay_search_closest_node(tree, node->data, &result); - if(!result) + if(!result) { return NULL; + } - if(result < 0) + if(result < 0) { splay_insert_before(tree, closest, node); - else + } else { splay_insert_after(tree, closest, node); + } } return node; @@ -425,26 +467,34 @@ void splay_insert_top(splay_tree_t *tree, splay_node_t *node) { void splay_insert_before(splay_tree_t *tree, splay_node_t *before, splay_node_t *node) { if(!before) { - if(tree->tail) + if(tree->tail) { splay_insert_after(tree, tree->tail, node); - else + } else { splay_insert_top(tree, node); + } + return; } node->next = before; - if((node->prev = before->prev)) + + if((node->prev = before->prev)) { before->prev->next = node; - else + } else { tree->head = node; + } + before->prev = node; splay_bottom_up(tree, before); node->right = before; before->parent = node; - if((node->left = before->left)) + + if((node->left = before->left)) { before->left->parent = node; + } + before->left = NULL; node->parent = NULL; @@ -454,26 +504,34 @@ void splay_insert_before(splay_tree_t *tree, splay_node_t *before, splay_node_t void splay_insert_after(splay_tree_t *tree, splay_node_t *after, splay_node_t *node) { if(!after) { - if(tree->head) + if(tree->head) { splay_insert_before(tree, tree->head, node); - else + } else { splay_insert_top(tree, node); + } + return; } node->prev = after; - if((node->next = after->next)) + + if((node->next = after->next)) { after->next->prev = node; - else + } else { tree->tail = node; + } + after->next = node; splay_bottom_up(tree, after); node->left = after; after->parent = node; - if((node->right = after->right)) + + if((node->right = after->right)) { after->right->parent = node; + } + after->right = NULL; node->parent = NULL; @@ -486,30 +544,35 @@ splay_node_t *splay_unlink(splay_tree_t *tree, void *data) { node = splay_search_node(tree, data); - if(node) + if(node) { splay_unlink_node(tree, node); + } return node; } void splay_unlink_node(splay_tree_t *tree, splay_node_t *node) { - if(node->prev) + if(node->prev) { node->prev->next = node->next; - else + } else { tree->head = node->next; + } - if(node->next) + if(node->next) { node->next->prev = node->prev; - else + } else { tree->tail = node->prev; + } splay_bottom_up(tree, node); if(node->prev) { node->left->parent = NULL; tree->root = node->left; - if((node->prev->right = node->right)) + + if((node->prev->right = node->right)) { node->right->parent = node->prev; + } } else if(node->next) { tree->root = node->right; node->right->parent = NULL; @@ -530,8 +593,9 @@ void splay_delete(splay_tree_t *tree, void *data) { node = splay_search_node(tree, data); - if(node) + if(node) { splay_delete_node(tree, node); + } } /* Fast tree cleanup */ diff --git a/src/splay_tree.h b/src/splay_tree.h index d360fc3..9dd749d 100644 --- a/src/splay_tree.h +++ b/src/splay_tree.h @@ -63,10 +63,10 @@ typedef struct splay_tree_t { /* (De)constructors */ -extern splay_tree_t *splay_alloc_tree(splay_compare_t, splay_action_t) __attribute__ ((__malloc__)); +extern splay_tree_t *splay_alloc_tree(splay_compare_t, splay_action_t) __attribute__((__malloc__)); extern void splay_free_tree(splay_tree_t *); -extern splay_node_t *splay_alloc_node(void) __attribute__ ((__malloc__)); +extern splay_node_t *splay_alloc_node(void) __attribute__((__malloc__)); extern void splay_free_node(splay_tree_t *tree, splay_node_t *); /* Insertion and deletion */ diff --git a/src/sptps.c b/src/sptps.c index 2d02b66..93a7ad3 100644 --- a/src/sptps.c +++ b/src/sptps.c @@ -103,8 +103,9 @@ static bool send_record_priv_datagram(sptps_t *s, uint8_t type, const void *data } // Send a record (private version, accepts all record types, handles encryption and authentication). static bool send_record_priv(sptps_t *s, uint8_t type, const void *data, uint16_t len) { - if(s->datagram) + if(s->datagram) { return send_record_priv_datagram(s, type, data, len); + } char buffer[len + 19UL]; @@ -130,11 +131,13 @@ static bool send_record_priv(sptps_t *s, uint8_t type, const void *data, uint16_ bool sptps_send_record(sptps_t *s, uint8_t type, const void *data, uint16_t len) { // Sanity checks: application cannot send data before handshake is finished, // and only record types 0..127 are allowed. - if(!s->outstate) + if(!s->outstate) { return error(s, EINVAL, "Handshake phase not finished yet"); + } - if(type >= SPTPS_HANDSHAKE) + if(type >= SPTPS_HANDSHAKE) { return error(s, EINVAL, "Invalid application record type"); + } return send_record_priv(s, type, data, len); } @@ -144,11 +147,15 @@ static bool send_kex(sptps_t *s) { size_t keylen = ECDH_SIZE; // Make room for our KEX message, which we will keep around since send_sig() needs it. - if(s->mykex) + if(s->mykex) { return false; + } + s->mykex = realloc(s->mykex, 1 + 32 + keylen); - if(!s->mykex) + + if(!s->mykex) { return error(s, errno, strerror(errno)); + } // Set version byte to zero. s->mykex[0] = SPTPS_VERSION; @@ -157,8 +164,9 @@ static bool send_kex(sptps_t *s) { randomize(s->mykex + 1, 32); // Create a new ECDH public key. - if(!(s->ecdh = ecdh_generate_public(s->mykex + 1 + 32))) + if(!(s->ecdh = ecdh_generate_public(s->mykex + 1 + 32))) { return error(s, EINVAL, "Failed to generate ECDH public key"); + } return send_record_priv(s, SPTPS_HANDSHAKE, s->mykex, 1 + 32 + keylen); } @@ -178,8 +186,9 @@ static bool send_sig(sptps_t *s) { memcpy(msg + 1 + 2 * (33 + keylen), s->label, s->labellen); // Sign the result. - if(!ecdsa_sign(s->mykey, msg, sizeof(msg), sig)) + if(!ecdsa_sign(s->mykey, msg, sizeof(msg), sig)) { return error(s, EINVAL, "Failed to sign SIG record"); + } // Send the SIG exchange record. return send_record_priv(s, SPTPS_HANDSHAKE, sig, sizeof(sig)); @@ -191,20 +200,25 @@ static bool generate_key_material(sptps_t *s, const char *shared, size_t len) { if(!s->outstate) { s->incipher = chacha_poly1305_init(); s->outcipher = chacha_poly1305_init(); - if(!s->incipher || !s->outcipher) + + if(!s->incipher || !s->outcipher) { return error(s, EINVAL, "Failed to open cipher"); + } } // Allocate memory for key material size_t keylen = 2 * CHACHA_POLY1305_KEYLEN; s->key = realloc(s->key, keylen); - if(!s->key) + + if(!s->key) { return error(s, errno, strerror(errno)); + } // Create the HMAC seed, which is "key expansion" + session label + server nonce + client nonce char seed[s->labellen + 64 + 13]; memcpy(seed, "key expansion", 13); + if(s->initiator) { memcpy(seed + 13, s->mykex + 1, 32); memcpy(seed + 45, s->hiskex + 1, 32); @@ -212,11 +226,13 @@ static bool generate_key_material(sptps_t *s, const char *shared, size_t len) { memcpy(seed + 13, s->hiskex + 1, 32); memcpy(seed + 45, s->mykex + 1, 32); } + memcpy(seed + 77, s->label, s->labellen); // Use PRF to generate the key material - if(!prf(shared, len, seed, s->labellen + 64 + 13, s->key, keylen)) + if(!prf(shared, len, seed, s->labellen + 64 + 13, s->key, keylen)) { return error(s, EINVAL, "Failed to generate key material"); + } return true; } @@ -228,15 +244,18 @@ static bool send_ack(sptps_t *s) { // Receive an ACKnowledgement record. static bool receive_ack(sptps_t *s, const char *data, uint16_t len) { - if(len) + if(len) { return error(s, EIO, "Invalid ACK record length"); + } if(s->initiator) { - if(!chacha_poly1305_set_key(s->incipher, s->key)) + if(!chacha_poly1305_set_key(s->incipher, s->key)) { return error(s, EINVAL, "Failed to set counter"); + } } else { - if(!chacha_poly1305_set_key(s->incipher, s->key + CHACHA_POLY1305_KEYLEN)) + if(!chacha_poly1305_set_key(s->incipher, s->key + CHACHA_POLY1305_KEYLEN)) { return error(s, EINVAL, "Failed to set counter"); + } } free(s->key); @@ -249,17 +268,22 @@ static bool receive_ack(sptps_t *s, const char *data, uint16_t len) { // Receive a Key EXchange record, respond by sending a SIG record. static bool receive_kex(sptps_t *s, const char *data, uint16_t len) { // Verify length of the HELLO record - if(len != 1 + 32 + ECDH_SIZE) + if(len != 1 + 32 + ECDH_SIZE) { return error(s, EIO, "Invalid KEX record length"); + } // Ignore version number for now. // Make a copy of the KEX message, send_sig() and receive_sig() need it - if(s->hiskex) + if(s->hiskex) { return error(s, EINVAL, "Received a second KEX message before first has been processed"); + } + s->hiskex = realloc(s->hiskex, len); - if(!s->hiskex) + + if(!s->hiskex) { return error(s, errno, strerror(errno)); + } memcpy(s->hiskex, data, len); @@ -272,8 +296,9 @@ static bool receive_sig(sptps_t *s, const char *data, uint16_t len) { size_t siglen = ecdsa_size(s->hiskey); // Verify length of KEX record. - if(len != siglen) + if(len != siglen) { return error(s, EIO, "Invalid KEX record length"); + } // Concatenate both KEX messages, plus tag indicating if it is from the connection originator char msg[(1 + 32 + keylen) * 2 + 1 + s->labellen]; @@ -284,18 +309,23 @@ static bool receive_sig(sptps_t *s, const char *data, uint16_t len) { memcpy(msg + 1 + 2 * (33 + keylen), s->label, s->labellen); // Verify signature. - if(!ecdsa_verify(s->hiskey, msg, sizeof(msg), data)) + if(!ecdsa_verify(s->hiskey, msg, sizeof(msg), data)) { return error(s, EIO, "Failed to verify SIG record"); + } // Compute shared secret. char shared[ECDH_SHARED_SIZE]; - if(!ecdh_compute_shared(s->ecdh, s->hiskex + 1 + 32, shared)) + + if(!ecdh_compute_shared(s->ecdh, s->hiskex + 1 + 32, shared)) { return error(s, EINVAL, "Failed to compute ECDH shared secret"); + } + s->ecdh = NULL; // Generate key material from shared secret. - if(!generate_key_material(s, shared, sizeof(shared))) + if(!generate_key_material(s, shared, sizeof(shared))) { return false; + } free(s->mykex); free(s->hiskex); @@ -304,16 +334,19 @@ static bool receive_sig(sptps_t *s, const char *data, uint16_t len) { s->hiskex = NULL; // Send cipher change record - if(s->outstate && !send_ack(s)) + if(s->outstate && !send_ack(s)) { return false; + } // TODO: only set new keys after ACK has been set/received if(s->initiator) { - if(!chacha_poly1305_set_key(s->outcipher, s->key + CHACHA_POLY1305_KEYLEN)) + if(!chacha_poly1305_set_key(s->outcipher, s->key + CHACHA_POLY1305_KEYLEN)) { return error(s, EINVAL, "Failed to set key"); + } } else { - if(!chacha_poly1305_set_key(s->outcipher, s->key)) + if(!chacha_poly1305_set_key(s->outcipher, s->key)) { return error(s, EINVAL, "Failed to set key"); + } } return true; @@ -321,8 +354,9 @@ static bool receive_sig(sptps_t *s, const char *data, uint16_t len) { // Force another Key EXchange (for testing purposes). bool sptps_force_kex(sptps_t *s) { - if(!s->outstate || s->state != SPTPS_SECONDARY_KEX) + if(!s->outstate || s->state != SPTPS_SECONDARY_KEX) { return error(s, EINVAL, "Cannot force KEX in current state"); + } s->state = SPTPS_KEX; return send_kex(s); @@ -332,41 +366,59 @@ bool sptps_force_kex(sptps_t *s) { static bool receive_handshake(sptps_t *s, const char *data, uint16_t len) { // Only a few states to deal with handshaking. switch(s->state) { - case SPTPS_SECONDARY_KEX: - // We receive a secondary KEX request, first respond by sending our own. - if(!send_kex(s)) - return false; - case SPTPS_KEX: - // We have sent our KEX request, we expect our peer to sent one as well. - if(!receive_kex(s, data, len)) - return false; - s->state = SPTPS_SIG; - return true; - case SPTPS_SIG: - // If we already sent our secondary public ECDH key, we expect the peer to send his. - if(!receive_sig(s, data, len)) + case SPTPS_SECONDARY_KEX: + + // We receive a secondary KEX request, first respond by sending our own. + if(!send_kex(s)) { + return false; + } + + case SPTPS_KEX: + + // We have sent our KEX request, we expect our peer to sent one as well. + if(!receive_kex(s, data, len)) { + return false; + } + + s->state = SPTPS_SIG; + return true; + + case SPTPS_SIG: + + // If we already sent our secondary public ECDH key, we expect the peer to send his. + if(!receive_sig(s, data, len)) { + return false; + } + + if(s->outstate) { + s->state = SPTPS_ACK; + } else { + s->outstate = true; + + if(!receive_ack(s, NULL, 0)) { return false; - if(s->outstate) - s->state = SPTPS_ACK; - else { - s->outstate = true; - if(!receive_ack(s, NULL, 0)) - return false; - s->receive_record(s->handle, SPTPS_HANDSHAKE, NULL, 0); - s->state = SPTPS_SECONDARY_KEX; } - return true; - case SPTPS_ACK: - // We expect a handshake message to indicate transition to the new keys. - if(!receive_ack(s, data, len)) - return false; s->receive_record(s->handle, SPTPS_HANDSHAKE, NULL, 0); s->state = SPTPS_SECONDARY_KEX; - return true; - // TODO: split ACK into a VERify and ACK? - default: - return error(s, EIO, "Invalid session state %d", s->state); + } + + return true; + + case SPTPS_ACK: + + // We expect a handshake message to indicate transition to the new keys. + if(!receive_ack(s, data, len)) { + return false; + } + + s->receive_record(s->handle, SPTPS_HANDSHAKE, NULL, 0); + s->state = SPTPS_SECONDARY_KEX; + return true; + + // TODO: split ACK into a VERify and ACK? + default: + return error(s, EIO, "Invalid session state %d", s->state); } } @@ -381,44 +433,54 @@ static bool sptps_check_seqno(sptps_t *s, uint32_t seqno, bool update_state) { if(seqno >= s->inseqno + s->replaywin * 8) { // Prevent packets that jump far ahead of the queue from causing many others to be dropped. bool farfuture = s->farfuture < s->replaywin >> 2; - if (update_state) + + if(update_state) { s->farfuture++; - if(farfuture) + } + + if(farfuture) { return update_state ? error(s, EIO, "Packet is %d seqs in the future, dropped (%u)\n", seqno - s->inseqno, s->farfuture) : false; + } // Unless we have seen lots of them, in which case we consider the others lost. - if(update_state) + if(update_state) { warning(s, "Lost %d packets\n", seqno - s->inseqno); - if (update_state) { + } + + if(update_state) { // Mark all packets in the replay window as being late. memset(s->late, 255, s->replaywin); } - } else if (seqno < s->inseqno) { + } else if(seqno < s->inseqno) { // If the sequence number is farther in the past than the bitmap goes, or if the packet was already received, drop it. - if((s->inseqno >= s->replaywin * 8 && seqno < s->inseqno - s->replaywin * 8) || !(s->late[(seqno / 8) % s->replaywin] & (1 << seqno % 8))) + if((s->inseqno >= s->replaywin * 8 && seqno < s->inseqno - s->replaywin * 8) || !(s->late[(seqno / 8) % s->replaywin] & (1 << seqno % 8))) { return update_state ? error(s, EIO, "Received late or replayed packet, seqno %d, last received %d\n", seqno, s->inseqno) : false; - } else if (update_state) { + } + } else if(update_state) { // We missed some packets. Mark them in the bitmap as being late. - for(int i = s->inseqno; i < seqno; i++) + for(int i = s->inseqno; i < seqno; i++) { s->late[(i / 8) % s->replaywin] |= 1 << i % 8; + } } } - if (update_state) { + if(update_state) { // Mark the current packet as not being late. s->late[(seqno / 8) % s->replaywin] &= ~(1 << seqno % 8); s->farfuture = 0; } } - if (update_state) { - if(seqno >= s->inseqno) + if(update_state) { + if(seqno >= s->inseqno) { s->inseqno = seqno + 1; + } - if(!s->inseqno) + if(!s->inseqno) { s->received = 0; - else + } else { s->received++; + } } return true; @@ -426,14 +488,17 @@ static bool sptps_check_seqno(sptps_t *s, uint32_t seqno, bool update_state) { // Check datagram for valid HMAC bool sptps_verify_datagram(sptps_t *s, const void *data, size_t len) { - if(!s->instate || len < 21) + if(!s->instate || len < 21) { return error(s, EIO, "Received short packet"); + } uint32_t seqno; memcpy(&seqno, data, 4); seqno = ntohl(seqno); - if (!sptps_check_seqno(s, seqno, false)) + + if(!sptps_check_seqno(s, seqno, false)) { return false; + } char buffer[len]; size_t outlen; @@ -442,24 +507,29 @@ bool sptps_verify_datagram(sptps_t *s, const void *data, size_t len) { // Receive incoming data, datagram version. static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len) { - if(len < (s->instate ? 21 : 5)) + if(len < (s->instate ? 21 : 5)) { return error(s, EIO, "Received short packet"); + } uint32_t seqno; memcpy(&seqno, data, 4); seqno = ntohl(seqno); - data += 4; len -= 4; + data += 4; + len -= 4; if(!s->instate) { - if(seqno != s->inseqno) + if(seqno != s->inseqno) { return error(s, EIO, "Invalid packet seqno: %d != %d", seqno, s->inseqno); + } s->inseqno = seqno + 1; - uint8_t type = *(data++); len--; + uint8_t type = *(data++); + len--; - if(type != SPTPS_HANDSHAKE) + if(type != SPTPS_HANDSHAKE) { return error(s, EIO, "Application record received before handshake finished"); + } return receive_handshake(s, data, len); } @@ -468,11 +538,14 @@ static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len char buffer[len]; size_t outlen; - if(!chacha_poly1305_decrypt(s->incipher, seqno, data, len, buffer, &outlen)) + + if(!chacha_poly1305_decrypt(s->incipher, seqno, data, len, buffer, &outlen)) { return error(s, EIO, "Failed to decrypt and verify packet"); + } - if(!sptps_check_seqno(s, seqno, true)) + if(!sptps_check_seqno(s, seqno, true)) { return false; + } // Append a NULL byte for safety. buffer[outlen] = 0; @@ -480,16 +553,21 @@ static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len data = buffer; len = outlen; - uint8_t type = *(data++); len--; + uint8_t type = *(data++); + len--; if(type < SPTPS_HANDSHAKE) { - if(!s->instate) + if(!s->instate) { return error(s, EIO, "Application record received before handshake finished"); - if(!s->receive_record(s->handle, type, data, len)) + } + + if(!s->receive_record(s->handle, type, data, len)) { return false; + } } else if(type == SPTPS_HANDSHAKE) { - if(!receive_handshake(s, data, len)) + if(!receive_handshake(s, data, len)) { return false; + } } else { return error(s, EIO, "Invalid record type %d", type); } @@ -501,17 +579,21 @@ static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len size_t sptps_receive_data(sptps_t *s, const void *data, size_t len) { size_t total_read = 0; - if(!s->state) + if(!s->state) { return error(s, EIO, "Invalid session state zero"); + } - if(s->datagram) + if(s->datagram) { return sptps_receive_data_datagram(s, data, len) ? len : false; + } // First read the 2 length bytes. if(s->buflen < 2) { size_t toread = 2 - s->buflen; - if(toread > len) + + if(toread > len) { toread = len; + } memcpy(s->inbuf + s->buflen, data, toread); @@ -521,8 +603,9 @@ size_t sptps_receive_data(sptps_t *s, const void *data, size_t len) { data += toread; // Exit early if we don't have the full length. - if(s->buflen < 2) + if(s->buflen < 2) { return total_read; + } // Get the length bytes @@ -531,26 +614,32 @@ size_t sptps_receive_data(sptps_t *s, const void *data, size_t len) { // If we have the length bytes, ensure our buffer can hold the whole request. s->inbuf = realloc(s->inbuf, s->reclen + 19UL); - if(!s->inbuf) + + if(!s->inbuf) { return error(s, errno, strerror(errno)); + } // Exit early if we have no more data to process. - if(!len) + if(!len) { return total_read; + } } // Read up to the end of the record. size_t toread = s->reclen + (s->instate ? 19UL : 3UL) - s->buflen; - if(toread > len) + + if(toread > len) { toread = len; + } memcpy(s->inbuf + s->buflen, data, toread); total_read += toread; s->buflen += toread; // If we don't have a whole record, exit. - if(s->buflen < s->reclen + (s->instate ? 19UL : 3UL)) + if(s->buflen < s->reclen + (s->instate ? 19UL : 3UL)) { return total_read; + } // Update sequence number. @@ -558,8 +647,9 @@ size_t sptps_receive_data(sptps_t *s, const void *data, size_t len) { // Check HMAC and decrypt. if(s->instate) { - if(!chacha_poly1305_decrypt(s->incipher, seqno, s->inbuf + 2UL, s->reclen + 17UL, s->inbuf + 2UL, NULL)) + if(!chacha_poly1305_decrypt(s->incipher, seqno, s->inbuf + 2UL, s->reclen + 17UL, s->inbuf + 2UL, NULL)) { return error(s, EINVAL, "Failed to decrypt and verify record"); + } } // Append a NULL byte for safety. @@ -568,13 +658,17 @@ size_t sptps_receive_data(sptps_t *s, const void *data, size_t len) { uint8_t type = s->inbuf[2]; if(type < SPTPS_HANDSHAKE) { - if(!s->instate) + if(!s->instate) { return error(s, EIO, "Application record received before handshake finished"); - if(!s->receive_record(s->handle, type, s->inbuf + 3, s->reclen)) + } + + if(!s->receive_record(s->handle, type, s->inbuf + 3, s->reclen)) { return false; + } } else if(type == SPTPS_HANDSHAKE) { - if(!receive_handshake(s, s->inbuf + 3, s->reclen)) + if(!receive_handshake(s, s->inbuf + 3, s->reclen)) { return false; + } } else { return error(s, EIO, "Invalid record type %d", type); } @@ -595,21 +689,30 @@ bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_ s->mykey = mykey; s->hiskey = hiskey; s->replaywin = sptps_replaywin; + if(s->replaywin) { s->late = malloc(s->replaywin); - if(!s->late) + + if(!s->late) { return error(s, errno, strerror(errno)); + } + memset(s->late, 0, s->replaywin); } s->label = malloc(labellen); - if(!s->label) + + if(!s->label) { return error(s, errno, strerror(errno)); + } if(!datagram) { s->inbuf = malloc(7); - if(!s->inbuf) + + if(!s->inbuf) { return error(s, errno, strerror(errno)); + } + s->buflen = 0; } diff --git a/src/sptps_keypair.c b/src/sptps_keypair.c index fde8622..1bf2da0 100644 --- a/src/sptps_keypair.c +++ b/src/sptps_keypair.c @@ -38,8 +38,8 @@ void logger(int level, int priority, const char *format, ...) { static void usage() { fprintf(stderr, "Usage: %s [options] private_key_file public_key_file\n\n", program_name); fprintf(stderr, "Valid options are:\n" - " --help Display this help and exit.\n" - "\n"); + " --help Display this help and exit.\n" + "\n"); fprintf(stderr, "Report bugs to tinc@tinc-vpn.org.\n"); } @@ -54,20 +54,20 @@ int main(int argc, char *argv[]) { int option_index = 0; while((r = getopt_long(argc, argv, "", long_options, &option_index)) != EOF) { - switch (r) { - case 0: /* long option */ - break; + switch(r) { + case 0: /* long option */ + break; - case '?': /* wrong options */ - usage(); - return 1; + case '?': /* wrong options */ + usage(); + return 1; - case 1: /* help */ - usage(); - return 0; + case 1: /* help */ + usage(); + return 0; - default: - break; + default: + break; } } @@ -83,15 +83,19 @@ int main(int argc, char *argv[]) { crypto_init(); ecdsa_t *key = ecdsa_generate(); - if(!key) + + if(!key) { return 1; - + } + FILE *fp = fopen(argv[1], "w"); + if(fp) { if(!ecdsa_write_pem_private_key(key, fp)) { fprintf(stderr, "Could not write ECDSA private key\n"); return 1; } + fclose(fp); } else { fprintf(stderr, "Could not open '%s' for writing: %s\n", argv[1], strerror(errno)); @@ -99,9 +103,12 @@ int main(int argc, char *argv[]) { } fp = fopen(argv[2], "w"); + if(fp) { - if(!ecdsa_write_pem_public_key(key, fp)) + if(!ecdsa_write_pem_public_key(key, fp)) { fprintf(stderr, "Could not write ECDSA public key\n"); + } + fclose(fp); } else { fprintf(stderr, "Could not open '%s' for writing: %s\n", argv[2], strerror(errno)); diff --git a/src/sptps_speed.c b/src/sptps_speed.c index ef97be7..db7314e 100644 --- a/src/sptps_speed.c +++ b/src/sptps_speed.c @@ -29,9 +29,13 @@ #include "sptps.h" // Symbols necessary to link with logger.o -bool send_request(void *c, const char *msg, ...) { return false; } +bool send_request(void *c, const char *msg, ...) { + return false; +} struct list_t *connection_list = NULL; -bool send_meta(void *c, const char *msg , int len) { return false; } +bool send_meta(void *c, const char *msg, int len) { + return false; +} char *logfilename = NULL; bool do_detach = false; struct timeval now; @@ -50,10 +54,14 @@ static void receive_data(sptps_t *sptps) { char buf[4096], *bufp = buf; int fd = *(int *)sptps->handle; size_t len = recv(fd, buf, sizeof(buf), 0); + while(len) { size_t done = sptps_receive_data(sptps, bufp, len); - if(!done) + + if(!done) { abort(); + } + bufp += done; len -= done; } @@ -73,8 +81,10 @@ static void clock_start() { static bool clock_countto(double seconds) { clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end); elapsed = end.tv_sec + end.tv_nsec * 1e-9 - start.tv_sec - start.tv_nsec * 1e-9; - if(elapsed < seconds) + + if(elapsed < seconds) { return ++count; + } rate = count / elapsed; return false; @@ -96,8 +106,11 @@ int main(int argc, char *argv[]) { // Key generation fprintf(stderr, "Generating keys for %lg seconds: ", duration); - for(clock_start(); clock_countto(duration);) + + for(clock_start(); clock_countto(duration);) { ecdsa_free(ecdsa_generate()); + } + fprintf(stderr, "%17.2lf op/s\n", rate); key1 = ecdsa_generate(); @@ -106,34 +119,46 @@ int main(int argc, char *argv[]) { // Ed25519 signatures fprintf(stderr, "Ed25519 sign for %lg seconds: ", duration); + for(clock_start(); clock_countto(duration);) - if(!ecdsa_sign(key1, buf1, 256, buf2)) + if(!ecdsa_sign(key1, buf1, 256, buf2)) { return 1; + } + fprintf(stderr, "%20.2lf op/s\n", rate); fprintf(stderr, "Ed25519 verify for %lg seconds: ", duration); + for(clock_start(); clock_countto(duration);) if(!ecdsa_verify(key1, buf1, 256, buf2)) { fprintf(stderr, "Signature verification failed\n"); return 1; } + fprintf(stderr, "%18.2lf op/s\n", rate); ecdh1 = ecdh_generate_public(buf1); fprintf(stderr, "ECDH for %lg seconds: ", duration); + for(clock_start(); clock_countto(duration);) { ecdh2 = ecdh_generate_public(buf2); - if(!ecdh2) + + if(!ecdh2) { return 1; - if(!ecdh_compute_shared(ecdh2, buf1, buf3)) + } + + if(!ecdh_compute_shared(ecdh2, buf1, buf3)) { return 1; + } } + fprintf(stderr, "%28.2lf op/s\n", rate); ecdh_free(ecdh1); // SPTPS authentication phase int fd[2]; + if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) { fprintf(stderr, "Could not create a UNIX socket pair: %s\n", sockstrerror(sockerrno)); return 1; @@ -142,43 +167,62 @@ int main(int argc, char *argv[]) { struct pollfd pfd[2] = {{fd[0], POLLIN}, {fd[1], POLLIN}}; fprintf(stderr, "SPTPS/TCP authenticate for %lg seconds: ", duration); + for(clock_start(); clock_countto(duration);) { sptps_start(&sptps1, fd + 0, true, false, key1, key2, "sptps_speed", 11, send_data, receive_record); sptps_start(&sptps2, fd + 1, false, false, key2, key1, "sptps_speed", 11, send_data, receive_record); + while(poll(pfd, 2, 0)) { - if(pfd[0].revents) + if(pfd[0].revents) { receive_data(&sptps1); - if(pfd[1].revents) + } + + if(pfd[1].revents) { receive_data(&sptps2); + } } + sptps_stop(&sptps1); sptps_stop(&sptps2); } + fprintf(stderr, "%10.2lf op/s\n", rate * 2); // SPTPS data sptps_start(&sptps1, fd + 0, true, false, key1, key2, "sptps_speed", 11, send_data, receive_record); sptps_start(&sptps2, fd + 1, false, false, key2, key1, "sptps_speed", 11, send_data, receive_record); + while(poll(pfd, 2, 0)) { - if(pfd[0].revents) + if(pfd[0].revents) { receive_data(&sptps1); - if(pfd[1].revents) + } + + if(pfd[1].revents) { receive_data(&sptps2); + } } + fprintf(stderr, "SPTPS/TCP transmit for %lg seconds: ", duration); + for(clock_start(); clock_countto(duration);) { - if(!sptps_send_record(&sptps1, 0, buf1, 1451)) + if(!sptps_send_record(&sptps1, 0, buf1, 1451)) { abort(); + } + receive_data(&sptps2); } + rate *= 2 * 1451 * 8; - if(rate > 1e9) + + if(rate > 1e9) { fprintf(stderr, "%14.2lf Gbit/s\n", rate / 1e9); - else if(rate > 1e6) + } else if(rate > 1e6) { fprintf(stderr, "%14.2lf Mbit/s\n", rate / 1e6); - else if(rate > 1e3) + } else if(rate > 1e3) { fprintf(stderr, "%14.2lf kbit/s\n", rate / 1e3); + } + sptps_stop(&sptps1); sptps_stop(&sptps2); @@ -193,43 +237,62 @@ int main(int argc, char *argv[]) { } fprintf(stderr, "SPTPS/UDP authenticate for %lg seconds: ", duration); + for(clock_start(); clock_countto(duration);) { sptps_start(&sptps1, fd + 0, true, true, key1, key2, "sptps_speed", 11, send_data, receive_record); sptps_start(&sptps2, fd + 1, false, true, key2, key1, "sptps_speed", 11, send_data, receive_record); + while(poll(pfd, 2, 0)) { - if(pfd[0].revents) + if(pfd[0].revents) { receive_data(&sptps1); - if(pfd[1].revents) + } + + if(pfd[1].revents) { receive_data(&sptps2); + } } + sptps_stop(&sptps1); sptps_stop(&sptps2); } + fprintf(stderr, "%10.2lf op/s\n", rate * 2); // SPTPS datagram data sptps_start(&sptps1, fd + 0, true, true, key1, key2, "sptps_speed", 11, send_data, receive_record); sptps_start(&sptps2, fd + 1, false, true, key2, key1, "sptps_speed", 11, send_data, receive_record); + while(poll(pfd, 2, 0)) { - if(pfd[0].revents) + if(pfd[0].revents) { receive_data(&sptps1); - if(pfd[1].revents) + } + + if(pfd[1].revents) { receive_data(&sptps2); + } } + fprintf(stderr, "SPTPS/UDP transmit for %lg seconds: ", duration); + for(clock_start(); clock_countto(duration);) { - if(!sptps_send_record(&sptps1, 0, buf1, 1451)) + if(!sptps_send_record(&sptps1, 0, buf1, 1451)) { abort(); + } + receive_data(&sptps2); } + rate *= 2 * 1451 * 8; - if(rate > 1e9) + + if(rate > 1e9) { fprintf(stderr, "%14.2lf Gbit/s\n", rate / 1e9); - else if(rate > 1e6) + } else if(rate > 1e6) { fprintf(stderr, "%14.2lf Mbit/s\n", rate / 1e6); - else if(rate > 1e3) + } else if(rate > 1e3) { fprintf(stderr, "%14.2lf kbit/s\n", rate / 1e3); + } + sptps_stop(&sptps1); sptps_stop(&sptps2); diff --git a/src/sptps_test.c b/src/sptps_test.c index e7dcea2..9b7c289 100644 --- a/src/sptps_test.c +++ b/src/sptps_test.c @@ -31,9 +31,13 @@ #include "utils.h" // Symbols necessary to link with logger.o -bool send_request(void *c, const char *msg, ...) { return false; } +bool send_request(void *c, const char *msg, ...) { + return false; +} struct list_t *connection_list = NULL; -bool send_meta(void *c, const char *msg , int len) { return false; } +bool send_meta(void *c, const char *msg, int len) { + return false; +} char *logfilename = NULL; bool do_detach = false; struct timeval now; @@ -49,19 +53,29 @@ static int addressfamily = AF_UNSPEC; static bool send_data(void *handle, uint8_t type, const void *data, size_t len) { char hex[len * 2 + 1]; bin2hex(data, hex, len); - if(verbose) + + if(verbose) { fprintf(stderr, "Sending %d bytes of data:\n%s\n", (int)len, hex); + } + const int *sock = handle; - if(send(*sock, data, len, 0) != len) + + if(send(*sock, data, len, 0) != len) { return false; + } + return true; } static bool receive_record(void *handle, uint8_t type, const void *data, uint16_t len) { - if(verbose) + if(verbose) { fprintf(stderr, "Received type %d record of %u bytes:\n", type, len); - if(!writeonly) + } + + if(!writeonly) { write(out, data, len); + } + return true; } @@ -83,20 +97,20 @@ const char *program_name; static void usage() { fprintf(stderr, "Usage: %s [options] my_ed25519_key_file his_ed25519_key_file [host] port\n\n", program_name); fprintf(stderr, "Valid options are:\n" - " -d, --datagram Enable datagram mode.\n" - " -q, --quit Quit when EOF occurs on stdin.\n" - " -r, --readonly Only send data from the socket to stdout.\n" + " -d, --datagram Enable datagram mode.\n" + " -q, --quit Quit when EOF occurs on stdin.\n" + " -r, --readonly Only send data from the socket to stdout.\n" #ifdef HAVE_LINUX - " -t, --tun Use a tun device instead of stdio.\n" + " -t, --tun Use a tun device instead of stdio.\n" #endif - " -w, --writeonly Only send data from stdin to the socket.\n" - " -L, --packet-loss RATE Fake packet loss of RATE percent.\n" - " -R, --replay-window N Set replay window to N bytes.\n" - " -s, --special Enable special handling of lines starting with #, ^ and $.\n" - " -v, --verbose Display debug messages.\n" - " -4 Use IPv4.\n" - " -6 Use IPv6.\n" - "\n"); + " -w, --writeonly Only send data from stdin to the socket.\n" + " -L, --packet-loss RATE Fake packet loss of RATE percent.\n" + " -R, --replay-window N Set replay window to N bytes.\n" + " -s, --special Enable special handling of lines starting with #, ^ and $.\n" + " -v, --verbose Display debug messages.\n" + " -4 Use IPv4.\n" + " -6 Use IPv6.\n" + "\n"); fprintf(stderr, "Report bugs to tinc@tinc-vpn.org.\n"); } @@ -114,70 +128,70 @@ int main(int argc, char *argv[]) { bool quit = false; while((r = getopt_long(argc, argv, "dqrstwL:W:v46", long_options, &option_index)) != EOF) { - switch (r) { - case 0: /* long option */ - break; + switch(r) { + case 0: /* long option */ + break; - case 'd': /* datagram mode */ - datagram = true; - break; + case 'd': /* datagram mode */ + datagram = true; + break; - case 'q': /* close connection on EOF from stdin */ - quit = true; - break; + case 'q': /* close connection on EOF from stdin */ + quit = true; + break; - case 'r': /* read only */ - readonly = true; - break; + case 'r': /* read only */ + readonly = true; + break; - case 't': /* read only */ + case 't': /* read only */ #ifdef HAVE_LINUX - tun = true; + tun = true; #else - fprintf(stderr, "--tun is only supported on Linux.\n"); - usage(); - return 1; + fprintf(stderr, "--tun is only supported on Linux.\n"); + usage(); + return 1; #endif - break; + break; - case 'w': /* write only */ - writeonly = true; - break; + case 'w': /* write only */ + writeonly = true; + break; - case 'L': /* packet loss rate */ - packetloss = atoi(optarg); - break; + case 'L': /* packet loss rate */ + packetloss = atoi(optarg); + break; - case 'W': /* replay window size */ - sptps_replaywin = atoi(optarg); - break; + case 'W': /* replay window size */ + sptps_replaywin = atoi(optarg); + break; - case 'v': /* be verbose */ - verbose = true; - break; + case 'v': /* be verbose */ + verbose = true; + break; - case 's': /* special character handling */ - special = true; - break; + case 's': /* special character handling */ + special = true; + break; - case '?': /* wrong options */ - usage(); - return 1; + case '?': /* wrong options */ + usage(); + return 1; - case '4': /* IPv4 */ - addressfamily = AF_INET; - break; + case '4': /* IPv4 */ + addressfamily = AF_INET; + break; - case '6': /* IPv6 */ - addressfamily = AF_INET6; - break; + case '6': /* IPv6 */ + addressfamily = AF_INET6; + break; - case 1: /* help */ - usage(); - return 0; + case 1: /* help */ + usage(); + return 0; - default: - break; + default: + break; } } @@ -190,34 +204,44 @@ int main(int argc, char *argv[]) { return 1; } - if(argc > 4) + if(argc > 4) { initiator = true; + } srand(time(NULL)); #ifdef HAVE_LINUX + if(tun) { in = out = open("/dev/net/tun", O_RDWR | O_NONBLOCK); + if(in < 0) { fprintf(stderr, "Could not open tun device: %s\n", strerror(errno)); return 1; } + struct ifreq ifr = { .ifr_flags = IFF_TUN }; + if(ioctl(in, TUNSETIFF, &ifr)) { fprintf(stderr, "Could not configure tun interface: %s\n", strerror(errno)); return 1; } + ifr.ifr_name[IFNAMSIZ - 1] = 0; fprintf(stderr, "Using tun interface %s\n", ifr.ifr_name); } + #endif #ifdef HAVE_MINGW static struct WSAData wsa_state; - if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) + + if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) { return 1; + } + #endif struct addrinfo *ai, hint; @@ -234,6 +258,7 @@ int main(int argc, char *argv[]) { } int sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if(sock < 0) { fprintf(stderr, "Could not create socket: %s\n", sockstrerror(sockerrno)); return 1; @@ -247,6 +272,7 @@ int main(int argc, char *argv[]) { fprintf(stderr, "Could not connect to peer: %s\n", sockstrerror(sockerrno)); return 1; } + fprintf(stderr, "Connected\n"); } else { if(bind(sock, ai->ai_addr, ai->ai_addrlen)) { @@ -259,9 +285,11 @@ int main(int argc, char *argv[]) { fprintf(stderr, "Could not listen on socket: %s\n", sockstrerror(sockerrno)); return 1; } + fprintf(stderr, "Listening...\n"); sock = accept(sock, NULL, NULL); + if(sock < 0) { fprintf(stderr, "Could not accept connection: %s\n", sockstrerror(sockerrno)); return 1; @@ -290,97 +318,133 @@ int main(int argc, char *argv[]) { crypto_init(); FILE *fp = fopen(argv[1], "r"); + if(!fp) { fprintf(stderr, "Could not open %s: %s\n", argv[1], strerror(errno)); return 1; } - if(!(mykey = ecdsa_read_pem_private_key(fp))) + + if(!(mykey = ecdsa_read_pem_private_key(fp))) { return 1; + } + fclose(fp); fp = fopen(argv[2], "r"); + if(!fp) { fprintf(stderr, "Could not open %s: %s\n", argv[2], strerror(errno)); return 1; } - if(!(hiskey = ecdsa_read_pem_public_key(fp))) + + if(!(hiskey = ecdsa_read_pem_public_key(fp))) { return 1; + } + fclose(fp); - if(verbose) + if(verbose) { fprintf(stderr, "Keys loaded\n"); + } sptps_t s; - if(!sptps_start(&s, &sock, initiator, datagram, mykey, hiskey, "sptps_test", 10, send_data, receive_record)) + + if(!sptps_start(&s, &sock, initiator, datagram, mykey, hiskey, "sptps_test", 10, send_data, receive_record)) { return 1; + } while(true) { - if(writeonly && readonly) + if(writeonly && readonly) { break; + } char buf[65535] = ""; fd_set fds; FD_ZERO(&fds); #ifndef HAVE_MINGW - if(!readonly && s.instate) + + if(!readonly && s.instate) { FD_SET(in, &fds); + } + #endif FD_SET(sock, &fds); - if(select(sock + 1, &fds, NULL, NULL, NULL) <= 0) + + if(select(sock + 1, &fds, NULL, NULL, NULL) <= 0) { return 1; + } if(FD_ISSET(in, &fds)) { ssize_t len = read(in, buf, sizeof(buf)); + if(len < 0) { fprintf(stderr, "Could not read from stdin: %s\n", strerror(errno)); return 1; } + if(len == 0) { - if(quit) + if(quit) { break; + } + readonly = true; continue; } - if(special && buf[0] == '#') + + if(special && buf[0] == '#') { s.outseqno = atoi(buf + 1); - if(special && buf[0] == '^') + } + + if(special && buf[0] == '^') { sptps_send_record(&s, SPTPS_HANDSHAKE, NULL, 0); - else if(special && buf[0] == '$') { + } else if(special && buf[0] == '$') { sptps_force_kex(&s); - if(len > 1) + + if(len > 1) { sptps_send_record(&s, 0, buf, len); - } else - if(!sptps_send_record(&s, buf[0] == '!' ? 1 : 0, buf, (len == 1 && buf[0] == '\n') ? 0 : buf[0] == '*' ? sizeof(buf) : len)) + } + } else if(!sptps_send_record(&s, buf[0] == '!' ? 1 : 0, buf, (len == 1 && buf[0] == '\n') ? 0 : buf[0] == '*' ? sizeof(buf) : len)) { return 1; + } } if(FD_ISSET(sock, &fds)) { ssize_t len = recv(sock, buf, sizeof(buf), 0); + if(len < 0) { fprintf(stderr, "Could not read from socket: %s\n", sockstrerror(sockerrno)); return 1; } + if(len == 0) { fprintf(stderr, "Connection terminated by peer.\n"); break; } + if(verbose) { char hex[len * 2 + 1]; bin2hex(buf, hex, len); fprintf(stderr, "Received %d bytes of data:\n%s\n", (int)len, hex); } + if(packetloss && (rand() % 100) < packetloss) { - if(verbose) + if(verbose) { fprintf(stderr, "Dropped.\n"); + } + continue; } + char *bufp = buf; + while(len) { size_t done = sptps_receive_data(&s, bufp, len); + if(!done) { - if(!datagram) + if(!datagram) { return 1; + } } else { break; } @@ -391,8 +455,9 @@ int main(int argc, char *argv[]) { } } - if(!sptps_stop(&s)) + if(!sptps_stop(&s)) { return 1; + } return 0; } diff --git a/src/subnet.c b/src/subnet.c index e72cdaa..4fefda6 100644 --- a/src/subnet.c +++ b/src/subnet.c @@ -92,15 +92,19 @@ void subnet_add(node_t *n, subnet_t *subnet) { subnet->owner = n; splay_insert(subnet_tree, subnet); - if (n) + + if(n) { splay_insert(n->subnet_tree, subnet); + } subnet_cache_flush(); } void subnet_del(node_t *n, subnet_t *subnet) { - if (n) + if(n) { splay_delete(n->subnet_tree, subnet); + } + splay_delete(subnet_tree, subnet); subnet_cache_flush(); @@ -117,26 +121,31 @@ subnet_t *lookup_subnet_mac(const node_t *owner, const mac_t *address) { // Check if this address is cached - if((r = hash_search(mac_cache, address))) + if((r = hash_search(mac_cache, address))) { return r; + } // Search all subnets for a matching one for splay_each(subnet_t, p, owner ? owner->subnet_tree : subnet_tree) { - if(!p || p->type != SUBNET_MAC) + if(!p || p->type != SUBNET_MAC) { continue; + } if(!memcmp(address, &p->net.mac.address, sizeof(*address))) { r = p; - if(!p->owner || p->owner->status.reachable) + + if(!p->owner || p->owner->status.reachable) { break; + } } } // Cache the result - if(r) + if(r) { hash_insert(mac_cache, address, r); + } return r; } @@ -146,26 +155,31 @@ subnet_t *lookup_subnet_ipv4(const ipv4_t *address) { // Check if this address is cached - if((r = hash_search(ipv4_cache, address))) + if((r = hash_search(ipv4_cache, address))) { return r; + } // Search all subnets for a matching one for splay_each(subnet_t, p, subnet_tree) { - if(!p || p->type != SUBNET_IPV4) + if(!p || p->type != SUBNET_IPV4) { continue; + } if(!maskcmp(address, &p->net.ipv4.address, p->net.ipv4.prefixlength)) { r = p; - if(!p->owner || p->owner->status.reachable) + + if(!p->owner || p->owner->status.reachable) { break; + } } } // Cache the result - if(r) + if(r) { hash_insert(ipv4_cache, address, r); + } return r; } @@ -175,26 +189,31 @@ subnet_t *lookup_subnet_ipv6(const ipv6_t *address) { // Check if this address is cached - if((r = hash_search(ipv6_cache, address))) + if((r = hash_search(ipv6_cache, address))) { return r; + } // Search all subnets for a matching one for splay_each(subnet_t, p, subnet_tree) { - if(!p || p->type != SUBNET_IPV6) + if(!p || p->type != SUBNET_IPV6) { continue; + } if(!maskcmp(address, &p->net.ipv6.address, p->net.ipv6.prefixlength)) { r = p; - if(!p->owner || p->owner->status.reachable) + + if(!p->owner || p->owner->status.reachable) { break; + } } } // Cache the result - if(r) + if(r) { hash_insert(ipv6_cache, address, r); + } return r; } @@ -225,15 +244,18 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) { if(!subnet) { for splay_each(subnet_t, subnet, owner->subnet_tree) { - if(!net2str(netstr, sizeof(netstr), subnet)) + if(!net2str(netstr, sizeof(netstr), subnet)) { continue; + } // Strip the weight from the subnet, and put it in its own environment variable char *weight = strchr(netstr, '#'); - if(weight) + + if(weight) { *weight++ = 0; - else + } else { weight = empty; + } // Prepare the SUBNET and WEIGHT variables environment_update(&env, env_subnet, "SUBNET=%s", netstr); @@ -245,10 +267,12 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) { if(net2str(netstr, sizeof(netstr), subnet)) { // Strip the weight from the subnet, and put it in its own environment variable char *weight = strchr(netstr, '#'); - if(weight) + + if(weight) { *weight++ = 0; - else + } else { weight = empty; + } // Prepare the SUBNET and WEIGHT variables environment_update(&env, env_subnet, "SUBNET=%s", netstr); @@ -265,12 +289,13 @@ bool dump_subnets(connection_t *c) { for splay_each(subnet_t, subnet, subnet_tree) { char netstr[MAXNETSTR]; - if(!net2str(netstr, sizeof(netstr), subnet)) + if(!net2str(netstr, sizeof(netstr), subnet)) { continue; + } send_request(c, "%d %d %s %s", - CONTROL, REQ_DUMP_SUBNETS, - netstr, subnet->owner ? subnet->owner->name : "(broadcast)"); + CONTROL, REQ_DUMP_SUBNETS, + netstr, subnet->owner ? subnet->owner->name : "(broadcast)"); } return send_request(c, "%d %d", CONTROL, REQ_DUMP_SUBNETS); diff --git a/src/subnet.h b/src/subnet.h index 5bd5ff0..4ba10e9 100644 --- a/src/subnet.h +++ b/src/subnet.h @@ -66,11 +66,11 @@ typedef struct subnet_t { extern splay_tree_t *subnet_tree; extern int subnet_compare(const struct subnet_t *, const struct subnet_t *); -extern subnet_t *new_subnet(void) __attribute__ ((__malloc__)); +extern subnet_t *new_subnet(void) __attribute__((__malloc__)); extern void free_subnet(subnet_t *); extern void init_subnets(void); extern void exit_subnets(void); -extern splay_tree_t *new_subnet_tree(void) __attribute__ ((__malloc__)); +extern splay_tree_t *new_subnet_tree(void) __attribute__((__malloc__)); extern void free_subnet_tree(splay_tree_t *); extern void subnet_add(struct node_t *, subnet_t *); extern void subnet_del(struct node_t *, subnet_t *); diff --git a/src/subnet_parse.c b/src/subnet_parse.c index ca17dce..c54d343 100644 --- a/src/subnet_parse.c +++ b/src/subnet_parse.c @@ -39,13 +39,15 @@ int maskcmp(const void *va, const void *vb, int masklen) { for(m = masklen, i = 0; m >= 8; m -= 8, i++) { result = a[i] - b[i]; - if(result) + + if(result) { return result; + } } if(m) return (a[i] & (0x100 - (1 << (8 - m)))) - - (b[i] & (0x100 - (1 << (8 - m)))); + (b[i] & (0x100 - (1 << (8 - m)))); return 0; } @@ -57,11 +59,13 @@ void mask(void *va, int masklen, int len) { i = masklen / 8; masklen %= 8; - if(masklen) + if(masklen) { a[i++] &= (0x100 - (1 << (8 - masklen))); + } - for(; i < len; i++) + for(; i < len; i++) { a[i] = 0; + } } void maskcpy(void *va, const void *vb, int masklen, int len) { @@ -69,16 +73,18 @@ void maskcpy(void *va, const void *vb, int masklen, int len) { char *a = va; const char *b = vb; - for(m = masklen, i = 0; m >= 8; m -= 8, i++) + for(m = masklen, i = 0; m >= 8; m -= 8, i++) { a[i] = b[i]; + } if(m) { a[i] = b[i] & (0x100 - (1 << (8 - m))); i++; } - for(; i < len; i++) + for(; i < len; i++) { a[i] = 0; + } } bool maskcheck(const void *va, int masklen, int len) { @@ -88,12 +94,14 @@ bool maskcheck(const void *va, int masklen, int len) { i = masklen / 8; masklen %= 8; - if(masklen && a[i++] & (0xff >> masklen)) + if(masklen && a[i++] & (0xff >> masklen)) { return false; + } for(; i < len; i++) - if(a[i] != 0) + if(a[i] != 0) { return false; + } return true; } @@ -105,13 +113,15 @@ static int subnet_compare_mac(const subnet_t *a, const subnet_t *b) { result = memcmp(&a->net.mac.address, &b->net.mac.address, sizeof(a->net.mac.address)); - if(result) + if(result) { return result; + } result = a->weight - b->weight; - if(result || !a->owner || !b->owner) + if(result || !a->owner || !b->owner) { return result; + } return strcmp(a->owner->name, b->owner->name); } @@ -121,18 +131,21 @@ static int subnet_compare_ipv4(const subnet_t *a, const subnet_t *b) { result = b->net.ipv4.prefixlength - a->net.ipv4.prefixlength; - if(result) + if(result) { return result; + } result = memcmp(&a->net.ipv4.address, &b->net.ipv4.address, sizeof(ipv4_t)); - if(result) + if(result) { return result; + } result = a->weight - b->weight; - if(result || !a->owner || !b->owner) + if(result || !a->owner || !b->owner) { return result; + } return strcmp(a->owner->name, b->owner->name); } @@ -142,18 +155,21 @@ static int subnet_compare_ipv6(const subnet_t *a, const subnet_t *b) { result = b->net.ipv6.prefixlength - a->net.ipv6.prefixlength; - if(result) + if(result) { return result; + } result = memcmp(&a->net.ipv6.address, &b->net.ipv6.address, sizeof(ipv6_t)); - if(result) + if(result) { return result; + } result = a->weight - b->weight; - if(result || !a->owner || !b->owner) + if(result || !a->owner || !b->owner) { return result; + } return strcmp(a->owner->name, b->owner->name); } @@ -163,16 +179,20 @@ int subnet_compare(const subnet_t *a, const subnet_t *b) { result = a->type - b->type; - if(result) + if(result) { return result; + } - switch (a->type) { + switch(a->type) { case SUBNET_MAC: return subnet_compare_mac(a, b); + case SUBNET_IPV4: return subnet_compare_ipv4(a, b); + case SUBNET_IPV6: return subnet_compare_ipv6(a, b); + default: logger(DEBUG_ALWAYS, LOG_ERR, "subnet_compare() was called with unknown subnet type %d, exitting!", a->type); exit(1); @@ -191,114 +211,158 @@ bool str2net(subnet_t *subnet, const char *subnetstr) { int weight = DEFAULT_WEIGHT; char *weight_separator = strchr(str, '#'); - if (weight_separator) { + + if(weight_separator) { char *weight_str = weight_separator + 1; - if (sscanf(weight_str, "%d%n", &weight, &consumed) < 1) + + if(sscanf(weight_str, "%d%n", &weight, &consumed) < 1) { return false; - if (weight_str[consumed]) + } + + if(weight_str[consumed]) { return false; + } + *weight_separator = 0; } int prefixlength = -1; char *prefixlength_separator = strchr(str, '/'); - if (prefixlength_separator) { - char* prefixlength_str = prefixlength_separator + 1; - if (sscanf(prefixlength_str, "%d%n", &prefixlength, &consumed) < 1) + + if(prefixlength_separator) { + char *prefixlength_str = prefixlength_separator + 1; + + if(sscanf(prefixlength_str, "%d%n", &prefixlength, &consumed) < 1) { return false; - if (prefixlength_str[consumed]) + } + + if(prefixlength_str[consumed]) { return false; + } + *prefixlength_separator = 0; - if (prefixlength < 0) + if(prefixlength < 0) { return false; + } } uint16_t x[8]; - if (sscanf(str, "%hx:%hx:%hx:%hx:%hx:%hx%n", &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &consumed) >= 6 && !str[consumed]) { + + if(sscanf(str, "%hx:%hx:%hx:%hx:%hx:%hx%n", &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &consumed) >= 6 && !str[consumed]) { /* Normally we should check that each part has two digits to prevent ambiguities. However, in old tinc versions net2str() will agressively return MAC addresses with one-digit parts, so we have to accept them otherwise we would be unable to parse ADD_SUBNET messages. */ - if (prefixlength >= 0) + if(prefixlength >= 0) { return false; + } subnet->type = SUBNET_MAC; subnet->weight = weight; - for(int i = 0; i < 6; i++) + + for(int i = 0; i < 6; i++) { subnet->net.mac.address.x[i] = x[i]; + } + return true; } - if (sscanf(str, "%hu.%hu.%hu.%hu%n", &x[0], &x[1], &x[2], &x[3], &consumed) >= 4 && !str[consumed]) { - if (prefixlength == -1) + if(sscanf(str, "%hu.%hu.%hu.%hu%n", &x[0], &x[1], &x[2], &x[3], &consumed) >= 4 && !str[consumed]) { + if(prefixlength == -1) { prefixlength = 32; - if (prefixlength > 32) + } + + if(prefixlength > 32) { return false; + } subnet->type = SUBNET_IPV4; subnet->net.ipv4.prefixlength = prefixlength; subnet->weight = weight; + for(int i = 0; i < 4; i++) { - if (x[i] > 255) + if(x[i] > 255) { return false; + } + subnet->net.ipv4.address.x[i] = x[i]; } + return true; } /* IPv6 */ - char* last_colon = strrchr(str, ':'); - if (last_colon && sscanf(last_colon, ":%hu.%hu.%hu.%hu%n", &x[0], &x[1], &x[2], &x[3], &consumed) >= 4 && !last_colon[consumed]) { + char *last_colon = strrchr(str, ':'); + + if(last_colon && sscanf(last_colon, ":%hu.%hu.%hu.%hu%n", &x[0], &x[1], &x[2], &x[3], &consumed) >= 4 && !last_colon[consumed]) { /* Dotted quad suffix notation, convert to standard IPv6 notation */ - for (int i = 0; i < 4; i++) - if (x[i] > 255) + for(int i = 0; i < 4; i++) + if(x[i] > 255) { return false; + } + snprintf(last_colon, sizeof(str) - (last_colon - str), ":%02x%02x:%02x%02x", x[0], x[1], x[2], x[3]); } - char* double_colon = strstr(str, "::"); - if (double_colon) { + char *double_colon = strstr(str, "::"); + + if(double_colon) { /* Figure out how many zero groups we need to expand */ int zero_group_count = 8; - for (const char* cur = str; *cur; cur++) - if (*cur != ':') { + + for(const char *cur = str; *cur; cur++) + if(*cur != ':') { zero_group_count--; - while(cur[1] && cur[1] != ':') + + while(cur[1] && cur[1] != ':') { cur++; + } } - if (zero_group_count < 1) + + if(zero_group_count < 1) { return false; + } /* Split the double colon in the middle to make room for zero groups */ double_colon++; memmove(double_colon + (zero_group_count * 2 - 1), double_colon, strlen(double_colon) + 1); /* Write zero groups in the resulting gap, overwriting the second colon */ - for (int i = 0; i < zero_group_count; i++) + for(int i = 0; i < zero_group_count; i++) { memcpy(&double_colon[i * 2], "0:", 2); + } /* Remove any leading or trailing colons */ - if (str[0] == ':') + if(str[0] == ':') { memmove(&str[0], &str[1], strlen(&str[1]) + 1); - if (str[strlen(str) - 1] == ':') + } + + if(str[strlen(str) - 1] == ':') { str[strlen(str) - 1] = 0; + } } - if (sscanf(str, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx%n", - &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], &consumed) >= 8 && !str[consumed]) { - if (prefixlength == -1) + if(sscanf(str, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx%n", + &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], &consumed) >= 8 && !str[consumed]) { + if(prefixlength == -1) { prefixlength = 128; - if (prefixlength > 128) + } + + if(prefixlength > 128) { return false; + } subnet->type = SUBNET_IPV6; subnet->net.ipv6.prefixlength = prefixlength; subnet->weight = weight; - for(int i = 0; i < 8; i++) + + for(int i = 0; i < 8; i++) { subnet->net.ipv6.address.x[i] = htons(x[i]); + } + return true; } @@ -313,96 +377,114 @@ bool net2str(char *netstr, int len, const subnet_t *subnet) { int result; int prefixlength = -1; - switch (subnet->type) { - case SUBNET_MAC: - result = snprintf(netstr, len, "%02x:%02x:%02x:%02x:%02x:%02x", - subnet->net.mac.address.x[0], - subnet->net.mac.address.x[1], - subnet->net.mac.address.x[2], - subnet->net.mac.address.x[3], - subnet->net.mac.address.x[4], - subnet->net.mac.address.x[5]); - netstr += result; - len -= result; - break; - - case SUBNET_IPV4: - result = snprintf(netstr, len, "%u.%u.%u.%u", - subnet->net.ipv4.address.x[0], - subnet->net.ipv4.address.x[1], - subnet->net.ipv4.address.x[2], - subnet->net.ipv4.address.x[3]); - netstr += result; - len -= result; - prefixlength = subnet->net.ipv4.prefixlength; - if (prefixlength == 32) - prefixlength = -1; - break; - - case SUBNET_IPV6: { - /* Find the longest sequence of consecutive zeroes */ - int max_zero_length = 0; - int max_zero_length_index = 0; - int current_zero_length = 0; - int current_zero_length_index = 0; - for (int i = 0; i < 8; i++) { - if (subnet->net.ipv6.address.x[i] != 0) - current_zero_length = 0; - else { - if (current_zero_length == 0) - current_zero_length_index = i; - current_zero_length++; - if (current_zero_length > max_zero_length) { - max_zero_length = current_zero_length; - max_zero_length_index = current_zero_length_index; - } + + switch(subnet->type) { + case SUBNET_MAC: + result = snprintf(netstr, len, "%02x:%02x:%02x:%02x:%02x:%02x", + subnet->net.mac.address.x[0], + subnet->net.mac.address.x[1], + subnet->net.mac.address.x[2], + subnet->net.mac.address.x[3], + subnet->net.mac.address.x[4], + subnet->net.mac.address.x[5]); + netstr += result; + len -= result; + break; + + case SUBNET_IPV4: + result = snprintf(netstr, len, "%u.%u.%u.%u", + subnet->net.ipv4.address.x[0], + subnet->net.ipv4.address.x[1], + subnet->net.ipv4.address.x[2], + subnet->net.ipv4.address.x[3]); + netstr += result; + len -= result; + prefixlength = subnet->net.ipv4.prefixlength; + + if(prefixlength == 32) { + prefixlength = -1; + } + + break; + + case SUBNET_IPV6: { + /* Find the longest sequence of consecutive zeroes */ + int max_zero_length = 0; + int max_zero_length_index = 0; + int current_zero_length = 0; + int current_zero_length_index = 0; + + for(int i = 0; i < 8; i++) { + if(subnet->net.ipv6.address.x[i] != 0) { + current_zero_length = 0; + } else { + if(current_zero_length == 0) { + current_zero_length_index = i; + } + + current_zero_length++; + + if(current_zero_length > max_zero_length) { + max_zero_length = current_zero_length; + max_zero_length_index = current_zero_length_index; } } + } + + /* Print the address */ + for(int i = 0; i < 8;) { + if(max_zero_length > 1 && max_zero_length_index == i) { + /* Shorten the representation as per RFC 5952 */ + const char *const FORMATS[] = { "%.1s", "%.2s", "%.3s" }; + const char *const *format = &FORMATS[0]; - /* Print the address */ - for (int i = 0; i < 8;) { - if (max_zero_length > 1 && max_zero_length_index == i) { - /* Shorten the representation as per RFC 5952 */ - const char* const FORMATS[] = { "%.1s", "%.2s", "%.3s" }; - const char* const* format = &FORMATS[0]; - if (i == 0) - format++; - if (i + max_zero_length == 8) - format++; - result = snprintf(netstr, len, *format, ":::"); - i += max_zero_length; - } else { - result = snprintf(netstr, len, "%x:", ntohs(subnet->net.ipv6.address.x[i])); - i++; + if(i == 0) { + format++; } - netstr += result; - len -= result; + + if(i + max_zero_length == 8) { + format++; + } + + result = snprintf(netstr, len, *format, ":::"); + i += max_zero_length; + } else { + result = snprintf(netstr, len, "%x:", ntohs(subnet->net.ipv6.address.x[i])); + i++; } - /* Remove the trailing colon */ - netstr--; - len++; - *netstr = 0; + netstr += result; + len -= result; + } + + /* Remove the trailing colon */ + netstr--; + len++; + *netstr = 0; - prefixlength = subnet->net.ipv6.prefixlength; - if (prefixlength == 128) - prefixlength = -1; - break; + prefixlength = subnet->net.ipv6.prefixlength; + + if(prefixlength == 128) { + prefixlength = -1; } - default: - logger(DEBUG_ALWAYS, LOG_ERR, "net2str() was called with unknown subnet type %d, exiting!", subnet->type); - exit(1); + break; + } + + default: + logger(DEBUG_ALWAYS, LOG_ERR, "net2str() was called with unknown subnet type %d, exiting!", subnet->type); + exit(1); } - if (prefixlength >= 0) { + if(prefixlength >= 0) { result = snprintf(netstr, len, "/%d", prefixlength); netstr += result; len -= result; } - if (subnet->weight != DEFAULT_WEIGHT) + if(subnet->weight != DEFAULT_WEIGHT) { snprintf(netstr, len, "#%d", subnet->weight); + } return true; } diff --git a/src/tincctl.c b/src/tincctl.c index 5dd6410..4803d6c 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -91,12 +91,12 @@ static struct option const long_options[] = { static void version(void) { printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE, - BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR); + BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR); printf("Copyright (C) 1998-2017 Ivo Timmermans, Guus Sliepen and others.\n" - "See the AUTHORS file for a complete list.\n\n" - "tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n" - "and you are welcome to redistribute it under certain conditions;\n" - "see the file COPYING for details.\n"); + "See the AUTHORS file for a complete list.\n\n" + "tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n" + "and you are welcome to redistribute it under certain conditions;\n" + "see the file COPYING for details.\n"); } static void usage(bool status) { @@ -105,61 +105,61 @@ static void usage(bool status) { } else { printf("Usage: %s [options] command\n\n", program_name); printf("Valid options are:\n" - " -b, --batch Don't ask for anything (non-interactive mode).\n" - " -c, --config=DIR Read configuration options from DIR.\n" - " -n, --net=NETNAME Connect to net NETNAME.\n" - " --pidfile=FILENAME Read control cookie from FILENAME.\n" - " --force Force some commands to work despite warnings.\n" - " --help Display this help and exit.\n" - " --version Output version information and exit.\n" - "\n" - "Valid commands are:\n" - " init [name] Create initial configuration files.\n" - " get VARIABLE Print current value of VARIABLE\n" - " set VARIABLE VALUE Set VARIABLE to VALUE\n" - " add VARIABLE VALUE Add VARIABLE with the given VALUE\n" - " del VARIABLE [VALUE] Remove VARIABLE [only ones with watching VALUE]\n" - " start [tincd options] Start tincd.\n" - " stop Stop tincd.\n" - " restart [tincd options] Restart tincd.\n" - " reload Partially reload configuration of running tincd.\n" - " pid Show PID of currently running tincd.\n" + " -b, --batch Don't ask for anything (non-interactive mode).\n" + " -c, --config=DIR Read configuration options from DIR.\n" + " -n, --net=NETNAME Connect to net NETNAME.\n" + " --pidfile=FILENAME Read control cookie from FILENAME.\n" + " --force Force some commands to work despite warnings.\n" + " --help Display this help and exit.\n" + " --version Output version information and exit.\n" + "\n" + "Valid commands are:\n" + " init [name] Create initial configuration files.\n" + " get VARIABLE Print current value of VARIABLE\n" + " set VARIABLE VALUE Set VARIABLE to VALUE\n" + " add VARIABLE VALUE Add VARIABLE with the given VALUE\n" + " del VARIABLE [VALUE] Remove VARIABLE [only ones with watching VALUE]\n" + " start [tincd options] Start tincd.\n" + " stop Stop tincd.\n" + " restart [tincd options] Restart tincd.\n" + " reload Partially reload configuration of running tincd.\n" + " pid Show PID of currently running tincd.\n" #ifdef DISABLE_LEGACY - " generate-keys Generate a new Ed25519 public/private keypair.\n" + " generate-keys Generate a new Ed25519 public/private keypair.\n" #else - " generate-keys [bits] Generate new RSA and Ed25519 public/private keypairs.\n" - " generate-rsa-keys [bits] Generate a new RSA public/private keypair.\n" + " generate-keys [bits] Generate new RSA and Ed25519 public/private keypairs.\n" + " generate-rsa-keys [bits] Generate a new RSA public/private keypair.\n" #endif - " generate-ed25519-keys Generate a new Ed25519 public/private keypair.\n" - " dump Dump a list of one of the following things:\n" - " [reachable] nodes - all known nodes in the VPN\n" - " edges - all known connections in the VPN\n" - " subnets - all known subnets in the VPN\n" - " connections - all meta connections with ourself\n" - " [di]graph - graph of the VPN in dotty format\n" - " invitations - outstanding invitations\n" - " info NODE|SUBNET|ADDRESS Give information about a particular NODE, SUBNET or ADDRESS.\n" - " purge Purge unreachable nodes\n" - " debug N Set debug level\n" - " retry Retry all outgoing connections\n" - " disconnect NODE Close meta connection with NODE\n" + " generate-ed25519-keys Generate a new Ed25519 public/private keypair.\n" + " dump Dump a list of one of the following things:\n" + " [reachable] nodes - all known nodes in the VPN\n" + " edges - all known connections in the VPN\n" + " subnets - all known subnets in the VPN\n" + " connections - all meta connections with ourself\n" + " [di]graph - graph of the VPN in dotty format\n" + " invitations - outstanding invitations\n" + " info NODE|SUBNET|ADDRESS Give information about a particular NODE, SUBNET or ADDRESS.\n" + " purge Purge unreachable nodes\n" + " debug N Set debug level\n" + " retry Retry all outgoing connections\n" + " disconnect NODE Close meta connection with NODE\n" #ifdef HAVE_CURSES - " top Show real-time statistics\n" + " top Show real-time statistics\n" #endif - " pcap [snaplen] Dump traffic in pcap format [up to snaplen bytes per packet]\n" - " log [level] Dump log output [up to the specified level]\n" - " export Export host configuration of local node to standard output\n" - " export-all Export all host configuration files to standard output\n" - " import Import host configuration file(s) from standard input\n" - " exchange Same as export followed by import\n" - " exchange-all Same as export-all followed by import\n" - " invite NODE [...] Generate an invitation for NODE\n" - " join INVITATION Join a VPN using an INVITATION\n" - " network [NETNAME] List all known networks, or switch to the one named NETNAME.\n" - " fsck Check the configuration files for problems.\n" - " sign [FILE] Generate a signed version of a file.\n" - " verify NODE [FILE] Verify that a file was signed by the given NODE.\n" - "\n"); + " pcap [snaplen] Dump traffic in pcap format [up to snaplen bytes per packet]\n" + " log [level] Dump log output [up to the specified level]\n" + " export Export host configuration of local node to standard output\n" + " export-all Export all host configuration files to standard output\n" + " import Import host configuration file(s) from standard input\n" + " exchange Same as export followed by import\n" + " exchange-all Same as export-all followed by import\n" + " invite NODE [...] Generate an invitation for NODE\n" + " join INVITATION Join a VPN using an INVITATION\n" + " network [NETNAME] List all known networks, or switch to the one named NETNAME.\n" + " fsck Check the configuration files for problems.\n" + " sign [FILE] Generate a signed version of a file.\n" + " verify NODE [FILE] Verify that a file was signed by the given NODE.\n" + "\n"); printf("Report bugs to tinc@tinc-vpn.org.\n"); } } @@ -169,50 +169,51 @@ static bool parse_options(int argc, char **argv) { int option_index = 0; while((r = getopt_long(argc, argv, "+bc:n:", long_options, &option_index)) != EOF) { - switch (r) { - case 0: /* long option */ - break; + switch(r) { + case 0: /* long option */ + break; - case 'b': - tty = false; - break; + case 'b': + tty = false; + break; - case 'c': /* config file */ - confbase = xstrdup(optarg); - confbasegiven = true; - break; + case 'c': /* config file */ + confbase = xstrdup(optarg); + confbasegiven = true; + break; - case 'n': /* net name given */ - netname = xstrdup(optarg); - break; + case 'n': /* net name given */ + netname = xstrdup(optarg); + break; - case 1: /* show help */ - show_help = true; - break; + case 1: /* show help */ + show_help = true; + break; - case 2: /* show version */ - show_version = true; - break; + case 2: /* show version */ + show_version = true; + break; - case 3: /* open control socket here */ - pidfilename = xstrdup(optarg); - break; + case 3: /* open control socket here */ + pidfilename = xstrdup(optarg); + break; - case 4: /* force */ - force = true; - break; + case 4: /* force */ + force = true; + break; - case '?': /* wrong options */ - usage(true); - return false; + case '?': /* wrong options */ + usage(true); + return false; - default: - break; + default: + break; } } - if(!netname && (netname = getenv("NETNAME"))) + if(!netname && (netname = getenv("NETNAME"))) { netname = xstrdup(netname); + } /* netname "." is special: a "top-level name" */ @@ -245,8 +246,11 @@ FILE *fopenmask(const char *filename, const char *mode, mode_t perms) { } #ifdef HAVE_FCHMOD - if((perms & 0444) && f) + + if((perms & 0444) && f) { fchmod(fileno(f), perms); + } + #endif umask(mask); return f; @@ -261,8 +265,10 @@ static void disable_old_keys(const char *filename, const char *what) { FILE *r, *w; r = fopen(filename, "r"); - if(!r) + + if(!r) { return; + } snprintf(tmpfile, sizeof(tmpfile), "%s.tmp", filename); @@ -280,33 +286,43 @@ static void disable_old_keys(const char *filename, const char *what) { bool ed25519pubkey = !strncasecmp(buf, "Ed25519PublicKey", 16) && strchr(" \t=", buf[16]) && strstr(what, "Ed25519"); - if(ed25519pubkey) + if(ed25519pubkey) { disabled = true; + } if(w) { - if(block || ed25519pubkey) + if(block || ed25519pubkey) { fputc('#', w); + } + if(fputs(buf, w) < 0) { error = true; break; } } - if(block && !strncmp(buf, "-----END ", 9)) + if(block && !strncmp(buf, "-----END ", 9)) { block = false; + } } if(w) - if(fclose(w) < 0) + if(fclose(w) < 0) { error = true; - if(ferror(r) || fclose(r) < 0) + } + + if(ferror(r) || fclose(r) < 0) { error = true; + } if(disabled) { if(!w || error) { fprintf(stderr, "Warning: old key(s) found, remove them by hand!\n"); - if(w) + + if(w) { unlink(tmpfile); + } + return; } @@ -314,9 +330,11 @@ static void disable_old_keys(const char *filename, const char *what) { // We cannot atomically replace files on Windows. char bakfile[PATH_MAX] = ""; snprintf(bakfile, sizeof(bakfile), "%s.bak", filename); + if(rename(filename, bakfile) || rename(tmpfile, filename)) { rename(bakfile, filename); #else + if(rename(tmpfile, filename)) { #endif fprintf(stderr, "Warning: old key(s) found, remove them by hand!\n"); @@ -348,16 +366,21 @@ static FILE *ask_and_open(const char *filename, const char *what, const char *mo } size_t len = strlen(buf); - if(len) + + if(len) { buf[--len] = 0; + } - if(len) + if(len) { filename = buf; + } } #ifdef HAVE_MINGW + if(filename[0] != '\\' && filename[0] != '/' && !strchr(filename, ':')) { #else + if(filename[0] != '/') { #endif /* The directory is a relative path or a filename. */ @@ -394,14 +417,16 @@ static bool ed25519_keygen(bool ask) { if(!(key = ecdsa_generate())) { fprintf(stderr, "Error during key generation!\n"); return false; - } else + } else { fprintf(stderr, "Done.\n"); + } snprintf(fname, sizeof(fname), "%s" SLASH "ed25519_key.priv", confbase); f = ask_and_open(fname, "private Ed25519 key", "a", ask, 0600); - if(!f) + if(!f) { goto error; + } if(!ecdsa_write_pem_private_key(key, f)) { fprintf(stderr, "Error writing private key!\n"); @@ -410,15 +435,17 @@ static bool ed25519_keygen(bool ask) { fclose(f); - if(name) + if(name) { snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, name); - else + } else { snprintf(fname, sizeof(fname), "%s" SLASH "ed25519_key.pub", confbase); + } f = ask_and_open(fname, "public Ed25519 key", "a", ask, 0666); - if(!f) + if(!f) { return false; + } char *pubkey = ecdsa_get_base64_public_key(key); fprintf(f, "Ed25519PublicKey = %s\n", pubkey); @@ -430,8 +457,11 @@ static bool ed25519_keygen(bool ask) { return true; error: - if(f) + + if(f) { fclose(f); + } + ecdsa_free(key); return false; } @@ -462,14 +492,16 @@ static bool rsa_keygen(int bits, bool ask) { if(!(key = rsa_generate(bits, 0x10001))) { fprintf(stderr, "Error during key generation!\n"); return false; - } else + } else { fprintf(stderr, "Done.\n"); + } snprintf(fname, sizeof(fname), "%s" SLASH "rsa_key.priv", confbase); f = ask_and_open(fname, "private RSA key", "a", ask, 0600); - if(!f) + if(!f) { goto error; + } if(!rsa_write_pem_private_key(key, f)) { fprintf(stderr, "Error writing private key!\n"); @@ -478,15 +510,17 @@ static bool rsa_keygen(int bits, bool ask) { fclose(f); - if(name) + if(name) { snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, name); - else + } else { snprintf(fname, sizeof(fname), "%s" SLASH "rsa_key.pub", confbase); + } f = ask_and_open(fname, "public RSA key", "a", ask, 0666); - if(!f) + if(!f) { goto error; + } if(!rsa_write_pem_public_key(key, f)) { fprintf(stderr, "Error writing public key!\n"); @@ -499,8 +533,11 @@ static bool rsa_keygen(int bits, bool ask) { return true; error: - if(f) + + if(f) { fclose(f); + } + rsa_free(key); return false; } @@ -512,20 +549,25 @@ size_t blen = 0; bool recvline(int fd, char *line, size_t len) { char *newline = NULL; - if(!fd) + if(!fd) { return false; + } while(!(newline = memchr(buffer, '\n', blen))) { int result = recv(fd, buffer + blen, sizeof(buffer) - blen, 0); - if(result == -1 && sockerrno == EINTR) + + if(result == -1 && sockerrno == EINTR) { continue; - else if(result <= 0) + } else if(result <= 0) { return false; + } + blen += result; } - if(newline - buffer >= len) + if(newline - buffer >= len) { return false; + } len = newline - buffer; @@ -538,15 +580,19 @@ bool recvline(int fd, char *line, size_t len) { } bool recvdata(int fd, char *data, size_t len) { - if(len == -1) + if(len == -1) { len = blen; + } while(blen < len) { int result = recv(fd, buffer + blen, sizeof(buffer) - blen, 0); - if(result == -1 && sockerrno == EINTR) + + if(result == -1 && sockerrno == EINTR) { continue; - else if(result <= 0) + } else if(result <= 0) { return false; + } + blen += result; } @@ -568,18 +614,22 @@ bool sendline(int fd, char *format, ...) { buffer[sizeof(buffer) - 1] = 0; va_end(ap); - if(blen < 1 || blen >= sizeof(buffer)) + if(blen < 1 || blen >= sizeof(buffer)) { return false; + } buffer[blen] = '\n'; blen++; while(blen) { int result = send(fd, p, blen, MSG_NOSIGNAL); - if(result == -1 && sockerrno == EINTR) + + if(result == -1 && sockerrno == EINTR) { continue; - else if(result <= 0) + } else if(result <= 0) { return false; + } + p += result; blen -= result; } @@ -603,7 +653,7 @@ static void pcap(int fd, FILE *out, int snaplen) { 0xa1b2c3d4, 2, 4, 0, 0, - snaplen ?: sizeof(data), + snaplen ? : sizeof(data), 1, }; @@ -620,14 +670,20 @@ static void pcap(int fd, FILE *out, int snaplen) { fflush(out); char line[32]; + while(recvline(fd, line, sizeof(line))) { int code, req, len; int n = sscanf(line, "%d %d %d", &code, &req, &len); gettimeofday(&tv, NULL); - if(n != 3 || code != CONTROL || req != REQ_PCAP || len < 0 || len > sizeof(data)) + + if(n != 3 || code != CONTROL || req != REQ_PCAP || len < 0 || len > sizeof(data)) { break; - if(!recvdata(fd, data, len)) + } + + if(!recvdata(fd, data, len)) { break; + } + packet.tv_sec = tv.tv_sec; packet.tv_usec = tv.tv_usec; packet.len = len; @@ -646,10 +702,15 @@ static void logcontrol(int fd, FILE *out, int level) { while(recvline(fd, line, sizeof(line))) { int code, req, len; int n = sscanf(line, "%d %d %d", &code, &req, &len); - if(n != 3 || code != CONTROL || req != REQ_LOG || len < 0 || len > sizeof(data)) + + if(n != 3 || code != CONTROL || req != REQ_LOG || len < 0 || len > sizeof(data)) { break; - if(!recvdata(fd, data, len)) + } + + if(!recvdata(fd, data, len)) { break; + } + fwrite(data, len, 1, out); fputc('\n', out); fflush(out); @@ -663,6 +724,7 @@ static bool remove_service(void) { SERVICE_STATUS status = {0}; manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + if(!manager) { fprintf(stderr, "Could not open service manager: %s\n", winerror(GetLastError())); return false; @@ -675,10 +737,11 @@ static bool remove_service(void) { return false; } - if(!ControlService(service, SERVICE_CONTROL_STOP, &status)) + if(!ControlService(service, SERVICE_CONTROL_STOP, &status)) { fprintf(stderr, "Could not stop %s service: %s\n", identname, winerror(GetLastError())); - else + } else { fprintf(stderr, "%s service stopped\n", identname); + } if(!DeleteService(service)) { fprintf(stderr, "Could not remove %s service: %s\n", identname, winerror(GetLastError())); @@ -697,6 +760,7 @@ bool connect_tincd(bool verbose) { FD_ZERO(&r); FD_SET(fd, &r); struct timeval tv = {0, 0}; + if(select(fd + 1, &r, NULL, NULL, &tv)) { fprintf(stderr, "Previous connection to tincd lost, reconnecting.\n"); close(fd); @@ -707,9 +771,12 @@ bool connect_tincd(bool verbose) { } FILE *f = fopen(pidfilename, "r"); + if(!f) { - if(verbose) + if(verbose) { fprintf(stderr, "Could not open pid file %s: %s\n", pidfilename, strerror(errno)); + } + return false; } @@ -717,8 +784,10 @@ bool connect_tincd(bool verbose) { char port[129]; if(fscanf(f, "%20d %1024s %128s port %128s", &pid, controlcookie, host, port) != 4) { - if(verbose) + if(verbose) { fprintf(stderr, "Could not parse pid file %s\n", pidfilename); + } + fclose(f); return false; } @@ -726,7 +795,8 @@ bool connect_tincd(bool verbose) { fclose(f); #ifndef HAVE_MINGW - if ((pid == 0) || (kill(pid, 0) && (errno == ESRCH))) { + + if((pid == 0) || (kill(pid, 0) && (errno == ESRCH))) { fprintf(stderr, "Could not find tincd running at pid %d\n", pid); /* clean up the stale socket and pid file */ unlink(pidfilename); @@ -735,23 +805,31 @@ bool connect_tincd(bool verbose) { } struct sockaddr_un sa; + sa.sun_family = AF_UNIX; + strncpy(sa.sun_path, unixsocketname, sizeof(sa.sun_path)); fd = socket(AF_UNIX, SOCK_STREAM, 0); + if(fd < 0) { - if(verbose) + if(verbose) { fprintf(stderr, "Cannot create UNIX socket: %s\n", sockstrerror(sockerrno)); + } + return false; } if(connect(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) { - if(verbose) + if(verbose) { fprintf(stderr, "Cannot connect to UNIX socket %s: %s\n", unixsocketname, sockstrerror(sockerrno)); + } + close(fd); fd = -1; return false; } + #else struct addrinfo hints = { .ai_family = AF_UNSPEC, @@ -763,15 +841,20 @@ bool connect_tincd(bool verbose) { struct addrinfo *res = NULL; if(getaddrinfo(host, port, &hints, &res) || !res) { - if(verbose) + if(verbose) { fprintf(stderr, "Cannot resolve %s port %s: %s", host, port, sockstrerror(sockerrno)); + } + return false; } fd = socket(res->ai_family, SOCK_STREAM, IPPROTO_TCP); + if(fd < 0) { - if(verbose) + if(verbose) { fprintf(stderr, "Cannot create TCP socket: %s\n", sockstrerror(sockerrno)); + } + return false; } @@ -779,14 +862,18 @@ bool connect_tincd(bool verbose) { unsigned long arg = 0; if(ioctlsocket(fd, FIONBIO, &arg) != 0) { - if(verbose) + if(verbose) { fprintf(stderr, "ioctlsocket failed: %s", sockstrerror(sockerrno)); + } } + #endif if(connect(fd, res->ai_addr, res->ai_addrlen) < 0) { - if(verbose) + if(verbose) { fprintf(stderr, "Cannot connect to %s port %s: %s\n", host, port, sockstrerror(sockerrno)); + } + close(fd); fd = -1; return false; @@ -804,8 +891,10 @@ bool connect_tincd(bool verbose) { int version; if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %4095s %d", &code, data, &version) != 3 || code != 0) { - if(verbose) + if(verbose) { fprintf(stderr, "Cannot read greeting from control socket: %s\n", sockstrerror(sockerrno)); + } + close(fd); fd = -1; return false; @@ -814,8 +903,10 @@ bool connect_tincd(bool verbose) { sendline(fd, "%d ^%s %d", ID, controlcookie, TINC_CTL_VERSION_CURRENT); if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &version, &pid) != 3 || code != 4 || version != TINC_CTL_VERSION_CURRENT) { - if(verbose) + if(verbose) { fprintf(stderr, "Could not fully establish control socket connection\n"); + } + close(fd); fd = -1; return false; @@ -827,10 +918,12 @@ bool connect_tincd(bool verbose) { static int cmd_start(int argc, char *argv[]) { if(connect_tincd(false)) { - if(netname) + if(netname) { fprintf(stderr, "A tincd is already running for net `%s' with pid %d.\n", netname, pid); - else + } else { fprintf(stderr, "A tincd is already running with pid %d.\n", pid); + } + return 0; } @@ -838,14 +931,18 @@ static int cmd_start(int argc, char *argv[]) { char *slash = strrchr(program_name, '/'); #ifdef HAVE_MINGW - if ((c = strrchr(program_name, '\\')) > slash) + + if((c = strrchr(program_name, '\\')) > slash) { slash = c; + } + #endif - if (slash++) + if(slash++) { xasprintf(&c, "%.*stincd", (int)(slash - program_name), program_name); - else + } else { c = "tincd"; + } int nargc = 0; char **nargv = xzalloc((optind + argc) * sizeof(*nargv)); @@ -863,20 +960,27 @@ static int cmd_start(int argc, char *argv[]) { xasprintf(&arg0, "\"%s\"", arg0); #endif nargv[nargc++] = arg0; - for(int i = 1; i < optind; i++) + + for(int i = 1; i < optind; i++) { nargv[nargc++] = orig_argv[i]; - for(int i = 1; i < argc; i++) + } + + for(int i = 1; i < argc; i++) { nargv[nargc++] = argv[i]; + } #ifdef HAVE_MINGW int status = spawnvp(_P_WAIT, c, nargv); - if (status == -1) { + + if(status == -1) { fprintf(stderr, "Error starting %s: %s\n", c, strerror(errno)); return 1; } + return status; #else int pfd[2] = {-1, -1}; + if(socketpair(AF_UNIX, SOCK_STREAM, 0, pfd)) { fprintf(stderr, "Could not create umbilical socket: %s\n", strerror(errno)); free(nargv); @@ -884,6 +988,7 @@ static int cmd_start(int argc, char *argv[]) { } pid_t pid = fork(); + if(pid == -1) { fprintf(stderr, "Could not fork: %s\n", strerror(errno)); free(nargv); @@ -915,13 +1020,17 @@ static int cmd_start(int argc, char *argv[]) { while((len = read(pfd[0], buf, sizeof(buf))) > 0) { failure = buf[len - 1]; - if(!failure) + + if(!failure) { len--; + } + write(2, buf, len); } - if(len) + if(len) { failure = true; + } close(pfd[0]); @@ -948,6 +1057,7 @@ static int cmd_stop(int argc, char *argv[]) { } #ifndef HAVE_MINGW + if(!connect_tincd(true)) { if(pid) { if(kill(pid, SIGTERM)) { @@ -968,9 +1078,13 @@ static int cmd_stop(int argc, char *argv[]) { while(recvline(fd, line, sizeof(line))) { // Wait for tincd to close the connection... } + #else - if(!remove_service()) + + if(!remove_service()) { return 1; + } + #endif close(fd); pid = 0; @@ -990,10 +1104,12 @@ static int cmd_reload(int argc, char *argv[]) { return 1; } - if(!connect_tincd(true)) + if(!connect_tincd(true)) { return 1; + } sendline(fd, "%d %d", CONTROL, REQ_RELOAD); + if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_RELOAD || result) { fprintf(stderr, "Could not reload configuration.\n"); return 1; @@ -1007,6 +1123,7 @@ static int dump_invitations(void) { char dname[PATH_MAX]; snprintf(dname, sizeof(dname), "%s" SLASH "invitations", confbase); DIR *dir = opendir(dname); + if(!dir) { if(errno == ENOENT) { fprintf(stderr, "No outstanding invitations.\n"); @@ -1018,32 +1135,41 @@ static int dump_invitations(void) { } struct dirent *ent; + bool found = false; while((ent = readdir(dir))) { char buf[MAX_STRING_SIZE]; - if(b64decode(ent->d_name, buf, 24) != 18) + + if(b64decode(ent->d_name, buf, 24) != 18) { continue; + } char fname[PATH_MAX]; snprintf(fname, sizeof(fname), "%s" SLASH "%s", dname, ent->d_name); FILE *f = fopen(fname, "r"); + if(!f) { fprintf(stderr, "Cannot open %s: %s\n", fname, strerror(errno)); continue; } buf[0] = 0; + if(!fgets(buf, sizeof(buf), f)) { fprintf(stderr, "Invalid invitation file %s", fname); fclose(f); continue; } + fclose(f); char *eol = buf + strlen(buf); - while(strchr("\t \r\n", *--eol)) + + while(strchr("\t \r\n", *--eol)) { *eol = 0; + } + if(strncmp(buf, "Name = ", 7) || !check_id(buf + 7)) { fprintf(stderr, "Invalid invitation file %s", fname); continue; @@ -1055,8 +1181,9 @@ static int dump_invitations(void) { closedir(dir); - if(!found) + if(!found) { fprintf(stderr, "No outstanding invitations.\n"); + } return 0; } @@ -1070,6 +1197,7 @@ static int cmd_dump(int argc, char *argv[]) { usage(true); return 1; } + only_reachable = true; argv++; argc--; @@ -1081,23 +1209,25 @@ static int cmd_dump(int argc, char *argv[]) { return 1; } - if(!strcasecmp(argv[1], "invitations")) + if(!strcasecmp(argv[1], "invitations")) { return dump_invitations(); + } - if(!connect_tincd(true)) + if(!connect_tincd(true)) { return 1; + } int do_graph = 0; - if(!strcasecmp(argv[1], "nodes")) + if(!strcasecmp(argv[1], "nodes")) { sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES); - else if(!strcasecmp(argv[1], "edges")) + } else if(!strcasecmp(argv[1], "edges")) { sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES); - else if(!strcasecmp(argv[1], "subnets")) + } else if(!strcasecmp(argv[1], "subnets")) { sendline(fd, "%d %d", CONTROL, REQ_DUMP_SUBNETS); - else if(!strcasecmp(argv[1], "connections")) + } else if(!strcasecmp(argv[1], "connections")) { sendline(fd, "%d %d", CONTROL, REQ_DUMP_CONNECTIONS); - else if(!strcasecmp(argv[1], "graph")) { + } else if(!strcasecmp(argv[1], "graph")) { sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES); sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES); do_graph = 1; @@ -1111,25 +1241,31 @@ static int cmd_dump(int argc, char *argv[]) { return 1; } - if(do_graph == 1) + if(do_graph == 1) { printf("graph {\n"); - else if(do_graph == 2) + } else if(do_graph == 2) { printf("digraph {\n"); + } while(recvline(fd, line, sizeof(line))) { char node1[4096], node2[4096]; int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, node1, node2); + if(n == 2) { - if(do_graph && req == REQ_DUMP_NODES) + if(do_graph && req == REQ_DUMP_NODES) { continue; - else { - if(do_graph) + } else { + if(do_graph) { printf("}\n"); + } + return 0; } } - if(n < 2) + + if(n < 2) { break; + } char node[4096]; char id[4096]; @@ -1149,75 +1285,92 @@ static int cmd_dump(int argc, char *argv[]) { long int last_state_change; switch(req) { - case REQ_DUMP_NODES: { - int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %d %d %d %d %x %x %4095s %4095s %d %hd %hd %hd %ld", node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_int, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change); - if(n != 17) { - fprintf(stderr, "Unable to parse node dump from tincd: %s\n", line); - return 1; - } + case REQ_DUMP_NODES: { + int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %d %d %d %d %x %x %4095s %4095s %d %hd %hd %hd %ld", node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_int, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change); - memcpy(&status, &status_int, sizeof(status)); + if(n != 17) { + fprintf(stderr, "Unable to parse node dump from tincd: %s\n", line); + return 1; + } - if(do_graph) { - const char *color = "black"; - if(!strcmp(host, "MYSELF")) - color = "green"; - else if(!status.reachable) - color = "red"; - else if(strcmp(via, node)) - color = "orange"; - else if(!status.validkey) - color = "black"; - else if(minmtu > 0) - color = "green"; - printf(" %s [label = \"%s\", color = \"%s\"%s];\n", node, node, color, strcmp(host, "MYSELF") ? "" : ", style = \"filled\""); - } else { - if(only_reachable && !status.reachable) - continue; - printf("%s id %s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %d (min %d max %d)\n", - node, id, host, port, cipher, digest, maclength, compression, options, status_int, nexthop, via, distance, pmtu, minmtu, maxmtu); + memcpy(&status, &status_int, sizeof(status)); + + if(do_graph) { + const char *color = "black"; + + if(!strcmp(host, "MYSELF")) { + color = "green"; + } else if(!status.reachable) { + color = "red"; + } else if(strcmp(via, node)) { + color = "orange"; + } else if(!status.validkey) { + color = "black"; + } else if(minmtu > 0) { + color = "green"; } - } break; - case REQ_DUMP_EDGES: { - int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %4095s port %4095s %x %d", from, to, host, port, local_host, local_port, &options, &weight); - if(n != 8) { - fprintf(stderr, "Unable to parse edge dump from tincd.\n"); - return 1; + printf(" %s [label = \"%s\", color = \"%s\"%s];\n", node, node, color, strcmp(host, "MYSELF") ? "" : ", style = \"filled\""); + } else { + if(only_reachable && !status.reachable) { + continue; } - if(do_graph) { - float w = 1 + 65536.0 / weight; - if(do_graph == 1 && strcmp(node1, node2) > 0) - printf(" %s -- %s [w = %f, weight = %f];\n", node1, node2, w, w); - else if(do_graph == 2) - printf(" %s -> %s [w = %f, weight = %f];\n", node1, node2, w, w); - } else { - printf("%s to %s at %s port %s local %s port %s options %x weight %d\n", from, to, host, port, local_host, local_port, options, weight); - } - } break; + printf("%s id %s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %d (min %d max %d)\n", + node, id, host, port, cipher, digest, maclength, compression, options, status_int, nexthop, via, distance, pmtu, minmtu, maxmtu); + } + } + break; - case REQ_DUMP_SUBNETS: { - int n = sscanf(line, "%*d %*d %4095s %4095s", subnet, node); - if(n != 2) { - fprintf(stderr, "Unable to parse subnet dump from tincd.\n"); - return 1; - } - printf("%s owner %s\n", strip_weight(subnet), node); - } break; + case REQ_DUMP_EDGES: { + int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %4095s port %4095s %x %d", from, to, host, port, local_host, local_port, &options, &weight); - case REQ_DUMP_CONNECTIONS: { - int n = sscanf(line, "%*d %*d %4095s %4095s port %4095s %x %d %x", node, host, port, &options, &socket, &status_int); - if(n != 6) { - fprintf(stderr, "Unable to parse connection dump from tincd.\n"); - return 1; + if(n != 8) { + fprintf(stderr, "Unable to parse edge dump from tincd.\n"); + return 1; + } + + if(do_graph) { + float w = 1 + 65536.0 / weight; + + if(do_graph == 1 && strcmp(node1, node2) > 0) { + printf(" %s -- %s [w = %f, weight = %f];\n", node1, node2, w, w); + } else if(do_graph == 2) { + printf(" %s -> %s [w = %f, weight = %f];\n", node1, node2, w, w); } - printf("%s at %s port %s options %x socket %d status %x\n", node, host, port, options, socket, status_int); - } break; + } else { + printf("%s to %s at %s port %s local %s port %s options %x weight %d\n", from, to, host, port, local_host, local_port, options, weight); + } + } + break; - default: - fprintf(stderr, "Unable to parse dump from tincd.\n"); + case REQ_DUMP_SUBNETS: { + int n = sscanf(line, "%*d %*d %4095s %4095s", subnet, node); + + if(n != 2) { + fprintf(stderr, "Unable to parse subnet dump from tincd.\n"); return 1; + } + + printf("%s owner %s\n", strip_weight(subnet), node); + } + break; + + case REQ_DUMP_CONNECTIONS: { + int n = sscanf(line, "%*d %*d %4095s %4095s port %4095s %x %d %x", node, host, port, &options, &socket, &status_int); + + if(n != 6) { + fprintf(stderr, "Unable to parse connection dump from tincd.\n"); + return 1; + } + + printf("%s at %s port %s options %x socket %d status %x\n", node, host, port, options, socket, status_int); + } + break; + + default: + fprintf(stderr, "Unable to parse dump from tincd.\n"); + return 1; } } @@ -1231,10 +1384,12 @@ static int cmd_purge(int argc, char *argv[]) { return 1; } - if(!connect_tincd(true)) + if(!connect_tincd(true)) { return 1; + } sendline(fd, "%d %d", CONTROL, REQ_PURGE); + if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_PURGE || result) { fprintf(stderr, "Could not purge old information.\n"); return 1; @@ -1249,13 +1404,15 @@ static int cmd_debug(int argc, char *argv[]) { return 1; } - if(!connect_tincd(true)) + if(!connect_tincd(true)) { return 1; + } int debuglevel = atoi(argv[1]); int origlevel; sendline(fd, "%d %d %d", CONTROL, REQ_SET_DEBUG, debuglevel); + if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &origlevel) != 3 || code != CONTROL || req != REQ_SET_DEBUG) { fprintf(stderr, "Could not set debug level.\n"); return 1; @@ -1271,10 +1428,12 @@ static int cmd_retry(int argc, char *argv[]) { return 1; } - if(!connect_tincd(true)) + if(!connect_tincd(true)) { return 1; + } sendline(fd, "%d %d", CONTROL, REQ_RETRY); + if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_RETRY || result) { fprintf(stderr, "Could not retry outgoing connections.\n"); return 1; @@ -1294,10 +1453,12 @@ static int cmd_connect(int argc, char *argv[]) { return 1; } - if(!connect_tincd(true)) + if(!connect_tincd(true)) { return 1; + } sendline(fd, "%d %d %s", CONTROL, REQ_CONNECT, argv[1]); + if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_CONNECT || result) { fprintf(stderr, "Could not connect to %s.\n", argv[1]); return 1; @@ -1317,10 +1478,12 @@ static int cmd_disconnect(int argc, char *argv[]) { return 1; } - if(!connect_tincd(true)) + if(!connect_tincd(true)) { return 1; + } sendline(fd, "%d %d %s", CONTROL, REQ_DISCONNECT, argv[1]); + if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_DISCONNECT || result) { fprintf(stderr, "Could not disconnect %s.\n", argv[1]); return 1; @@ -1336,8 +1499,10 @@ static int cmd_top(int argc, char *argv[]) { } #ifdef HAVE_CURSES - if(!connect_tincd(true)) + + if(!connect_tincd(true)) { return 1; + } top(fd); return 0; @@ -1353,8 +1518,9 @@ static int cmd_pcap(int argc, char *argv[]) { return 1; } - if(!connect_tincd(true)) + if(!connect_tincd(true)) { return 1; + } pcap(fd, stdout, argc > 1 ? atoi(argv[1]) : 0); return 0; @@ -1373,8 +1539,9 @@ static int cmd_log(int argc, char *argv[]) { return 1; } - if(!connect_tincd(true)) + if(!connect_tincd(true)) { return 1; + } #ifdef SIGINT signal(SIGINT, sigint_handler); @@ -1397,8 +1564,9 @@ static int cmd_pid(int argc, char *argv[]) { return 1; } - if(!connect_tincd(true) || !pid) + if(!connect_tincd(true) || !pid) { return 1; + } printf("%d\n", pid); return 0; @@ -1406,34 +1574,48 @@ static int cmd_pid(int argc, char *argv[]) { int rstrip(char *value) { int len = strlen(value); - while(len && strchr("\t\r\n ", value[len - 1])) + + while(len && strchr("\t\r\n ", value[len - 1])) { value[--len] = 0; + } + return len; } char *get_my_name(bool verbose) { FILE *f = fopen(tinc_conf, "r"); + if(!f) { - if(verbose) + if(verbose) { fprintf(stderr, "Could not open %s: %s\n", tinc_conf, strerror(errno)); + } + return NULL; } char buf[4096]; char *value; + while(fgets(buf, sizeof(buf), f)) { int len = strcspn(buf, "\t ="); value = buf + len; value += strspn(value, "\t "); + if(*value == '=') { value++; value += strspn(value, "\t "); } - if(!rstrip(value)) + + if(!rstrip(value)) { continue; + } + buf[len] = 0; - if(strcasecmp(buf, "Name")) + + if(strcasecmp(buf, "Name")) { continue; + } + if(*value) { fclose(f); return replace_name(value); @@ -1441,29 +1623,41 @@ char *get_my_name(bool verbose) { } fclose(f); - if(verbose) + + if(verbose) { fprintf(stderr, "Could not find Name in %s.\n", tinc_conf); + } + return NULL; } ecdsa_t *get_pubkey(FILE *f) { char buf[4096]; char *value; + while(fgets(buf, sizeof(buf), f)) { int len = strcspn(buf, "\t ="); value = buf + len; value += strspn(value, "\t "); + if(*value == '=') { value++; value += strspn(value, "\t "); } - if(!rstrip(value)) + + if(!rstrip(value)) { continue; + } + buf[len] = 0; - if(strcasecmp(buf, "Ed25519PublicKey")) + + if(strcasecmp(buf, "Ed25519PublicKey")) { continue; - if(*value) + } + + if(*value) { return ecdsa_set_base64_public_key(value); + } } return NULL; @@ -1553,10 +1747,12 @@ static int cmd_config(int argc, char *argv[]) { return 1; } - if(strcasecmp(argv[0], "config")) + if(strcasecmp(argv[0], "config")) { argv--, argc++; + } int action = -2; + if(!strcasecmp(argv[1], "get")) { argv++, argc--; } else if(!strcasecmp(argv[1], "add")) { @@ -1574,6 +1770,7 @@ static int cmd_config(int argc, char *argv[]) { // Concatenate the rest of the command line strncpy(line, argv[1], sizeof(line) - 1); + for(int i = 2; i < argc; i++) { strncat(line, " ", sizeof(line) - 1 - strlen(line)); strncat(line, argv[i], sizeof(line) - 1 - strlen(line)); @@ -1588,12 +1785,15 @@ static int cmd_config(int argc, char *argv[]) { len = strcspn(line, "\t ="); value = line + len; value += strspn(value, "\t "); + if(*value == '=') { value++; value += strspn(value, "\t "); } + line[len] = '\0'; variable = strchr(line, '.'); + if(variable) { node = line; *variable++ = 0; @@ -1611,16 +1811,18 @@ static int cmd_config(int argc, char *argv[]) { return 1; } - if(action < -1 && *value) + if(action < -1 && *value) { action = 0; + } /* Some simple checks. */ bool found = false; bool warnonremove = false; for(int i = 0; variables[i].name; i++) { - if(strcasecmp(variables[i].name, variable)) + if(strcasecmp(variables[i].name, variable)) { continue; + } found = true; variable = (char *)variables[i].name; @@ -1651,8 +1853,10 @@ static int cmd_config(int argc, char *argv[]) { if(!node && !(variables[i].type & VAR_SERVER)) { node = get_my_name(true); - if(!node) + + if(!node) { return 1; + } } /* Change "add" into "set" for variables that do not allow multiple occurences. @@ -1684,12 +1888,15 @@ static int cmd_config(int argc, char *argv[]) { // Open the right configuration file. char filename[PATH_MAX]; - if(node) + + if(node) { snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, node); - else + } else { snprintf(filename, sizeof(filename), "%s", tinc_conf); + } FILE *f = fopen(filename, "r"); + if(!f) { fprintf(stderr, "Could not open configuration file %s: %s\n", filename, strerror(errno)); return 1; @@ -1701,6 +1908,7 @@ static int cmd_config(int argc, char *argv[]) { if(action >= -1) { snprintf(tmpfile, sizeof(tmpfile), "%s.config.tmp", filename); tf = fopen(tmpfile, "w"); + if(!tf) { fprintf(stderr, "Could not open temporary file %s: %s\n", tmpfile, strerror(errno)); fclose(f); @@ -1726,10 +1934,12 @@ static int cmd_config(int argc, char *argv[]) { len = strcspn(buf2, "\t ="); bvalue = buf2 + len; bvalue += strspn(bvalue, "\t "); + if(*bvalue == '=') { bvalue++; bvalue += strspn(bvalue, "\t "); } + rstrip(bvalue); buf2[len] = '\0'; @@ -1739,34 +1949,39 @@ static int cmd_config(int argc, char *argv[]) { if(action < -1) { found = true; printf("%s\n", bvalue); - // Del + // Del } else if(action == -1) { if(!*value || !strcasecmp(bvalue, value)) { removed = true; continue; } - // Set + + // Set } else if(action == 0) { // Warn if "set" was used for variables that can occur multiple times - if(warnonremove && strcasecmp(bvalue, value)) + if(warnonremove && strcasecmp(bvalue, value)) { fprintf(stderr, "Warning: removing %s = %s\n", variable, bvalue); + } // Already set? Delete the rest... - if(set) + if(set) { continue; + } // Otherwise, replace. if(fprintf(tf, "%s = %s\n", variable, value) < 0) { fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno)); return 1; } + set = true; continue; - // Add + // Add } else if(action > 0) { // Check if we've already seen this variable with the same value - if(!strcasecmp(bvalue, value)) + if(!strcasecmp(bvalue, value)) { found = true; + } } } @@ -1799,7 +2014,7 @@ static int cmd_config(int argc, char *argv[]) { } // Add new variable if necessary. - if((action > 0 && !found)|| (action == 0 && !set)) { + if((action > 0 && !found) || (action == 0 && !set)) { if(fprintf(tf, "%s = %s\n", variable, value) < 0) { fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno)); return 1; @@ -1830,19 +2045,23 @@ static int cmd_config(int argc, char *argv[]) { // Replace the configuration file with the new one #ifdef HAVE_MINGW + if(remove(filename)) { fprintf(stderr, "Error replacing file %s: %s\n", filename, strerror(errno)); return 1; } + #endif + if(rename(tmpfile, filename)) { fprintf(stderr, "Error renaming temporary file %s to configuration file %s: %s\n", tmpfile, filename, strerror(errno)); return 1; } // Silently try notifying a running tincd of changes. - if(connect_tincd(false)) + if(connect_tincd(false)) { sendline(fd, "%d %d", CONTROL, REQ_RELOAD); + } return 0; } @@ -1860,11 +2079,13 @@ static bool try_bind(int port) { char portstr[16]; snprintf(portstr, sizeof(portstr), "%d", port); - if(getaddrinfo(NULL, portstr, &hint, &ai) || !ai) + if(getaddrinfo(NULL, portstr, &hint, &ai) || !ai) { return false; + } for(aip = ai; aip; aip = aip->ai_next) { int fd = socket(ai->ai_family, SOCK_STREAM, IPPROTO_TCP); + if(!fd) { success = false; break; @@ -1872,6 +2093,7 @@ static bool try_bind(int port) { int result = bind(fd, ai->ai_addr, ai->ai_addrlen); closesocket(fd); + if(result) { success = false; break; @@ -1883,17 +2105,20 @@ static bool try_bind(int port) { } int check_port(char *name) { - if(try_bind(655)) + if(try_bind(655)) { return 655; + } fprintf(stderr, "Warning: could not bind to port 655. "); for(int i = 0; i < 100; i++) { int port = 0x1000 + (rand() & 0x7fff); + if(try_bind(port)) { char filename[PATH_MAX]; snprintf(filename, sizeof(filename), "%s" SLASH "hosts" SLASH "%s", confbase, name); FILE *f = fopen(filename, "a"); + if(!f) { fprintf(stderr, "Could not open %s: %s\n", filename, strerror(errno)); fprintf(stderr, "Please change tinc's Port manually.\n"); @@ -1924,15 +2149,19 @@ static int cmd_init(int argc, char *argv[]) { if(tty) { char buf[1024]; fprintf(stderr, "Enter the Name you want your tinc node to have: "); + if(!fgets(buf, sizeof(buf), stdin)) { fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno)); return 1; } + int len = rstrip(buf); + if(!len) { fprintf(stderr, "No name given!\n"); return 1; } + name = strdup(buf); } else { fprintf(stderr, "No Name given!\n"); @@ -1940,6 +2169,7 @@ static int cmd_init(int argc, char *argv[]) { } } else { name = strdup(argv[1]); + if(!*name) { fprintf(stderr, "No Name given!\n"); return 1; @@ -1967,6 +2197,7 @@ static int cmd_init(int argc, char *argv[]) { } FILE *f = fopen(tinc_conf, "w"); + if(!f) { fprintf(stderr, "Could not create file %s: %s\n", tinc_conf, strerror(errno)); return 1; @@ -1976,27 +2207,35 @@ static int cmd_init(int argc, char *argv[]) { fclose(f); #ifndef DISABLE_LEGACY - if(!rsa_keygen(2048, false)) + + if(!rsa_keygen(2048, false)) { return 1; + } + #endif - if(!ed25519_keygen(false)) + if(!ed25519_keygen(false)) { return 1; + } check_port(name); #ifndef HAVE_MINGW char filename[PATH_MAX]; snprintf(filename, sizeof(filename), "%s" SLASH "tinc-up", confbase); + if(access(filename, F_OK)) { FILE *f = fopenmask(filename, "w", 0777); + if(!f) { fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno)); return 1; } + fprintf(f, "#!/bin/sh\n\necho 'Unconfigured tinc-up script, please edit '$0'!'\n\n#ifconfig $INTERFACE netmask \n"); fclose(f); } + #endif return 0; @@ -2005,24 +2244,31 @@ static int cmd_init(int argc, char *argv[]) { static int cmd_generate_keys(int argc, char *argv[]) { #ifdef DISABLE_LEGACY + if(argc > 1) { #else + if(argc > 2) { #endif fprintf(stderr, "Too many arguments!\n"); return 1; } - if(!name) + if(!name) { name = get_my_name(false); + } #ifndef DISABLE_LEGACY - if(!rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true)) + + if(!rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true)) { return 1; + } + #endif - if(!ed25519_keygen(true)) + if(!ed25519_keygen(true)) { return 1; + } return 0; } @@ -2034,8 +2280,9 @@ static int cmd_generate_rsa_keys(int argc, char *argv[]) { return 1; } - if(!name) + if(!name) { name = get_my_name(false); + } return !rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true); } @@ -2047,8 +2294,9 @@ static int cmd_generate_ed25519_keys(int argc, char *argv[]) { return 1; } - if(!name) + if(!name) { name = get_my_name(false); + } return !ed25519_keygen(true); } @@ -2074,8 +2322,9 @@ static int cmd_info(int argc, char *argv[]) { return 1; } - if(!connect_tincd(true)) + if(!connect_tincd(true)) { return 1; + } return info(fd, argv[1]); } @@ -2113,8 +2362,10 @@ static int cmd_edit(int argc, char *argv[]) { if(!*filename) { snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, argv[1]); char *dash = strchr(argv[1], '-'); + if(dash) { *dash++ = 0; + if((strcmp(dash, "up") && strcmp(dash, "down")) || !check_id(argv[1])) { fprintf(stderr, "Invalid configuration filename.\n"); return 1; @@ -2124,18 +2375,21 @@ static int cmd_edit(int argc, char *argv[]) { char *command; #ifndef HAVE_MINGW - xasprintf(&command, "\"%s\" \"%s\"", getenv("VISUAL") ?: getenv("EDITOR") ?: "vi", filename); + xasprintf(&command, "\"%s\" \"%s\"", getenv("VISUAL") ? : getenv("EDITOR") ? : "vi", filename); #else xasprintf(&command, "edit \"%s\"", filename); #endif int result = system(command); free(command); - if(result) + + if(result) { return result; + } // Silently try notifying a running tincd of changes. - if(connect_tincd(false)) + if(connect_tincd(false)) { sendline(fd, "%d %d", CONTROL, REQ_RELOAD); + } return 0; } @@ -2144,6 +2398,7 @@ static int export(const char *name, FILE *out) { char filename[PATH_MAX]; snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, name); FILE *in = fopen(filename, "r"); + if(!in) { fprintf(stderr, "Could not open configuration file %s: %s\n", filename, strerror(errno)); return 1; @@ -2151,9 +2406,11 @@ static int export(const char *name, FILE *out) { fprintf(out, "Name = %s\n", name); char buf[4096]; + while(fgets(buf, sizeof(buf), in)) { - if(strcspn(buf, "\t =") != 4 || strncasecmp(buf, "Name", 4)) + if(strcspn(buf, "\t =") != 4 || strncasecmp(buf, "Name", 4)) { fputs(buf, out); + } } if(ferror(in)) { @@ -2173,12 +2430,16 @@ static int cmd_export(int argc, char *argv[]) { } char *name = get_my_name(true); - if(!name) + + if(!name) { return 1; + } int result = export(name, stdout); - if(!tty) + + if(!tty) { fclose(stdout); + } free(name); return result; @@ -2191,6 +2452,7 @@ static int cmd_export_all(int argc, char *argv[]) { } DIR *dir = opendir(hosts_dir); + if(!dir) { fprintf(stderr, "Could not open host configuration directory %s: %s\n", hosts_dir, strerror(errno)); return 1; @@ -2201,20 +2463,25 @@ static int cmd_export_all(int argc, char *argv[]) { struct dirent *ent; while((ent = readdir(dir))) { - if(!check_id(ent->d_name)) + if(!check_id(ent->d_name)) { continue; + } - if(first) + if(first) { first = false; - else + } else { printf("#---------------------------------------------------------------#\n"); + } result |= export(ent->d_name, stdout); } closedir(dir); - if(!tty) + + if(!tty) { fclose(stdout); + } + return result; } @@ -2242,8 +2509,9 @@ static int cmd_import(int argc, char *argv[]) { return 1; } - if(out) + if(out) { fclose(out); + } snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, name); @@ -2254,6 +2522,7 @@ static int cmd_import(int argc, char *argv[]) { } out = fopen(filename, "w"); + if(!out) { fprintf(stderr, "Error creating configuration file %s: %s\n", filename, strerror(errno)); return 1; @@ -2267,8 +2536,9 @@ static int cmd_import(int argc, char *argv[]) { } - if(!strcmp(buf, "#---------------------------------------------------------------#\n")) + if(!strcmp(buf, "#---------------------------------------------------------------#\n")) { continue; + } if(out) { if(fputs(buf, out) < 0) { @@ -2278,8 +2548,9 @@ static int cmd_import(int argc, char *argv[]) { } } - if(out) + if(out) { fclose(out); + } if(count) { fprintf(stderr, "Imported %d host configuration files.\n", count); @@ -2291,11 +2562,11 @@ static int cmd_import(int argc, char *argv[]) { } static int cmd_exchange(int argc, char *argv[]) { - return cmd_export(argc, argv) ?: cmd_import(argc, argv); + return cmd_export(argc, argv) ? : cmd_import(argc, argv); } static int cmd_exchange_all(int argc, char *argv[]) { - return cmd_export_all(argc, argv) ?: cmd_import(argc, argv); + return cmd_export_all(argc, argv) ? : cmd_import(argc, argv); } static int switch_network(char *name) { @@ -2305,8 +2576,9 @@ static int switch_network(char *name) { return 1; } - if(!check_netname(name, true)) + if(!check_netname(name, true)) { fprintf(stderr, "Warning: unsafe character in netname!\n"); + } } if(fd >= 0) { @@ -2322,8 +2594,8 @@ static int switch_network(char *name) { free(hosts_dir); free(prompt); - xasprintf(&tinc_conf, "%s" SLASH "tinc.conf", confbase); - xasprintf(&hosts_dir, "%s" SLASH "hosts", confbase); + xasprintf(&tinc_conf, "%s" SLASH "tinc.conf", confbase); + xasprintf(&hosts_dir, "%s" SLASH "hosts", confbase); xasprintf(&prompt, "%s> ", identname); return 0; @@ -2335,19 +2607,23 @@ static int cmd_network(int argc, char *argv[]) { return 1; } - if(argc == 2) + if(argc == 2) { return switch_network(argv[1]); + } DIR *dir = opendir(confdir); + if(!dir) { fprintf(stderr, "Could not read directory %s: %s\n", confdir, strerror(errno)); - return 1; - } + return 1; + } struct dirent *ent; + while((ent = readdir(dir))) { - if(*ent->d_name == '.') + if(*ent->d_name == '.') { continue; + } if(!strcmp(ent->d_name, "tinc.conf")) { printf(".\n"); @@ -2356,8 +2632,10 @@ static int cmd_network(int argc, char *argv[]) { char fname[PATH_MAX]; snprintf(fname, sizeof(fname), "%s/%s/tinc.conf", confdir, ent->d_name); - if(!access(fname, R_OK)) + + if(!access(fname, R_OK)) { printf("%s\n", ent->d_name); + } } closedir(dir); @@ -2381,17 +2659,22 @@ static void *readfile(FILE *in, size_t *len) { while(!feof(in)) { size_t read = fread(buf + count, 1, alloced - count, in); - if(!read) + + if(!read) { break; + } + count += read; + if(count >= alloced) { alloced *= 2; buf = xrealloc(buf, alloced); } } - if(len) + if(len) { *len = count; + } return buf; } @@ -2404,13 +2687,16 @@ static int cmd_sign(int argc, char *argv[]) { if(!name) { name = get_my_name(true); - if(!name) + + if(!name) { return 1; + } } char fname[PATH_MAX]; snprintf(fname, sizeof(fname), "%s" SLASH "ed25519_key.priv", confbase); FILE *fp = fopen(fname, "r"); + if(!fp) { fprintf(stderr, "Could not open %s: %s\n", fname, strerror(errno)); return 1; @@ -2430,6 +2716,7 @@ static int cmd_sign(int argc, char *argv[]) { if(argc == 2) { in = fopen(argv[1], "rb"); + if(!in) { fprintf(stderr, "Could not open %s: %s\n", argv[1], strerror(errno)); ecdsa_free(key); @@ -2441,8 +2728,11 @@ static int cmd_sign(int argc, char *argv[]) { size_t len; char *data = readfile(in, &len); - if(in != stdin) + + if(in != stdin) { fclose(in); + } + if(!data) { fprintf(stderr, "Error reading %s: %s\n", argv[1], strerror(errno)); ecdsa_free(key); @@ -2460,12 +2750,14 @@ static int cmd_sign(int argc, char *argv[]) { free(trailer); char sig[87]; + if(!ecdsa_sign(key, data, len + trailer_len, sig)) { fprintf(stderr, "Error generating signature\n"); free(data); ecdsa_free(key); return 1; } + b64encode(sig, sig, 64); ecdsa_free(key); @@ -2488,12 +2780,16 @@ static int cmd_verify(int argc, char *argv[]) { } char *node = argv[1]; + if(!strcmp(node, ".")) { if(!name) { name = get_my_name(true); - if(!name) + + if(!name) { return 1; + } } + node = name; } else if(!strcmp(node, "*")) { node = NULL; @@ -2508,6 +2804,7 @@ static int cmd_verify(int argc, char *argv[]) { if(argc == 3) { in = fopen(argv[2], "rb"); + if(!in) { fprintf(stderr, "Could not open %s: %s\n", argv[2], strerror(errno)); return 1; @@ -2518,14 +2815,18 @@ static int cmd_verify(int argc, char *argv[]) { size_t len; char *data = readfile(in, &len); - if(in != stdin) + + if(in != stdin) { fclose(in); + } + if(!data) { fprintf(stderr, "Error reading %s: %s\n", argv[1], strerror(errno)); return 1; } char *newline = memchr(data, '\n', len); + if(!newline || (newline - data > MAX_STRING_SIZE - 1)) { fprintf(stderr, "Invalid input\n"); free(data); @@ -2551,8 +2852,9 @@ static int cmd_verify(int argc, char *argv[]) { return 1; } - if(!node) + if(!node) { node = signer; + } char *trailer; xasprintf(&trailer, " %s %ld", signer, t); @@ -2567,6 +2869,7 @@ static int cmd_verify(int argc, char *argv[]) { char fname[PATH_MAX]; snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, node); FILE *fp = fopen(fname, "r"); + if(!fp) { fprintf(stderr, "Could not open %s: %s\n", fname, strerror(errno)); free(data); @@ -2574,10 +2877,12 @@ static int cmd_verify(int argc, char *argv[]) { } ecdsa_t *key = get_pubkey(fp); + if(!key) { rewind(fp); key = ecdsa_read_pem_public_key(fp); } + if(!key) { fprintf(stderr, "Could not read public key from %s\n", fname); fclose(fp); @@ -2655,14 +2960,17 @@ static const struct { static char *complete_command(const char *text, int state) { static int i; - if(!state) + if(!state) { i = 0; - else + } else { i++; + } while(commands[i].command) { - if(!commands[i].hidden && !strncasecmp(commands[i].command, text, strlen(text))) + if(!commands[i].hidden && !strncasecmp(commands[i].command, text, strlen(text))) { return xstrdup(commands[i].command); + } + i++; } @@ -2673,14 +2981,17 @@ static char *complete_dump(const char *text, int state) { const char *matches[] = {"reachable", "nodes", "edges", "subnets", "connections", "graph", NULL}; static int i; - if(!state) + if(!state) { i = 0; - else + } else { i++; + } while(matches[i]) { - if(!strncasecmp(matches[i], text, strlen(text))) + if(!strncasecmp(matches[i], text, strlen(text))) { return xstrdup(matches[i]); + } + i++; } @@ -2690,13 +3001,15 @@ static char *complete_dump(const char *text, int state) { static char *complete_config(const char *text, int state) { static int i; - if(!state) + if(!state) { i = 0; - else + } else { i++; + } while(variables[i].name) { char *dot = strchr(text, '.'); + if(dot) { if((variables[i].type & VAR_HOST) && !strncasecmp(variables[i].name, dot + 1, strlen(dot + 1))) { char *match; @@ -2704,9 +3017,11 @@ static char *complete_config(const char *text, int state) { return match; } } else { - if(!strncasecmp(variables[i].name, text, strlen(text))) + if(!strncasecmp(variables[i].name, text, strlen(text))) { return xstrdup(variables[i].name); + } } + i++; } @@ -2715,10 +3030,14 @@ static char *complete_config(const char *text, int state) { static char *complete_info(const char *text, int state) { static int i; + if(!state) { i = 0; - if(!connect_tincd(false)) + + if(!connect_tincd(false)) { return NULL; + } + // Check the list of nodes sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES); sendline(fd, "%d %d", CONTROL, REQ_DUMP_SUBNETS); @@ -2727,12 +3046,15 @@ static char *complete_info(const char *text, int state) { while(recvline(fd, line, sizeof(line))) { char item[4096]; int n = sscanf(line, "%d %d %4095s", &code, &req, item); + if(n == 2) { i++; - if(i >= 2) + + if(i >= 2) { break; - else + } else { continue; + } } if(n != 3) { @@ -2740,8 +3062,9 @@ static char *complete_info(const char *text, int state) { break; } - if(!strncmp(item, text, strlen(text))) + if(!strncmp(item, text, strlen(text))) { return xstrdup(strip_weight(item)); + } } return NULL; @@ -2751,23 +3074,24 @@ static char *complete_nothing(const char *text, int state) { return NULL; } -static char **completion (const char *text, int start, int end) { +static char **completion(const char *text, int start, int end) { char **matches = NULL; - if(!start) + if(!start) { matches = rl_completion_matches(text, complete_command); - else if(!strncasecmp(rl_line_buffer, "dump ", 5)) + } else if(!strncasecmp(rl_line_buffer, "dump ", 5)) { matches = rl_completion_matches(text, complete_dump); - else if(!strncasecmp(rl_line_buffer, "add ", 4)) + } else if(!strncasecmp(rl_line_buffer, "add ", 4)) { matches = rl_completion_matches(text, complete_config); - else if(!strncasecmp(rl_line_buffer, "del ", 4)) + } else if(!strncasecmp(rl_line_buffer, "del ", 4)) { matches = rl_completion_matches(text, complete_config); - else if(!strncasecmp(rl_line_buffer, "get ", 4)) + } else if(!strncasecmp(rl_line_buffer, "get ", 4)) { matches = rl_completion_matches(text, complete_config); - else if(!strncasecmp(rl_line_buffer, "set ", 4)) + } else if(!strncasecmp(rl_line_buffer, "set ", 4)) { matches = rl_completion_matches(text, complete_config); - else if(!strncasecmp(rl_line_buffer, "info ", 5)) + } else if(!strncasecmp(rl_line_buffer, "info ", 5)) { matches = rl_completion_matches(text, complete_info); + } return matches; } @@ -2781,8 +3105,9 @@ static int cmd_shell(int argc, char *argv[]) { int maxargs = argc + 16; char **nargv = xmalloc(maxargs * sizeof(*nargv)); - for(int i = 0; i < argc; i++) + for(int i = 0; i < argc; i++) { nargv[i] = argv[i]; + } #ifdef HAVE_READLINE rl_readline_name = "tinc"; @@ -2794,30 +3119,38 @@ static int cmd_shell(int argc, char *argv[]) { while(true) { #ifdef HAVE_READLINE + if(tty) { free(copy); free(line); rl_basic_word_break_characters = "\t\n "; line = readline(prompt); - if(line) + + if(line) { copy = xstrdup(line); + } } else { line = fgets(buf, sizeof(buf), stdin); } + #else - if(tty) + + if(tty) { fputs(prompt, stdout); + } line = fgets(buf, sizeof(buf), stdin); #endif - if(!line) + if(!line) { break; + } /* Ignore comments */ - if(*line == '#') + if(*line == '#') { continue; + } /* Split */ @@ -2836,8 +3169,9 @@ static int cmd_shell(int argc, char *argv[]) { next = strtok(NULL, " \t\n"); } - if(nargc == argc) + if(nargc == argc) { continue; + } if(!strcasecmp(nargv[argc], "exit") || !strcasecmp(nargv[argc], "quit")) { free(nargv); @@ -2855,8 +3189,11 @@ static int cmd_shell(int argc, char *argv[]) { } #ifdef HAVE_READLINE - if(tty && found) + + if(tty && found) { add_history(copy); + } + #endif if(!found) { @@ -2867,8 +3204,10 @@ static int cmd_shell(int argc, char *argv[]) { free(nargv); - if(tty) + if(tty) { printf("\n"); + } + return result; } @@ -2879,8 +3218,9 @@ int main(int argc, char *argv[]) { orig_argc = argc; tty = isatty(0) && isatty(1); - if(!parse_options(argc, argv)) + if(!parse_options(argc, argv)) { return 1; + } make_names(false); xasprintf(&tinc_conf, "%s" SLASH "tinc.conf", confbase); @@ -2903,17 +3243,20 @@ int main(int argc, char *argv[]) { fprintf(stderr, "System call `%s' failed: %s", "WSAStartup", winerror(GetLastError())); return false; } + #endif srand(time(NULL)); crypto_init(); - if(optind >= argc) + if(optind >= argc) { return cmd_shell(argc, argv); + } for(int i = 0; commands[i].command; i++) { - if(!strcasecmp(argv[optind], commands[i].command)) + if(!strcasecmp(argv[optind], commands[i].command)) { return commands[i].function(argc - optind, argv + optind); + } } fprintf(stderr, "Unknown command `%s'.\n", argv[optind]); diff --git a/src/tincd.c b/src/tincd.c index 2ab9ba7..ab4d921 100644 --- a/src/tincd.c +++ b/src/tincd.c @@ -116,27 +116,27 @@ int main2(int argc, char **argv); static void usage(bool status) { if(status) fprintf(stderr, "Try `%s --help\' for more information.\n", - program_name); + program_name); else { printf("Usage: %s [option]...\n\n", program_name); - printf( " -c, --config=DIR Read configuration options from DIR.\n" - " -D, --no-detach Don't fork and detach.\n" - " -d, --debug[=LEVEL] Increase debug level or set it to LEVEL.\n" - " -n, --net=NETNAME Connect to net NETNAME.\n" + printf(" -c, --config=DIR Read configuration options from DIR.\n" + " -D, --no-detach Don't fork and detach.\n" + " -d, --debug[=LEVEL] Increase debug level or set it to LEVEL.\n" + " -n, --net=NETNAME Connect to net NETNAME.\n" #ifdef HAVE_MLOCKALL - " -L, --mlock Lock tinc into main memory.\n" + " -L, --mlock Lock tinc into main memory.\n" #endif - " --logfile[=FILENAME] Write log entries to a logfile.\n" - " -s --syslog Use syslog instead of stderr with --no-detach.\n" - " --pidfile=FILENAME Write PID and control socket cookie to FILENAME.\n" - " --bypass-security Disables meta protocol security, for debugging.\n" - " -o, --option[HOST.]KEY=VALUE Set global/host configuration value.\n" + " --logfile[=FILENAME] Write log entries to a logfile.\n" + " -s --syslog Use syslog instead of stderr with --no-detach.\n" + " --pidfile=FILENAME Write PID and control socket cookie to FILENAME.\n" + " --bypass-security Disables meta protocol security, for debugging.\n" + " -o, --option[HOST.]KEY=VALUE Set global/host configuration value.\n" #ifndef HAVE_MINGW - " -R, --chroot chroot to NET dir at startup.\n" - " -U, --user=USER setuid to given USER at startup.\n" + " -R, --chroot chroot to NET dir at startup.\n" + " -U, --user=USER setuid to given USER at startup.\n" #endif - " --help Display this help and exit.\n" - " --version Output version information and exit.\n\n"); + " --help Display this help and exit.\n" + " --version Output version information and exit.\n\n"); printf("Report bugs to tinc@tinc-vpn.org.\n"); } } @@ -150,98 +150,112 @@ static bool parse_options(int argc, char **argv) { cmdline_conf = list_alloc((list_action_t)free_config); while((r = getopt_long(argc, argv, "c:DLd::n:so:RU:", long_options, &option_index)) != EOF) { - switch (r) { - case 0: /* long option */ - break; + switch(r) { + case 0: /* long option */ + break; - case 'c': /* config file */ - confbase = xstrdup(optarg); - break; + case 'c': /* config file */ + confbase = xstrdup(optarg); + break; - case 'D': /* no detach */ - do_detach = false; - break; + case 'D': /* no detach */ + do_detach = false; + break; - case 'L': /* no detach */ + case 'L': /* no detach */ #ifndef HAVE_MLOCKALL - logger(DEBUG_ALWAYS, LOG_ERR, "The %s option is not supported on this platform.", argv[optind - 1]); - return false; + logger(DEBUG_ALWAYS, LOG_ERR, "The %s option is not supported on this platform.", argv[optind - 1]); + return false; #else - do_mlock = true; - break; + do_mlock = true; + break; #endif - case 'd': /* increase debug level */ - if(!optarg && optind < argc && *argv[optind] != '-') - optarg = argv[optind++]; - if(optarg) - debug_level = atoi(optarg); - else - debug_level++; - break; - - case 'n': /* net name given */ - netname = xstrdup(optarg); - break; - - case 's': /* syslog */ - use_logfile = false; - use_syslog = true; - break; - - case 'o': /* option */ - cfg = parse_config_line(optarg, NULL, ++lineno); - if (!cfg) - return false; - list_insert_tail(cmdline_conf, cfg); - break; + case 'd': /* increase debug level */ + if(!optarg && optind < argc && *argv[optind] != '-') { + optarg = argv[optind++]; + } -#ifdef HAVE_MINGW - case 'R': - case 'U': - logger(DEBUG_ALWAYS, LOG_ERR, "The %s option is not supported on this platform.", argv[optind - 1]); + if(optarg) { + debug_level = atoi(optarg); + } else { + debug_level++; + } + + break; + + case 'n': /* net name given */ + netname = xstrdup(optarg); + break; + + case 's': /* syslog */ + use_logfile = false; + use_syslog = true; + break; + + case 'o': /* option */ + cfg = parse_config_line(optarg, NULL, ++lineno); + + if(!cfg) { return false; + } + + list_insert_tail(cmdline_conf, cfg); + break; + +#ifdef HAVE_MINGW + + case 'R': + case 'U': + logger(DEBUG_ALWAYS, LOG_ERR, "The %s option is not supported on this platform.", argv[optind - 1]); + return false; #else - case 'R': /* chroot to NETNAME dir */ - do_chroot = true; - break; - case 'U': /* setuid to USER */ - switchuser = optarg; - break; + case 'R': /* chroot to NETNAME dir */ + do_chroot = true; + break; + + case 'U': /* setuid to USER */ + switchuser = optarg; + break; #endif - case 1: /* show help */ - show_help = true; - break; - - case 2: /* show version */ - show_version = true; - break; - - case 3: /* bypass security */ - bypass_security = true; - break; - - case 4: /* write log entries to a file */ - use_syslog = false; - use_logfile = true; - if(!optarg && optind < argc && *argv[optind] != '-') - optarg = argv[optind++]; - if(optarg) - logfilename = xstrdup(optarg); - break; - - case 5: /* open control socket here */ - pidfilename = xstrdup(optarg); - break; - - case '?': /* wrong options */ - usage(true); - return false; + case 1: /* show help */ + show_help = true; + break; + + case 2: /* show version */ + show_version = true; + break; - default: - break; + case 3: /* bypass security */ + bypass_security = true; + break; + + case 4: /* write log entries to a file */ + use_syslog = false; + use_logfile = true; + + if(!optarg && optind < argc && *argv[optind] != '-') { + optarg = argv[optind++]; + } + + if(optarg) { + logfilename = xstrdup(optarg); + } + + break; + + case 5: /* open control socket here */ + pidfilename = xstrdup(optarg); + break; + + case '?': /* wrong options */ + usage(true); + return false; + + default: + break; } } @@ -251,8 +265,9 @@ static bool parse_options(int argc, char **argv) { return false; } - if(!netname && (netname = getenv("NETNAME"))) + if(!netname && (netname = getenv("NETNAME"))) { netname = xstrdup(netname); + } /* netname "." is special: a "top-level name" */ @@ -266,8 +281,9 @@ static bool parse_options(int argc, char **argv) { return false; } - if(netname && !check_netname(netname, true)) + if(netname && !check_netname(netname, true)) { fprintf(stderr, "Warning: unsafe character in netname!\n"); + } return true; } @@ -275,41 +291,51 @@ static bool parse_options(int argc, char **argv) { static bool drop_privs(void) { #ifndef HAVE_MINGW uid_t uid = 0; - if (switchuser) { + + if(switchuser) { struct passwd *pw = getpwnam(switchuser); - if (!pw) { + + if(!pw) { logger(DEBUG_ALWAYS, LOG_ERR, "unknown user `%s'", switchuser); return false; } + uid = pw->pw_uid; - if (initgroups(switchuser, pw->pw_gid) != 0 || - setgid(pw->pw_gid) != 0) { + + if(initgroups(switchuser, pw->pw_gid) != 0 || + setgid(pw->pw_gid) != 0) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "initgroups", strerror(errno)); return false; } + #ifndef __ANDROID__ // Not supported in android NDK endgrent(); endpwent(); #endif } - if (do_chroot) { + + if(do_chroot) { tzset(); /* for proper timestamps in logs */ - if (chroot(confbase) != 0 || chdir("/") != 0) { + + if(chroot(confbase) != 0 || chdir("/") != 0) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "chroot", strerror(errno)); return false; } + free(confbase); confbase = xstrdup(""); } - if (switchuser) - if (setuid(uid) != 0) { + + if(switchuser) + if(setuid(uid) != 0) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setuid", strerror(errno)); return false; } + #endif return true; } @@ -323,8 +349,11 @@ static void stop_handler(void *data, int flags) { static BOOL WINAPI console_ctrl_handler(DWORD type) { logger(DEBUG_ALWAYS, LOG_NOTICE, "Got console shutdown request"); - if (WSASetEvent(stop_io.event) == FALSE) + + if(WSASetEvent(stop_io.event) == FALSE) { abort(); + } + return TRUE; } #else @@ -337,20 +366,21 @@ static BOOL WINAPI console_ctrl_handler(DWORD type) { int main(int argc, char **argv) { program_name = argv[0]; - if(!parse_options(argc, argv)) + if(!parse_options(argc, argv)) { return 1; + } make_names(true); chdir(confbase); if(show_version) { printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE, - BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR); + BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR); printf("Copyright (C) 1998-2016 Ivo Timmermans, Guus Sliepen and others.\n" - "See the AUTHORS file for a complete list.\n\n" - "tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n" - "and you are welcome to redistribute it under certain conditions;\n" - "see the file COPYING for details.\n"); + "See the AUTHORS file for a complete list.\n\n" + "tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n" + "and you are welcome to redistribute it under certain conditions;\n" + "see the file COPYING for details.\n"); return 0; } @@ -361,30 +391,42 @@ int main(int argc, char **argv) { } #ifdef HAVE_MINGW + if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "WSAStartup", winerror(GetLastError())); return 1; } + #else // Check if we got an umbilical fd from the process that started us char *umbstr = getenv("TINC_UMBILICAL"); + if(umbstr) { umbilical = atoi(umbstr); - if(fcntl(umbilical, F_GETFL) < 0) + + if(fcntl(umbilical, F_GETFL) < 0) { umbilical = 0; + } + #ifdef FD_CLOEXEC - if(umbilical) + + if(umbilical) { fcntl(umbilical, F_SETFD, FD_CLOEXEC); + } + #endif } + #endif - openlogger("tinc", use_logfile?LOGMODE_FILE:LOGMODE_STDERR); + openlogger("tinc", use_logfile ? LOGMODE_FILE : LOGMODE_STDERR); g_argv = argv; - if(getenv("LISTEN_PID") && atoi(getenv("LISTEN_PID")) == getpid()) + if(getenv("LISTEN_PID") && atoi(getenv("LISTEN_PID")) == getpid()) { do_detach = false; + } + #ifdef HAVE_UNSETENV unsetenv("LISTEN_PID"); #endif @@ -397,33 +439,43 @@ int main(int argc, char **argv) { srand(now.tv_sec + now.tv_usec); crypto_init(); - if(!read_server_config()) + if(!read_server_config()) { return 1; + } - if(!debug_level) + if(!debug_level) { get_config_int(lookup_config(config_tree, "LogLevel"), &debug_level); + } #ifdef HAVE_LZO + if(lzo_init() != LZO_E_OK) { logger(DEBUG_ALWAYS, LOG_ERR, "Error initializing LZO compressor!"); return 1; } + #endif #ifdef HAVE_MINGW io_add_event(&stop_io, stop_handler, NULL, WSACreateEvent()); - if (stop_io.event == FALSE) + + if(stop_io.event == FALSE) { abort(); + } int result; + if(!do_detach || !init_service()) { SetConsoleCtrlHandler(console_ctrl_handler, TRUE); result = main2(argc, argv); - } else + } else { result = 1; + } - if (WSACloseEvent(stop_io.event) == FALSE) + if(WSACloseEvent(stop_io.event) == FALSE) { abort(); + } + io_del(&stop_io); return result; } @@ -432,40 +484,44 @@ int main2(int argc, char **argv) { #endif char *priority = NULL; - if(!detach()) + if(!detach()) { return 1; + } #ifdef HAVE_MLOCKALL + /* Lock all pages into memory if requested. * This has to be done after daemon()/fork() so it works for child. * No need to do that in parent as it's very short-lived. */ if(do_mlock && mlockall(MCL_CURRENT | MCL_FUTURE) != 0) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "mlockall", - strerror(errno)); + strerror(errno)); return 1; } + #endif /* Setup sockets and open device. */ - if(!setup_network()) + if(!setup_network()) { goto end; + } /* Change process priority */ if(get_config_string(lookup_config(config_tree, "ProcessPriority"), &priority)) { if(!strcasecmp(priority, "Normal")) { - if (setpriority(NORMAL_PRIORITY_CLASS) != 0) { + if(setpriority(NORMAL_PRIORITY_CLASS) != 0) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setpriority", strerror(errno)); goto end; } } else if(!strcasecmp(priority, "Low")) { - if (setpriority(BELOW_NORMAL_PRIORITY_CLASS) != 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setpriority", strerror(errno)); + if(setpriority(BELOW_NORMAL_PRIORITY_CLASS) != 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setpriority", strerror(errno)); goto end; } } else if(!strcasecmp(priority, "High")) { - if (setpriority(HIGH_PRIORITY_CLASS) != 0) { + if(setpriority(HIGH_PRIORITY_CLASS) != 0) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setpriority", strerror(errno)); goto end; } @@ -476,8 +532,9 @@ int main2(int argc, char **argv) { } /* drop privileges */ - if (!drop_privs()) + if(!drop_privs()) { goto end; + } /* Start main loop. It only exits when tinc is killed. */ diff --git a/src/top.c b/src/top.c index 8d9ffb0..792f224 100644 --- a/src/top.c +++ b/src/top.c @@ -68,8 +68,9 @@ static const char *punit = "pkts"; static float pscale = 1; static bool update(int fd) { - if(!sendline(fd, "%d %d", CONTROL, REQ_DUMP_TRAFFIC)) + if(!sendline(fd, "%d %d", CONTROL, REQ_DUMP_TRAFFIC)) { return false; + } gettimeofday(&cur, NULL); @@ -86,25 +87,31 @@ static bool update(int fd) { uint64_t out_packets; uint64_t out_bytes; - for list_each(nodestats_t, ns, &node_list) + for list_each(nodestats_t, ns, &node_list) { ns->known = false; + } while(recvline(fd, line, sizeof(line))) { int n = sscanf(line, "%d %d %4095s %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, &code, &req, name, &in_packets, &in_bytes, &out_packets, &out_bytes); - if(n == 2) + if(n == 2) { return true; + } - if(n != 7) + if(n != 7) { return false; + } nodestats_t *found = NULL; for list_each(nodestats_t, ns, &node_list) { int result = strcmp(name, ns->name); + if(result > 0) { continue; - } if(result == 0) { + } + + if(result == 0) { found = ns; break; } else { @@ -138,21 +145,23 @@ static bool update(int fd) { } static int cmpfloat(float a, float b) { - if(a < b) + if(a < b) { return -1; - else if(a > b) + } else if(a > b) { return 1; - else + } else { return 0; + } } static int cmpu64(uint64_t a, uint64_t b) { - if(a < b) + if(a < b) { return -1; - else if(a > b) + } else if(a > b) { return 1; - else + } else { return 0; + } } static int sortfunc(const void *a, const void *b) { @@ -161,93 +170,120 @@ static int sortfunc(const void *a, const void *b) { int result; switch(sortmode) { - case 1: - if(cumulative) - result = -cmpu64(na->in_packets, nb->in_packets); - else - result = -cmpfloat(na->in_packets_rate, nb->in_packets_rate); - break; - case 2: - if(cumulative) - result = -cmpu64(na->in_bytes, nb->in_bytes); - else - result = -cmpfloat(na->in_bytes_rate, nb->in_bytes_rate); - break; - case 3: - if(cumulative) - result = -cmpu64(na->out_packets, nb->out_packets); - else - result = -cmpfloat(na->out_packets_rate, nb->out_packets_rate); - break; - case 4: - if(cumulative) - result = -cmpu64(na->out_bytes, nb->out_bytes); - else - result = -cmpfloat(na->out_bytes_rate, nb->out_bytes_rate); - break; - case 5: - if(cumulative) - result = -cmpu64(na->in_packets + na->out_packets, nb->in_packets + nb->out_packets); - else - result = -cmpfloat(na->in_packets_rate + na->out_packets_rate, nb->in_packets_rate + nb->out_packets_rate); - break; - case 6: - if(cumulative) - result = -cmpu64(na->in_bytes + na->out_bytes, nb->in_bytes + nb->out_bytes); - else - result = -cmpfloat(na->in_bytes_rate + na->out_bytes_rate, nb->in_bytes_rate + nb->out_bytes_rate); - break; - default: - result = strcmp(na->name, nb->name); - break; + case 1: + if(cumulative) { + result = -cmpu64(na->in_packets, nb->in_packets); + } else { + result = -cmpfloat(na->in_packets_rate, nb->in_packets_rate); + } + + break; + + case 2: + if(cumulative) { + result = -cmpu64(na->in_bytes, nb->in_bytes); + } else { + result = -cmpfloat(na->in_bytes_rate, nb->in_bytes_rate); + } + + break; + + case 3: + if(cumulative) { + result = -cmpu64(na->out_packets, nb->out_packets); + } else { + result = -cmpfloat(na->out_packets_rate, nb->out_packets_rate); + } + + break; + + case 4: + if(cumulative) { + result = -cmpu64(na->out_bytes, nb->out_bytes); + } else { + result = -cmpfloat(na->out_bytes_rate, nb->out_bytes_rate); + } + + break; + + case 5: + if(cumulative) { + result = -cmpu64(na->in_packets + na->out_packets, nb->in_packets + nb->out_packets); + } else { + result = -cmpfloat(na->in_packets_rate + na->out_packets_rate, nb->in_packets_rate + nb->out_packets_rate); + } + + break; + + case 6: + if(cumulative) { + result = -cmpu64(na->in_bytes + na->out_bytes, nb->in_bytes + nb->out_bytes); + } else { + result = -cmpfloat(na->in_bytes_rate + na->out_bytes_rate, nb->in_bytes_rate + nb->out_bytes_rate); + } + + break; + + default: + result = strcmp(na->name, nb->name); + break; } - if(result) + if(result) { return result; - else + } else { return na->i - nb->i; + } } static void redraw(void) { erase(); - mvprintw(0, 0, "Tinc %-16s Nodes: %4d Sort: %-10s %s", netname ?: "", node_list.count, sortname[sortmode], cumulative ? "Cumulative" : "Current"); + mvprintw(0, 0, "Tinc %-16s Nodes: %4d Sort: %-10s %s", netname ? : "", node_list.count, sortname[sortmode], cumulative ? "Cumulative" : "Current"); attrset(A_REVERSE); mvprintw(2, 0, "Node IN %s IN %s OUT %s OUT %s", punit, bunit, punit, bunit); chgat(-1, A_REVERSE, 0, NULL); static nodestats_t **sorted = 0; static int n = 0; + if(changed) { n = 0; sorted = xrealloc(sorted, node_list.count * sizeof(*sorted)); - for list_each(nodestats_t, ns, &node_list) + + for list_each(nodestats_t, ns, &node_list) { sorted[n++] = ns; + } + changed = false; } - for(int i = 0; i < n; i++) + for(int i = 0; i < n; i++) { sorted[i]->i = i; + } - if(sorted) + if(sorted) { qsort(sorted, n, sizeof(*sorted), sortfunc); + } for(int i = 0, row = 3; i < n; i++, row++) { nodestats_t *node = sorted[i]; + if(node->known) - if(node->in_packets_rate || node->out_packets_rate) + if(node->in_packets_rate || node->out_packets_rate) { attrset(A_BOLD); - else + } else { attrset(A_NORMAL); - else + } else { attrset(A_DIM); + } if(cumulative) mvprintw(row, 0, "%-16s %10.0f %10.0f %10.0f %10.0f", - node->name, node->in_packets * pscale, node->in_bytes * bscale, node->out_packets * pscale, node->out_bytes * bscale); + node->name, node->in_packets * pscale, node->in_bytes * bscale, node->out_packets * pscale, node->out_bytes * bscale); else mvprintw(row, 0, "%-16s %10.0f %10.0f %10.0f %10.0f", - node->name, node->in_packets_rate * pscale, node->in_bytes_rate * bscale, node->out_packets_rate * pscale, node->out_bytes_rate * bscale); + node->name, node->in_packets_rate * pscale, node->in_bytes_rate * bscale, node->out_packets_rate * pscale, node->out_bytes_rate * bscale); } attrset(A_NORMAL); @@ -262,77 +298,95 @@ void top(int fd) { bool running = true; while(running) { - if(!update(fd)) + if(!update(fd)) { break; + } redraw(); switch(getch()) { - case 's': { - timeout(-1); - float input = delay * 1e-3; - mvprintw(1, 0, "Change delay from %.1fs to: ", input); - scanw("%f", &input); - if(input < 0.1) - input = 0.1; - delay = input * 1e3; - timeout(delay); - break; + case 's': { + timeout(-1); + float input = delay * 1e-3; + mvprintw(1, 0, "Change delay from %.1fs to: ", input); + scanw("%f", &input); + + if(input < 0.1) { + input = 0.1; } - case 'c': - cumulative = !cumulative; - break; - case 'n': - sortmode = 0; - break; - case 'i': - sortmode = 2; - break; - case 'I': - sortmode = 1; - break; - case 'o': - sortmode = 4; - break; - case 'O': - sortmode = 3; - break; - case 't': - sortmode = 6; - break; - case 'T': - sortmode = 5; - break; - case 'b': - bunit = "bytes"; - bscale = 1; - punit = "pkts"; - pscale = 1; - break; - case 'k': - bunit = "kbyte"; - bscale = 1e-3; - punit = "pkts"; - pscale = 1; - break; - case 'M': - bunit = "Mbyte"; - bscale = 1e-6; - punit = "kpkt"; - pscale = 1e-3; - break; - case 'G': - bunit = "Gbyte"; - bscale = 1e-9; - punit = "Mpkt"; - pscale = 1e-6; - break; - case 'q': - case KEY_BREAK: - running = false; - break; - default: - break; + + delay = input * 1e3; + timeout(delay); + break; + } + + case 'c': + cumulative = !cumulative; + break; + + case 'n': + sortmode = 0; + break; + + case 'i': + sortmode = 2; + break; + + case 'I': + sortmode = 1; + break; + + case 'o': + sortmode = 4; + break; + + case 'O': + sortmode = 3; + break; + + case 't': + sortmode = 6; + break; + + case 'T': + sortmode = 5; + break; + + case 'b': + bunit = "bytes"; + bscale = 1; + punit = "pkts"; + pscale = 1; + break; + + case 'k': + bunit = "kbyte"; + bscale = 1e-3; + punit = "pkts"; + pscale = 1; + break; + + case 'M': + bunit = "Mbyte"; + bscale = 1e-6; + punit = "kpkt"; + pscale = 1e-3; + break; + + case 'G': + bunit = "Gbyte"; + bscale = 1e-9; + punit = "Mpkt"; + pscale = 1e-6; + break; + + case 'q': + case KEY_BREAK: + running = false; + break; + + default: + break; } } diff --git a/src/uml_device.c b/src/uml_device.c index 829e141..406c81d 100644 --- a/src/uml_device.c +++ b/src/uml_device.c @@ -41,10 +41,10 @@ static char *device_info; enum request_type { REQ_NEW_CONTROL }; static struct request { - uint32_t magic; - uint32_t version; - enum request_type type; - struct sockaddr_un sock; + uint32_t magic; + uint32_t version; + enum request_type type; + struct sockaddr_un sock; } request; static struct sockaddr_un data_sun; @@ -59,8 +59,9 @@ static bool setup_device(void) { } name; struct timeval tv; - if(!get_config_string(lookup_config(config_tree, "Device"), &device)) + if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { xasprintf(&device, LOCALSTATEDIR "/run/%s.umlsocket", identname); + } get_config_string(lookup_config(config_tree, "Interface"), &iface); @@ -117,7 +118,7 @@ static bool setup_device(void) { if((listen_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", device_info, - strerror(errno)); + strerror(errno)); return false; } @@ -134,6 +135,7 @@ static bool setup_device(void) { listen_sun.sun_family = AF_UNIX; strncpy(listen_sun.sun_path, device, sizeof(listen_sun.sun_path)); + if(bind(listen_fd, (struct sockaddr *)&listen_sun, sizeof(listen_sun)) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind %s to %s: %s", device_info, device, strerror(errno)); return false; @@ -149,35 +151,44 @@ static bool setup_device(void) { logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); - if(routing_mode == RMODE_ROUTER) + if(routing_mode == RMODE_ROUTER) { overwrite_mac = true; + } return true; } void close_device(void) { if(listen_fd >= 0) { - close(listen_fd); listen_fd = -1; + close(listen_fd); + listen_fd = -1; } if(request_fd >= 0) { - close(request_fd); request_fd = -1; + close(request_fd); + request_fd = -1; } if(data_fd >= 0) { - close(data_fd); data_fd = -1; + close(data_fd); + data_fd = -1; } if(write_fd >= 0) { - close(write_fd); write_fd = -1; + close(write_fd); + write_fd = -1; } unlink(device); - free(device); device = NULL; + free(device); + device = NULL; + if(iface) { - free(iface); iface = NULL; + free(iface); + iface = NULL; } + device_info = NULL; } @@ -185,95 +196,96 @@ static bool read_packet(vpn_packet_t *packet) { int inlen; switch(state) { - case 0: { - struct sockaddr sa; - socklen_t salen = sizeof(sa); + case 0: { + struct sockaddr sa; + socklen_t salen = sizeof(sa); + + request_fd = accept(listen_fd, &sa, &salen); - request_fd = accept(listen_fd, &sa, &salen); - if(request_fd < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not accept connection to %s %s: %s", device_info, device, strerror(errno)); - return false; - } + if(request_fd < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not accept connection to %s %s: %s", device_info, device, strerror(errno)); + return false; + } #ifdef FD_CLOEXEC - fcntl(request_fd, F_SETFD, FD_CLOEXEC); + fcntl(request_fd, F_SETFD, FD_CLOEXEC); #endif - if(fcntl(listen_fd, F_SETFL, O_NONBLOCK) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); - event_exit(); - return false; - } + if(fcntl(listen_fd, F_SETFL, O_NONBLOCK) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); + event_exit(); + return false; + } + + close(listen_fd); + listen_fd = -1; + device_fd = request_fd; + state = 1; + + return false; + } - close(listen_fd); - listen_fd = -1; - device_fd = request_fd; - state = 1; + case 1: { + if((inlen = read(request_fd, &request, sizeof(request))) != sizeof request) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading request from %s %s: %s", device_info, + device, strerror(errno)); + event_exit(); + return false; + } + if(request.magic != 0xfeedface || request.version != 3 || request.type != REQ_NEW_CONTROL) { + logger(DEBUG_ALWAYS, LOG_ERR, "Unknown magic %x, version %d, request type %d from %s %s", + request.magic, request.version, request.type, device_info, device); + event_exit(); return false; } - case 1: { - if((inlen = read(request_fd, &request, sizeof(request))) != sizeof request) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading request from %s %s: %s", device_info, - device, strerror(errno)); - event_exit(); - return false; - } - - if(request.magic != 0xfeedface || request.version != 3 || request.type != REQ_NEW_CONTROL) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unknown magic %x, version %d, request type %d from %s %s", - request.magic, request.version, request.type, device_info, device); - event_exit(); - return false; - } - - if(connect(write_fd, (struct sockkadr *)&request.sock, sizeof(request.sock)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind write %s: %s", device_info, strerror(errno)); - event_exit(); - return false; - } - - write(request_fd, &data_sun, sizeof(data_sun)); - device_fd = data_fd; - - logger(DEBUG_ALWAYS, LOG_INFO, "Connection with UML established"); - - state = 2; + if(connect(write_fd, (struct sockkadr *)&request.sock, sizeof(request.sock)) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind write %s: %s", device_info, strerror(errno)); + event_exit(); return false; } - case 2: { - if((inlen = read(data_fd, DATA(packet), MTU)) <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - event_exit(); - return false; - } + write(request_fd, &data_sun, sizeof(data_sun)); + device_fd = data_fd; - packet->len = inlen; + logger(DEBUG_ALWAYS, LOG_INFO, "Connection with UML established"); - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, - device_info); + state = 2; + return false; + } - return true; + case 2: { + if((inlen = read(data_fd, DATA(packet), MTU)) <= 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, + device, strerror(errno)); + event_exit(); + return false; } - default: - logger(DEBUG_ALWAYS, LOG_ERR, "Invalid value for state variable in " __FILE__); - abort(); + packet->len = inlen; + + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, + device_info); + + return true; + } + + default: + logger(DEBUG_ALWAYS, LOG_ERR, "Invalid value for state variable in " __FILE__); + abort(); } } static bool write_packet(vpn_packet_t *packet) { if(state != 2) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Dropping packet of %d bytes to %s: not connected to UML yet", - packet->len, device_info); + packet->len, device_info); return false; } logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + packet->len, device_info); if(write(write_fd, DATA(packet), packet->len) < 0) { if(errno != EINTR && errno != EAGAIN) { diff --git a/src/upnp.c b/src/upnp.c index e321dcf..3e90210 100644 --- a/src/upnp.c +++ b/src/upnp.c @@ -76,13 +76,16 @@ static void upnp_add_mapping(struct UPNPUrls *urls, struct IGDdatas *data, const // if we're running with Port=0 (dynamically assigned port). sockaddr_t sa; socklen_t salen = sizeof(sa); - if (getsockname(socket, &sa.sa, &salen)) { + + if(getsockname(socket, &sa.sa, &salen)) { logger(DEBUG_PROTOCOL, LOG_ERR, "[upnp] Unable to get socket address: [%d] %s", sockerrno, sockstrerror(sockerrno)); return; } + char *port; sockaddr2str(&sa, NULL, &port); - if (!port) { + + if(!port) { logger(DEBUG_PROTOCOL, LOG_ERR, "[upnp] Unable to get socket port"); return; } @@ -92,7 +95,8 @@ static void upnp_add_mapping(struct UPNPUrls *urls, struct IGDdatas *data, const snprintf(lease_duration, sizeof(lease_duration), "%d", upnp_refresh_period * 2); int error = UPNP_AddPortMapping(urls->controlURL, data->first.servicetype, port, port, myaddr, identname, proto, NULL, lease_duration); - if (error == 0) { + + if(error == 0) { logger(DEBUG_PROTOCOL, LOG_INFO, "[upnp] Successfully set port mapping (%s:%s %s for %s seconds)", myaddr, port, proto, lease_duration); } else { logger(DEBUG_PROTOCOL, LOG_ERR, "[upnp] Failed to set port mapping (%s:%s %s for %s seconds): [%d] %s", myaddr, port, proto, lease_duration, error, strupnperror(error)); @@ -106,26 +110,37 @@ static void upnp_refresh() { int error; struct UPNPDev *devices = upnp_discover(upnp_discover_wait * 1000, &error); - if (!devices) { + + if(!devices) { logger(DEBUG_PROTOCOL, LOG_WARNING, "[upnp] Unable to find IGD devices: [%d] %s", error, strupnperror(error)); freeUPNPDevlist(devices); return; } struct UPNPUrls urls; + struct IGDdatas data; + char myaddr[64]; + int result = UPNP_GetValidIGD(devices, &urls, &data, myaddr, sizeof(myaddr)); - if (result <= 0) { + + if(result <= 0) { logger(DEBUG_PROTOCOL, LOG_WARNING, "[upnp] No IGD found"); freeUPNPDevlist(devices); return; } + logger(DEBUG_PROTOCOL, LOG_INFO, "[upnp] IGD found: [%d] %s (local address: %s, service type: %s)", result, urls.controlURL, myaddr, data.first.servicetype); - for (int i = 0; i < listen_sockets; i++) { - if (upnp_tcp) upnp_add_mapping(&urls, &data, myaddr, listen_socket[i].tcp.fd, "TCP"); - if (upnp_udp) upnp_add_mapping(&urls, &data, myaddr, listen_socket[i].udp.fd, "UDP"); + for(int i = 0; i < listen_sockets; i++) { + if(upnp_tcp) { + upnp_add_mapping(&urls, &data, myaddr, listen_socket[i].tcp.fd, "TCP"); + } + + if(upnp_udp) { + upnp_add_mapping(&urls, &data, myaddr, listen_socket[i].udp.fd, "UDP"); + } } FreeUPNPUrls(&urls); @@ -133,14 +148,17 @@ static void upnp_refresh() { } static void *upnp_thread(void *data) { - while (true) { + while(true) { time_t start = time(NULL); upnp_refresh(); // Make sure we'll stick to the refresh period no matter how long upnp_refresh() takes. time_t refresh_time = start + upnp_refresh_period; time_t now = time(NULL); - if (now < refresh_time) sleep(refresh_time - now); + + if(now < refresh_time) { + sleep(refresh_time - now); + } } // TODO: we don't have a clean thread shutdown procedure, so we can't remove the mapping. @@ -158,7 +176,8 @@ void upnp_init(bool tcp, bool udp) { pthread_t thread; int error = pthread_create(&thread, NULL, upnp_thread, NULL); - if (error) { + + if(error) { logger(DEBUG_ALWAYS, LOG_ERR, "Unable to start UPnP-IGD client thread: [%d] %s", error, strerror(error)); } } diff --git a/src/utils.c b/src/utils.c index 940bc6e..da8c433 100644 --- a/src/utils.c +++ b/src/utils.c @@ -46,26 +46,32 @@ static const char base64_decode[256] = { }; static int charhex2bin(char c) { - if(isdigit(c)) + if(isdigit(c)) { return c - '0'; - else + } else { return toupper(c) - 'A' + 10; + } } int hex2bin(const char *src, void *vdst, int length) { char *dst = vdst; int i; - for(i = 0; i < length && isxdigit(src[i * 2]) && isxdigit(src[i * 2 + 1]); i++) + + for(i = 0; i < length && isxdigit(src[i * 2]) && isxdigit(src[i * 2 + 1]); i++) { dst[i] = charhex2bin(src[i * 2]) * 16 + charhex2bin(src[i * 2 + 1]); + } + return i; } int bin2hex(const void *vsrc, char *dst, int length) { const char *src = vsrc; + for(int i = length - 1; i >= 0; i--) { dst[i * 2 + 1] = hexadecimals[(unsigned char) src[i] & 15]; dst[i * 2] = hexadecimals[(unsigned char) src[i] >> 4]; } + dst[length * 2] = 0; return length * 2; } @@ -77,20 +83,29 @@ int b64decode(const char *src, void *dst, int length) { for(i = 0; i < length && src[i]; i++) { triplet |= base64_decode[src[i] & 0xff] << (6 * (i & 3)); + if((i & 3) == 3) { - if(triplet & 0xff000000U) + if(triplet & 0xff000000U) { return 0; - udst[0] = triplet & 0xff; triplet >>= 8; - udst[1] = triplet & 0xff; triplet >>= 8; + } + + udst[0] = triplet & 0xff; + triplet >>= 8; + udst[1] = triplet & 0xff; + triplet >>= 8; udst[2] = triplet; triplet = 0; udst += 3; } } - if(triplet & 0xff000000U) + + if(triplet & 0xff000000U) { return 0; + } + if((i & 3) == 3) { - udst[0] = triplet & 0xff; triplet >>= 8; + udst[0] = triplet & 0xff; + triplet >>= 8; udst[1] = triplet & 0xff; return i / 4 * 3 + 2; } else if((i & 3) == 2) { @@ -108,34 +123,42 @@ static int b64encode_internal(const void *src, char *dst, int length, const char int di = length / 3 * 4; switch(length % 3) { - case 2: - triplet = usrc[si] | usrc[si + 1] << 8; - dst[di] = alphabet[triplet & 63]; triplet >>= 6; - dst[di + 1] = alphabet[triplet & 63]; triplet >>= 6; - dst[di + 2] = alphabet[triplet]; - dst[di + 3] = 0; - length = di + 3; - break; - case 1: - triplet = usrc[si]; - dst[di] = alphabet[triplet & 63]; triplet >>= 6; - dst[di + 1] = alphabet[triplet]; - dst[di + 2] = 0; - length = di + 2; - break; - default: - dst[di] = 0; - length = di; - break; + case 2: + triplet = usrc[si] | usrc[si + 1] << 8; + dst[di] = alphabet[triplet & 63]; + triplet >>= 6; + dst[di + 1] = alphabet[triplet & 63]; + triplet >>= 6; + dst[di + 2] = alphabet[triplet]; + dst[di + 3] = 0; + length = di + 3; + break; + + case 1: + triplet = usrc[si]; + dst[di] = alphabet[triplet & 63]; + triplet >>= 6; + dst[di + 1] = alphabet[triplet]; + dst[di + 2] = 0; + length = di + 2; + break; + + default: + dst[di] = 0; + length = di; + break; } while(si > 0) { di -= 4; si -= 3; triplet = usrc[si] | usrc[si + 1] << 8 | usrc[si + 2] << 16; - dst[di] = alphabet[triplet & 63]; triplet >>= 6; - dst[di + 1] = alphabet[triplet & 63]; triplet >>= 6; - dst[di + 2] = alphabet[triplet & 63]; triplet >>= 6; + dst[di] = alphabet[triplet & 63]; + triplet >>= 6; + dst[di + 1] = alphabet[triplet & 63]; + triplet >>= 6; + dst[di + 2] = alphabet[triplet & 63]; + triplet >>= 6; dst[di + 3] = alphabet[triplet]; } @@ -160,13 +183,14 @@ const char *winerror(int err) { ptr = buf + snprintf(buf, sizeof(buf), "(%d) ", err); - if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), ptr, sizeof(buf) - (ptr - buf), NULL)) { + if(!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), ptr, sizeof(buf) - (ptr - buf), NULL)) { strncpy(buf, "(unable to format errormessage)", sizeof(buf)); }; - if((ptr = strchr(buf, '\r'))) + if((ptr = strchr(buf, '\r'))) { *ptr = '\0'; + } return buf; } @@ -174,34 +198,45 @@ const char *winerror(int err) { unsigned int bitfield_to_int(const void *bitfield, size_t size) { unsigned int value = 0; - if(size > sizeof(value)) + + if(size > sizeof(value)) { size = sizeof(value); + } + memcpy(&value, bitfield, size); return value; } bool check_id(const char *id) { - if(!id || !*id) + if(!id || !*id) { return false; + } for(; *id; id++) - if(!isalnum(*id) && *id != '_') + if(!isalnum(*id) && *id != '_') { return false; + } return true; } bool check_netname(const char *netname, bool strict) { - if(!netname || !*netname || *netname == '.') + if(!netname || !*netname || *netname == '.') { return false; + } for(const char *c = netname; *c; c++) { - if(iscntrl(*c)) + if(iscntrl(*c)) { return false; - if(*c == '/' || *c == '\\') + } + + if(*c == '/' || *c == '\\') { return false; - if(strict && strchr(" $%<>:`\"|?*", *c)) + } + + if(strict && strchr(" $%<>:`\"|?*", *c)) { return false; + } } return true; @@ -215,30 +250,36 @@ bool check_netname(const char *netname, bool strict) { char *replace_name(const char *name) { char *ret_name; - if (name[0] == '$') { + if(name[0] == '$') { char *envname = getenv(name + 1); - char hostname[HOST_NAME_MAX+1]; - if (!envname) { - if (strcmp(name + 1, "HOST")) { + char hostname[HOST_NAME_MAX + 1]; + + if(!envname) { + if(strcmp(name + 1, "HOST")) { logger(DEBUG_ALWAYS, LOG_ERR, "Invalid Name: environment variable %s does not exist\n", name + 1); return NULL; } - if (gethostname(hostname, sizeof(hostname)) || !*hostname) { + + if(gethostname(hostname, sizeof(hostname)) || !*hostname) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not get hostname: %s\n", sockstrerror(sockerrno)); return NULL; } + hostname[HOST_NAME_MAX] = 0; envname = hostname; } + ret_name = xstrdup(envname); - for (char *c = ret_name; *c; c++) - if (!isalnum(*c)) + + for(char *c = ret_name; *c; c++) + if(!isalnum(*c)) { *c = '_'; + } } else { ret_name = xstrdup(name); } - if (!check_id(ret_name)) { + if(!check_id(ret_name)) { logger(DEBUG_ALWAYS, LOG_ERR, "Invalid name for myself!"); free(ret_name); return NULL; diff --git a/src/vde_device.c b/src/vde_device.c index 73ad713..e2692eb 100644 --- a/src/vde_device.c +++ b/src/vde_device.c @@ -44,8 +44,9 @@ static bool setup_device(void) { return false; } - if(!get_config_string(lookup_config(config_tree, "Device"), &device)) + if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { xasprintf(&device, LOCALSTATEDIR "/run/vde.ctl"); + } get_config_string(lookup_config(config_tree, "Interface"), &iface); @@ -62,6 +63,7 @@ static bool setup_device(void) { }; conn = plug.vde_open(device, identname, &args); + if(!conn) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not open VDE socket %s", device); return false; @@ -75,29 +77,35 @@ static bool setup_device(void) { logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); - if(routing_mode == RMODE_ROUTER) + if(routing_mode == RMODE_ROUTER) { overwrite_mac = true; + } return true; } static void close_device(void) { if(conn) { - plug.vde_close(conn); conn = NULL; + plug.vde_close(conn); + conn = NULL; } - if(plug.dl_handle) + if(plug.dl_handle) { libvdeplug_dynclose(plug); + } - free(device); device = NULL; + free(device); + device = NULL; - free(iface); iface = NULL; + free(iface); + iface = NULL; device_info = NULL; } static bool read_packet(vpn_packet_t *packet) { int lenin = (ssize_t)plug.vde_recv(conn, DATA(packet), MTU, 0); + if(lenin <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); event_exit(); diff --git a/src/version.c b/src/version.c index 325a6f0..d0af1cc 100644 --- a/src/version.c +++ b/src/version.c @@ -1,5 +1,5 @@ /* - version.c -- version information + version.c -- version information Copyright (C) 2014 Etienne Dechamps This program is free software; you can redistribute it and/or modify @@ -22,10 +22,10 @@ #include "../config.h" /* This file is always rebuilt (even if there are no changes) so that the following is updated */ -const char* const BUILD_DATE = __DATE__; -const char* const BUILD_TIME = __TIME__; +const char *const BUILD_DATE = __DATE__; +const char *const BUILD_TIME = __TIME__; #ifdef GIT_DESCRIPTION -const char* const BUILD_VERSION = GIT_DESCRIPTION; +const char *const BUILD_VERSION = GIT_DESCRIPTION; #else -const char* const BUILD_VERSION = VERSION; +const char *const BUILD_VERSION = VERSION; #endif diff --git a/src/version.h b/src/version.h index f34373e..a4cf0a7 100644 --- a/src/version.h +++ b/src/version.h @@ -20,8 +20,8 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -extern const char* const BUILD_DATE; -extern const char* const BUILD_TIME; -extern const char* const BUILD_VERSION; +extern const char *const BUILD_DATE; +extern const char *const BUILD_TIME; +extern const char *const BUILD_VERSION; #endif diff --git a/src/xalloc.h b/src/xalloc.h index 1bde041..493af5c 100644 --- a/src/xalloc.h +++ b/src/xalloc.h @@ -21,34 +21,46 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -static inline void *xmalloc(size_t n) __attribute__ ((__malloc__)); +static inline void *xmalloc(size_t n) __attribute__((__malloc__)); static inline void *xmalloc(size_t n) { void *p = malloc(n); - if(!p) + + if(!p) { abort(); + } + return p; } -static inline void *xzalloc(size_t n) __attribute__ ((__malloc__)); +static inline void *xzalloc(size_t n) __attribute__((__malloc__)); static inline void *xzalloc(size_t n) { void *p = calloc(1, n); - if(!p) + + if(!p) { abort(); + } + return p; } static inline void *xrealloc(void *p, size_t n) { p = realloc(p, n); - if(!p) + + if(!p) { abort(); + } + return p; } -static inline char *xstrdup(const char *s) __attribute__ ((__malloc__)); +static inline char *xstrdup(const char *s) __attribute__((__malloc__)); static inline char *xstrdup(const char *s) { char *p = strdup(s); - if(!p) + + if(!p) { abort(); + } + return p; } @@ -56,18 +68,24 @@ static inline int xvasprintf(char **strp, const char *fmt, va_list ap) { #ifdef HAVE_MINGW char buf[1024]; int result = vsnprintf(buf, sizeof(buf), fmt, ap); - if(result < 0) + + if(result < 0) { abort(); + } + *strp = xstrdup(buf); #else int result = vasprintf(strp, fmt, ap); - if(result < 0) + + if(result < 0) { abort(); + } + #endif return result; } -static inline int xasprintf(char **strp, const char *fmt, ...) __attribute__ ((__format__(printf, 2, 3))); +static inline int xasprintf(char **strp, const char *fmt, ...) __attribute__((__format__(printf, 2, 3))); static inline int xasprintf(char **strp, const char *fmt, ...) { va_list ap; va_start(ap, fmt); diff --git a/test/pong.c b/test/pong.c index 24a215c..e0d8b09 100644 --- a/test/pong.c +++ b/test/pong.c @@ -28,12 +28,14 @@ static ssize_t do_arp(uint8_t *buf, ssize_t len, struct sockaddr_in *in) { memcpy(&arp, buf + 14, sizeof(arp)); // Is it a valid ARP request? - if(ntohs(arp.arp_hrd) != ARPHRD_ETHER || ntohs(arp.arp_pro) != ETH_P_IP || arp.arp_hln != ETH_ALEN || arp.arp_pln != sizeof(in->sin_addr.s_addr) || ntohs(arp.arp_op) != ARPOP_REQUEST) + if(ntohs(arp.arp_hrd) != ARPHRD_ETHER || ntohs(arp.arp_pro) != ETH_P_IP || arp.arp_hln != ETH_ALEN || arp.arp_pln != sizeof(in->sin_addr.s_addr) || ntohs(arp.arp_op) != ARPOP_REQUEST) { return 0; + } // Does it match our address? - if(memcmp(&in->sin_addr.s_addr, arp.arp_tpa, 4)) + if(memcmp(&in->sin_addr.s_addr, arp.arp_tpa, 4)) { return 0; + } // Swap addresses memcpy(buf, buf + 6, 6); @@ -55,20 +57,26 @@ static ssize_t do_ipv4(uint8_t *buf, ssize_t len, struct sockaddr_in *in) { struct icmp icmp; // Does it match our address? - if(memcmp(buf, mymac, 6)) + if(memcmp(buf, mymac, 6)) { return 0; + } memcpy(&ip, buf + 14, sizeof(ip)); - if(memcmp(&ip.ip_dst, &in->sin_addr.s_addr, 4)) + + if(memcmp(&ip.ip_dst, &in->sin_addr.s_addr, 4)) { return 0; + } // Is it an ICMP echo request? - if(ip.ip_p != IPPROTO_ICMP) + if(ip.ip_p != IPPROTO_ICMP) { return 0; + } memcpy(&icmp, buf + 14 + sizeof(ip), sizeof icmp); - if(icmp.icmp_type != ICMP_ECHO) + + if(icmp.icmp_type != ICMP_ECHO) { return 0; + } // Return an echo reply memcpy(buf, buf + 6, 6); @@ -100,6 +108,7 @@ int main(int argc, char *argv[]) { hints.ai_flags = AI_ADDRCONFIG; errno = ENOENT; + if(getaddrinfo(argv[1], argv[2], &hints, &ai) || !ai) { fprintf(stderr, "Could not resolve %s port %s: %s\n", argv[1], argv[2], strerror(errno)); return 1; @@ -107,6 +116,7 @@ int main(int argc, char *argv[]) { int fd; fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if(!fd) { fprintf(stderr, "Could not create socket: %s\n", strerror(errno)); return 1; @@ -121,45 +131,53 @@ int main(int argc, char *argv[]) { } switch(ai->ai_family) { - case AF_INET: { - struct ip_mreq mreq; - struct sockaddr_in in; - memcpy(&in, ai->ai_addr, sizeof(in)); - mreq.imr_multiaddr.s_addr = in.sin_addr.s_addr; - mreq.imr_interface.s_addr = htonl(INADDR_ANY); - if(setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&mreq, sizeof(mreq))) { - fprintf(stderr, "Cannot join multicast group: %s\n", strerror(errno)); - return 1; - } + case AF_INET: { + struct ip_mreq mreq; + struct sockaddr_in in; + memcpy(&in, ai->ai_addr, sizeof(in)); + mreq.imr_multiaddr.s_addr = in.sin_addr.s_addr; + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + + if(setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&mreq, sizeof(mreq))) { + fprintf(stderr, "Cannot join multicast group: %s\n", strerror(errno)); + return 1; + } + #ifdef IP_MULTICAST_LOOP - setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, (const void *)&one, sizeof(one)); + setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, (const void *)&one, sizeof(one)); #endif - } break; + } + break; #ifdef IPV6_JOIN_GROUP - case AF_INET6: { - struct ipv6_mreq mreq; - struct sockaddr_in6 in6; - memcpy(&in6, ai->ai_addr, sizeof(in6)); - memcpy(&mreq.ipv6mr_multiaddr, &in6.sin6_addr, sizeof(mreq.ipv6mr_multiaddr)); - mreq.ipv6mr_interface = in6.sin6_scope_id; - if(setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, (void *)&mreq, sizeof(mreq))) { - fprintf(stderr, "Cannot join multicast group: %s\n", strerror(errno)); - return 1; - } + + case AF_INET6: { + struct ipv6_mreq mreq; + struct sockaddr_in6 in6; + memcpy(&in6, ai->ai_addr, sizeof(in6)); + memcpy(&mreq.ipv6mr_multiaddr, &in6.sin6_addr, sizeof(mreq.ipv6mr_multiaddr)); + mreq.ipv6mr_interface = in6.sin6_scope_id; + + if(setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, (void *)&mreq, sizeof(mreq))) { + fprintf(stderr, "Cannot join multicast group: %s\n", strerror(errno)); + return 1; + } + #ifdef IPV6_MULTICAST_LOOP - setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (const void *)&one, sizeof(one)); + setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (const void *)&one, sizeof(one)); #endif - } break; + } + break; #endif - default: - fprintf(stderr, "Multicast for address family %x unsupported\n", ai->ai_family); - return 1; + default: + fprintf(stderr, "Multicast for address family %x unsupported\n", ai->ai_family); + return 1; } errno = ENOENT; struct addrinfo *ai2 = NULL; + if(getaddrinfo(argv[3], NULL, &hints, &ai2) || !ai2) { fprintf(stderr, "Could not resolve %s: %s\n", argv[3], strerror(errno)); return 1; @@ -170,26 +188,31 @@ int main(int argc, char *argv[]) { struct sockaddr src; socklen_t srclen; ssize_t len = recvfrom(fd, buf, sizeof(buf), 0, &src, &srclen); - if(len <= 0) + + if(len <= 0) { break; + } // Ignore short packets. - if(len < 14) + if(len < 14) { continue; + } uint16_t type = buf[12] << 8 | buf[13]; - if(ai2->ai_family == AF_INET && type == ETH_P_IP) + if(ai2->ai_family == AF_INET && type == ETH_P_IP) { len = do_ipv4(buf, len, (struct sockaddr_in *)ai2->ai_addr); - else if(ai2->ai_family == AF_INET && type == ETH_P_ARP) + } else if(ai2->ai_family == AF_INET && type == ETH_P_ARP) { len = do_arp(buf, len, (struct sockaddr_in *)ai2->ai_addr); - else if(ai2->ai_family == AF_INET6 && type == ETH_P_IPV6) + } else if(ai2->ai_family == AF_INET6 && type == ETH_P_IPV6) { len = do_ipv6(buf, len, (struct sockaddr_in6 *)ai2->ai_addr); - else + } else { continue; + } - if(len > 0) + if(len > 0) { sendto(fd, buf, len, 0, ai->ai_addr, ai->ai_addrlen); + } } return 0;