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;
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));
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);
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;
}
}
- if(found)
+ if(found) {
continue;
+ }
logger(DEBUG_CONNECTIONS, LOG_INFO, "Cancelled outgoing connection to %s", o->name);
list_delete_node(outgoing_list, node);
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. */
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. */
#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) {
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 = {
char name[64] = "";
socklen_t len = sizeof(name);
+
if(getsockopt(device_fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, name, &len)) {
iface = xstrdup(device);
} else {
// 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) {
// 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) {
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)
{
}
#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);
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;
}
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;
#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;
};
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;
}
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;
}
return 0;
}
-static int open_pcap()
-{
- if (pcap != NULL)
- {
+static int open_pcap() {
+ if(pcap != NULL) {
pcap_use_count++;
return 0;
}
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;
}
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;
}
}
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;
}
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;
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;
}
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;
// 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);
}
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];
/*
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];
/*
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;
}
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);
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);
}
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];
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;
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)
QUARTERROUND(x2, x7, x8, x13)
QUARTERROUND(x3, x4, x9, x14)
}
+
x0 = PLUS(x0, j0);
x1 = PLUS(x1, j1);
x2 = PLUS(x2, j2);
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 */
}
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;
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 */
-/*
+/*
* Public Domain poly1305 from Andrew Moon
* poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna
*/
} 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;
h4 = 0;
/* full blocks */
- if (inlen < 16)
+ if(inlen < 16) {
goto poly1305_donna_atmost15bytes;
+ }
- poly1305_donna_16bytes:
+poly1305_donna_16bytes:
m += 16;
inlen -= 16;
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);
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);
goto poly1305_donna_mul;
- poly1305_donna_finish:
+poly1305_donna_finish:
b = h0 >> 26;
h0 = h0 & 0x3ffffff;
h1 += b;
/* $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
*/
#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 */
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 *);
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;
}
}
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);
}
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;
}
if(node->next) {
found = node->next->data;
- if(!strcasecmp(found->variable, cfg->variable))
+ if(!strcasecmp(found->variable, cfg->variable)) {
return found;
+ }
}
}
}
bool get_config_bool(const config_t *cfg, bool *result) {
- if(!cfg)
+ if(!cfg) {
return false;
+ }
if(!strcasecmp(cfg->value, "yes")) {
*result = true;
}
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);
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);
}
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;
}
/*
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;
}
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;
}
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;
}
}
cfg = parse_config_line(line, fname, lineno);
- if (!cfg)
+
+ if(!cfg) {
break;
+ }
+
config_add(config_tree, cfg);
}
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;
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;
}
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 *);
}
void free_connection(connection_t *c) {
- if(!c)
+ if(!c) {
return;
+ }
#ifndef DISABLE_LEGACY
cipher_close(c->incipher);
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);
}
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);
#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"
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 */
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 *);
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);
}
}
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);
#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) {
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 */
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;
return false;
}
- if(!device)
+ if(!device) {
device = xstrdup(adapterid);
+ }
- if(!iface)
+ if(!iface) {
iface = xstrdup(adaptername);
+ }
snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, device);
/* 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()));
}
read(device_fd, &gelukt, 1);
+
if(gelukt != 1) {
logger(DEBUG_ALWAYS, LOG_DEBUG, "Tap reader failed!");
return false;
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;
}
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;
}
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;
}
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 *);
}
/* If we are the parent, terminate */
- if(pid)
+ if(pid) {
exit(0);
+ }
/* Detach by becoming the new process group leader */
if(setsid() < 0) {
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;
#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
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
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);
#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
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);
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;
} else {
errno = ENOENT;
}
+
return false;
}
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;
}
fprintf(fp, "-----BEGIN %s-----\n", type);
char base64[65];
+
while(size) {
size_t todo = size > 48 ? 48 : size;
b64encode(buf, base64, todo);
#include <stddef.h>
#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
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;
}
*/
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;
}
*/
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;
}
*/
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;
}
*/
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;
}
/*
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;
}
*/
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;
}
*/
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);
}
*/
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;
}
*/
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;
}
|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;
}
*/
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;
}
*/
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;
}
*/
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;
}
*/
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;
}
*/
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;
}
*/
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);
}
*/
#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 <stdint.h>
- #define FIXEDINT_H_INCLUDED
+#include <stdint.h>
+#define FIXEDINT_H_INCLUDED
- #if defined(__WATCOMC__) && __WATCOMC__ >= 1250 && !defined(UINT64_C)
- #include <limits.h>
- #define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX))
- #endif
+#if defined(__WATCOMC__) && __WATCOMC__ >= 1250 && !defined(UINT64_C)
+#include <limits.h>
+#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) {
*/
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;
+ }
+ }
+ }
+ }
}
/*
*/
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;
}
*/
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);
}
*/
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);
}
*/
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);
}
*/
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);
}
*/
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);
}
*/
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);
}
*/
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);
}
*/
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);
}
/*
*/
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);
+ }
}
*/
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;
}
*/
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);
#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);
}
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);
}
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 },
+ },
+ },
};
#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;
}
/*
*/
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);
}
*/
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);
}
/* 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)))
#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;
}
@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;
}
/**
@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;
}
/**
@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;
}
/* 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
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);
}
#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;
}
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);
}
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);
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);
}
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 *);
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
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
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
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;
}
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;
io_set(io, flags);
- if(!splay_insert_node(&io_tree, &io->node))
+ if(!splay_insert_node(&io_tree, &io->node)) {
abort();
+ }
}
#ifdef HAVE_MINGW
#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
}
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
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);
}
#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;
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;
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
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;
}
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++;
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
*/
}
}
+
#endif
return true;
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);
}
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;
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;
#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);
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;
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)) {
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;
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);
}
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;
}
} 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");
}
#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;
}
} 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");
}
#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
// 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;
rsa_t *rsa_pub = NULL;
f = fopen(fname, "r");
+
if(f) {
rsa_pub = rsa_read_pem_public_key(f);
fclose(f);
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));
} 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));
} 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);
}
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;
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;
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;
uint8_t pad[cipher->blklen];
if(cipher->padding) {
- if(!oneshot)
+ if(!oneshot) {
return false;
+ }
size_t reqlen = ((inlen + cipher->blklen) / cipher->blklen) * cipher->blklen;
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));
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));
}
if(cipher->padding) {
- if(!oneshot)
+ if(!oneshot) {
return false;
+ }
uint8_t padbyte = ((uint8_t *)outdata)[inlen - 1];
}
*outlen = origlen;
- } else
+ } else {
*outlen = inlen;
+ }
return true;
}
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;
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;
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;
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;
}
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);
}
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];
#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;
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;
}
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;
// 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
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;
}
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;
}
}
- if(outsize)
+ if(outsize) {
*outsize = j;
+ }
+
return true;
}
// 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)--;
}
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;
size_t len = ber_read_len(p, buflen);
if(tag == 0x10) {
- if(result)
+ if(result) {
*result = len;
+ }
+
return true;
} else {
return false;
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;
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));
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));
}
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;
}
}
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;
}
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;
}
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;
}
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';
}
if(size % 3 > 0) {
- if(size % 3 > 1)
+ if(size % 3 > 1) {
line[j++] = '=';
+ }
+
line[j++] = '=';
}
// 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 {
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);
}
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;
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;
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;
}
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
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.
/* 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 <stdlib.h>
#include <unistd.h>
-#endif /* GNU C library. */
+#endif /* GNU C library. */
#ifdef VMS
#include <unixlib.h>
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;
\f
-#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 <string.h>
-#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.
#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__ */
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)
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;
}
\f
/* Scan elements of ARGV (whose length is ARGC) for option characters
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. */
\f
#ifdef TEST
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 */
#ifndef _GETOPT_H
#define _GETOPT_H 1
-#ifdef __cplusplus
+#ifdef __cplusplus
extern "C" {
#endif
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
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
#include <stdlib.h>
#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.
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. */
\f
#ifdef TEST
#include <stdio.h>
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 */
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 */
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);
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.
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;
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);
}
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;
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;
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();
+ }
}
}
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 */
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;
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));
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);
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
}
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
}
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;
}
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");
}
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);
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;
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;
}
if(!found) {
- if(address)
+ if(address) {
fprintf(stderr, "Unknown address %s.\n", item);
- else
+ } else {
fprintf(stderr, "Unknown subnet %s.\n", item);
+ }
+
return 1;
}
}
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;
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;
*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);
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");
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;
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)) {
}
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;
}
hostname = xstrdup(line);
save:
+
if(*filename) {
FILE *f = fopen(filename, "a");
+
if(f) {
fprintf(f, "\nAddress = %s\n", hostname);
fclose(f);
}
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);
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;
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;
}
}
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;
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) {
}
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;
// 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;
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;
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));
}
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];
// 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);
}
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;
}
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;
}
// 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");
static bool finalize_join(void) {
char *name = xstrdup(get_value(data, "Name"));
+
if(!name) {
fprintf(stderr, "No Name found in invitation!\n");
return false;
if(!netname) {
netname = grep(data, "NetName");
+
if(netname && !check_netname(netname, true)) {
fprintf(stderr, "Unsafe NetName found in invitation!\n");
return false;
char temp_netname[32];
make_names:
+
if(!confbasegiven) {
free(confbase);
confbase = NULL;
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));
}
FILE *f = fopen(tinc_conf, "w");
+
if(!f) {
fprintf(stderr, "Could not create file %s: %s\n", tinc_conf, strerror(errno));
return false;
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);
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);
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);
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;
}
// 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);
}
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;
}
// 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");
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;
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());
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);
}
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;
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;
}
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;
// 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));
// 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);
#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;
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
#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
#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
} 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
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
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
struct nd_opt_hdr {
uint8_t nd_opt_type;
uint8_t nd_opt_len;
-} __attribute__ ((__gcc_struct__, __packed__));
+} __attribute__((__gcc_struct__, __packed__));
#endif
#endif
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);
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)";
/* 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);
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;
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;
}
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;
}
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);
}
node->next = list->head;
list->head = node;
- if(node->next)
+ if(node->next) {
node->next->prev = node;
- else
+ } else {
list->tail = node;
+ }
list->count++;
node->prev = list->tail;
list->tail = node;
- if(node->prev)
+ if(node->prev) {
node->prev->next = node;
- else
+ } else {
list->head = node;
+ }
list->count++;
node->prev = after;
after->next = node;
- if(node->next)
+ if(node->next) {
node->next->prev = node;
- else
+ } else {
list->tail = node;
+ }
list->count++;
node->prev = before->prev;
before->prev = node;
- if(node->prev)
+ if(node->prev) {
node->prev->next = node;
- else
+ } else {
list->head = node;
+ }
list->count++;
}
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--;
}
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);
}
/* 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);
+ }
}
/* (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 *);
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) {
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;
}
}
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);
}
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);
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;
}
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;
}
}
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
}
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;
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);
}
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);
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) {
}
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;
/* 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 */
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;
}
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;
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;
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);
#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;
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;
}
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) {
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 {
/* 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;
//=============
#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)
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;
}
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;
}
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 */
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;
return false;
}
- if(!device)
+ if(!device) {
device = xstrdup(adapterid);
+ }
- if(!iface)
+ if(!iface) {
iface = xstrdup(adaptername);
+ }
/* Try to open the corresponding tap device */
{
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.");
}
}
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;
}
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;
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;
}
host = xstrdup(device);
space = strchr(host, ' ');
+
if(!space) {
logger(DEBUG_ALWAYS, LOG_ERR, "Port number required for %s", device_info);
goto error;
}
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;
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);
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;
}
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;
}
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;
}
#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);
+ }
}
}
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);
}
}
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);
+ }
}
}
}
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;
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);
}
}
/* 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
}
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);
}
// 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;
}
// 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) {
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;
/* 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;
}
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) {
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 {
/* 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);
/* 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
+ });
}
/*
*/
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};
#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;
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;
}
/* 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);
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);
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) {
} 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 {
} 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;
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;
}
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
} 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;
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;
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;
}
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)) {
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;
+ }
}
}
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 */
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
}
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;
/* 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. */
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;
}
}
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;
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) {
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;
}
*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;
}
}
- 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);
return;
}
- if(n->status.sptps)
+ if(n->status.sptps) {
return send_sptps_packet(n, origpkt);
+ }
#ifdef DISABLE_LEGACY
return;
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;
}
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;
}
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;
}
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:
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));
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. */
}
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));
from->status.waitingforkey = false;
logger(DEBUG_META, LOG_INFO, "SPTPS key exchange with %s (%s) succesful", from->name, from->hostname);
}
+
return true;
}
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;
}
}
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;
/* 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;
// 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;
// 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. */
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;
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;
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);
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);
#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;
*/
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;
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;
+ }
}
}
/* 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;
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++;
+ }
}
}
/* 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. */
/* 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. */
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) {
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);
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;
}
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;
}
}
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;
}
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;
}
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;
+ }
}
}
}
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;
}
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;
}
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;
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. */
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) {
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 = {};
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;
}
} else {
usleep(errors * 50000);
errors++;
+
if(errors > 10) {
logger(DEBUG_ALWAYS, LOG_ERR, "Too many errors from %s, exiting!", device);
event_exit();
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;
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 */
/* 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);
}
bool read_ecdsa_public_key(connection_t *c) {
- if(ecdsa_active(c->ecdsa))
+ if(ecdsa_active(c->ecdsa)) {
return true;
+ }
FILE *fp;
char *fname;
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 */
/* 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);
/* 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");
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;
}
/* 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;
}
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;
}
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;
free(d);
return false;
}
+
myself->connection->rsa = rsa_set_hex_private_key(n, "FFFF", d);
free(n);
free(d);
/* 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;
}
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;
}
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) {
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);
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;
}
}
- if(lookup_config(config_tree, "Address"))
+ if(lookup_config(config_tree, "Address")) {
n->status.has_address = true;
+ }
exit_configuration(&config_tree);
}
get_config_string(lookup_config(config_tree, "Name"), &name);
- if(!name)
+ if(!name) {
return NULL;
+ }
returned_name = replace_name(name);
free(name);
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;
}
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);
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
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();
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) {
break;
}
- if(found)
+ if(found) {
continue;
+ }
if(listen_sockets >= MAXSOCKETS) {
logger(DEBUG_ALWAYS, LOG_ERR, "Too many listening sockets");
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);
}
void device_enable(void) {
- if (devops.enable)
+ if(devops.enable) {
devops.enable();
+ }
/* Run tinc-up script to further initialize the tap interface */
execute_script("tinc-down", &env);
environment_exit(&env);
- if (devops.disable)
+ if(devops.disable) {
devops.disable();
+ }
}
/*
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;
#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()) {
return false;
}
}
+
#endif
/* Ensure myport is numeric */
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);
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);
}
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;
}
#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;
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... */
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;
logger(DEBUG_ALWAYS, LOG_ERR, "Bogus compression level!");
return false;
}
- } else
+ } else {
myself->incompression = 0;
+ }
myself->connection->outcompression = 0;
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 */
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;
#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);
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) {
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");
+ }
}
}
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
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 */
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);
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();
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)
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));
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
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));
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;
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
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));
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)
#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;
}
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);
}
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!");
}
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);
}
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) {
| 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;
}
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) {
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);
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);
}
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;
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);
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);
} 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);
}
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;
}
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));
if(n && n->connection) {
logger(DEBUG_CONNECTIONS, LOG_INFO, "Already connected to %s", outgoing->name);
+
if(!n->connection->outgoing) {
n->connection->outgoing = outgoing;
return;
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;
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++;
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++;
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);
}
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. */
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;
}
/* 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);
+ }
}
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;
}
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) {
}
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));
}
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();
}
}
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();
}
}
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;
}
}
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 *);
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;
}
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;
}
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);
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);
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);
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);
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);
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);
}
#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 {
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 */
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 */
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 *);
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();
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;
}
#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;
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;
}
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;
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;
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;
}
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);
}
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);
}
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);
}
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;
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;
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;
}
}
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;
}
}
}
int cipher_get_nid(const cipher_t *cipher) {
- if(!cipher || !cipher->cipher)
+ if(!cipher || !cipher->cipher) {
return 0;
+ }
return EVP_CIPHER_nid(cipher->cipher);
}
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();
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;
}
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;
}
}
void digest_close(digest_t *digest) {
- if(!digest)
+ if(!digest) {
return;
+ }
free(digest->key);
free(digest);
}
} 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;
}
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;
}
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);
}
/* 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;
}
#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
}
rsa_t *rsa = RSA_new();
- if(!rsa)
+
+ if(!rsa) {
return NULL;
-
+ }
+
RSA_set0_key(rsa, bn_n, bn_e, NULL);
return rsa;
}
rsa_t *rsa = RSA_new();
- if(!rsa)
+
+ if(!rsa) {
return NULL;
+ }
RSA_set0_key(rsa, bn_n, bn_e, bn_d);
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;
}
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;
}
}
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;
}
void rsa_free(rsa_t *rsa) {
- if(rsa)
+ if(rsa) {
RSA_free(rsa);
+ }
}
/* 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;
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);
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
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;
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) {
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;
}
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;
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;
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;
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;
}
/* 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;
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;
}
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) {
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");
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 {
}
static void free_past_request(past_request_t *r) {
- if(r->request)
+ if(r->request) {
free((char *)r->request);
+ }
free(r);
}
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) {
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;
}
}
/* 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 *);
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);
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;
}
}
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);
}
// 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;
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);
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);
// 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;
// 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;
// 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)) {
// 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);
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;
}
}
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;
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;
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;
}
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);
}
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);
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;
}
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 {
#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
*/
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];
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);
/* 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;
#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;
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 */
#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);
/* 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 */
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;
}
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);
}
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. */
/* 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));
}
}
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);
+ }
}
}
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;
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;
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;
}
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;
}
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 */
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 */
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;
/* 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 */
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);
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;
}
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 */
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;
}
/* 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 */
// 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);
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);
}
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;
}
} 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;
/* Tell the rest about the new edge */
- if(!tunnelserver)
+ if(!tunnelserver) {
forward_request(c, request);
+ }
/* Run MST before or after we tell the rest? */
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) {
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;
}
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 */
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;
}
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;
/* Tell the rest about the deleted edge */
- if(!tunnelserver)
+ if(!tunnelserver) {
forward_request(c, request);
+ }
/* Delete the edge */
if(!to->status.reachable) {
e = lookup_edge(to, myself);
+
if(e) {
- if(!tunnelserver)
+ if(!tunnelserver) {
send_del_edge(everyone, e);
+ }
+
edge_del(e);
}
}
/* 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);
+ }
}
}
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;
}
/* Tell the others */
- if(!tunnelserver)
+ if(!tunnelserver) {
forward_request(c, request);
+ }
return true;
}
/* 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;
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);
}
/* 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;
}
}
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;
}
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;
}
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;
}
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);
}
}
bool send_ans_key(node_t *to) {
- if(to->status.sptps)
+ if(to->status.sptps) {
abort();
+ }
#ifdef DISABLE_LEGACY
return false;
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;
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
}
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;
}
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;
}
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;
}
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);
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
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;
}
/* 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;
/* 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);
}
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);
}
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;
}
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;
}
/* 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);
}
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;
}
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;
}
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;
}
/* 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
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];
}
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;
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;
/* 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;
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,
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;
}
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;
}
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;
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);
}
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;
}
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;
}
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 */
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;
}
/* 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;
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;
}
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;
}
*(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;
}
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);
}
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;
}
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;
}
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 */
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;
}
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;
}
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);
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;
}
#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;
}
}
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;
}
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;
}
len -= 2;
}
- if(len)
+ if(len) {
checksum += *(uint8_t *)p;
+ }
- while(checksum >> 16)
+ while(checksum >> 16) {
checksum = (checksum & 0xFFFF) + (checksum >> 16);
+ }
return ~checksum;
}
static int count = 0;
if(lasttime == now.tv_sec) {
- if(count >= frequency)
+ if(count >= frequency) {
return true;
+ }
} else {
lasttime = now.tv_sec;
count = 0;
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) {
struct in_addr ip_dst;
uint32_t oldlen;
- if(ratelimit(3))
+ if(ratelimit(3)) {
return;
+ }
/* Swap Ethernet source and destination addresses */
/* 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 */
uint32_t next;
} pseudo;
- if(ratelimit(3))
+ if(ratelimit(3)) {
return;
+ }
/* Swap Ethernet source and destination addresses */
/* 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 */
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;
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);
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) {
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;
/* 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);
}
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;
}
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;
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;
}
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;
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);
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);
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;
}
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;
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);
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;
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;
}
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);
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 */
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;
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);
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);
}
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);
/* 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 */
/* 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;
}
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 */
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);
} else {
fragment_ipv4_packet(via, packet, ethlen);
}
+
return;
} else if(type == ETH_P_IPV6 && packet->len > 1280 + ethlen) {
packet->len = via->mtu;
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;
}
}
#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
#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
#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
// 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);
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);
}
/* 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];
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;
} 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);
/* 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));
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. */
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. */
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;
}
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;
/* 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);
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;
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;
/* 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 */
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) {
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;
}
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;
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);
}
}
- 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) {
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);
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;
int c;
if(!root) {
- if(result)
+ if(result) {
*result = 0;
+ }
+
return NULL;
}
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;
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;
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;
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;
leftbottom->right = root->left;
root->left->parent = leftbottom;
}
+
root->left = left.right;
left.right->parent = root;
}
rightbottom->left = root->right;
root->right->parent = rightbottom;
}
+
root->right = right.left;
right.left->parent = root;
}
/* Return result */
tree->root = root;
- if(result)
+
+ if(result) {
*result = c;
+ }
return tree->root;
}
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;
}
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;
+ }
}
}
}
}
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);
}
node = tree->root;
if(!node) {
- if(result)
+ if(result) {
*result = 0;
+ }
+
return NULL;
}
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;
}
node = splay_search_closest_node(tree, data, &result);
- if(result < 0)
+ if(result < 0) {
node = node->prev;
+ }
return node;
}
node = splay_search_closest_node(tree, data, &result);
- if(result > 0)
+ if(result > 0) {
node = node->next;
+ }
return node;
}
} 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;
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;
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;
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;
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;
node = splay_search_node(tree, data);
- if(node)
+ if(node) {
splay_delete_node(tree, node);
+ }
}
/* Fast tree cleanup */
/* (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 */
}
// 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];
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);
}
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;
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);
}
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));
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);
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;
}
// 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);
// 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);
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];
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);
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;
// 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);
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);
}
}
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;
// 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;
// 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);
}
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;
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);
}
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);
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
// 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.
// 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.
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);
}
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;
}
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");
}
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;
}
}
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));
}
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));
#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;
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;
}
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;
// 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();
// 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;
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);
}
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);
#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;
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;
}
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");
}
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;
}
}
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;
}
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;
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)) {
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;
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;
}
}
}
- if(!sptps_stop(&s))
+ if(!sptps_stop(&s)) {
return 1;
+ }
return 0;
}
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();
// 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;
}
// 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;
}
// 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;
}
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);
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);
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);
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 *);
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;
}
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) {
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) {
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;
}
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);
}
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);
}
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);
}
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);
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;
}
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;
}
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) {
} 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");
}
}
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" */
}
#ifdef HAVE_FCHMOD
- if((perms & 0444) && f)
+
+ if((perms & 0444) && f) {
fchmod(fileno(f), perms);
+ }
+
#endif
umask(mask);
return f;
FILE *r, *w;
r = fopen(filename, "r");
- if(!r)
+
+ if(!r) {
return;
+ }
snprintf(tmpfile, sizeof(tmpfile), "%s.tmp", filename);
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;
}
// 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");
}
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. */
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");
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);
return true;
error:
- if(f)
+
+ if(f) {
fclose(f);
+ }
+
ecdsa_free(key);
return false;
}
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");
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");
return true;
error:
- if(f)
+
+ if(f) {
fclose(f);
+ }
+
rsa_free(key);
return false;
}
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;
}
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;
}
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;
}
0xa1b2c3d4,
2, 4,
0, 0,
- snaplen ?: sizeof(data),
+ snaplen ? : sizeof(data),
1,
};
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;
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);
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;
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()));
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);
}
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;
}
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;
}
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);
}
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,
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;
}
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;
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;
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;
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;
}
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));
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);
}
pid_t pid = fork();
+
if(pid == -1) {
fprintf(stderr, "Could not fork: %s\n", strerror(errno));
free(nargv);
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]);
}
#ifndef HAVE_MINGW
+
if(!connect_tincd(true)) {
if(pid) {
if(kill(pid, SIGTERM)) {
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;
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;
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");
}
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;
closedir(dir);
- if(!found)
+ if(!found) {
fprintf(stderr, "No outstanding invitations.\n");
+ }
return 0;
}
usage(true);
return 1;
}
+
only_reachable = true;
argv++;
argc--;
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;
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];
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;
}
}
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;
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;
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;
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;
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;
}
#ifdef HAVE_CURSES
- if(!connect_tincd(true))
+
+ if(!connect_tincd(true)) {
return 1;
+ }
top(fd);
return 0;
return 1;
}
- if(!connect_tincd(true))
+ if(!connect_tincd(true)) {
return 1;
+ }
pcap(fd, stdout, argc > 1 ? atoi(argv[1]) : 0);
return 0;
return 1;
}
- if(!connect_tincd(true))
+ if(!connect_tincd(true)) {
return 1;
+ }
#ifdef SIGINT
signal(SIGINT, sigint_handler);
return 1;
}
- if(!connect_tincd(true) || !pid)
+ if(!connect_tincd(true) || !pid) {
return 1;
+ }
printf("%d\n", pid);
return 0;
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);
}
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;
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")) {
// 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));
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;
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;
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.
// 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;
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);
len = strcspn(buf2, "\t =");
bvalue = buf2 + len;
bvalue += strspn(bvalue, "\t ");
+
if(*bvalue == '=') {
bvalue++;
bvalue += strspn(bvalue, "\t ");
}
+
rstrip(bvalue);
buf2[len] = '\0';
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;
+ }
}
}
}
// 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;
// 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;
}
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;
int result = bind(fd, ai->ai_addr, ai->ai_addrlen);
closesocket(fd);
+
if(result) {
success = false;
break;
}
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");
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");
}
} else {
name = strdup(argv[1]);
+
if(!*name) {
fprintf(stderr, "No Name given!\n");
return 1;
}
FILE *f = fopen(tinc_conf, "w");
+
if(!f) {
fprintf(stderr, "Could not create file %s: %s\n", tinc_conf, strerror(errno));
return 1;
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 <your vpn IP address> netmask <netmask of whole VPN>\n");
fclose(f);
}
+
#endif
return 0;
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;
}
return 1;
}
- if(!name)
+ if(!name) {
name = get_my_name(false);
+ }
return !rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true);
}
return 1;
}
- if(!name)
+ if(!name) {
name = get_my_name(false);
+ }
return !ed25519_keygen(true);
}
return 1;
}
- if(!connect_tincd(true))
+ if(!connect_tincd(true)) {
return 1;
+ }
return info(fd, argv[1]);
}
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;
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;
}
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;
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)) {
}
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;
}
DIR *dir = opendir(hosts_dir);
+
if(!dir) {
fprintf(stderr, "Could not open host configuration directory %s: %s\n", hosts_dir, strerror(errno));
return 1;
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;
}
return 1;
}
- if(out)
+ if(out) {
fclose(out);
+ }
snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, name);
}
out = fopen(filename, "w");
+
if(!out) {
fprintf(stderr, "Error creating configuration file %s: %s\n", filename, strerror(errno));
return 1;
}
- if(!strcmp(buf, "#---------------------------------------------------------------#\n"))
+ if(!strcmp(buf, "#---------------------------------------------------------------#\n")) {
continue;
+ }
if(out) {
if(fputs(buf, out) < 0) {
}
}
- if(out)
+ if(out) {
fclose(out);
+ }
if(count) {
fprintf(stderr, "Imported %d host configuration files.\n", count);
}
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) {
return 1;
}
- if(!check_netname(name, true))
+ if(!check_netname(name, true)) {
fprintf(stderr, "Warning: unsafe character in netname!\n");
+ }
}
if(fd >= 0) {
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;
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");
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);
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;
}
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;
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);
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);
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);
}
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;
if(argc == 3) {
in = fopen(argv[2], "rb");
+
if(!in) {
fprintf(stderr, "Could not open %s: %s\n", argv[2], strerror(errno));
return 1;
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);
return 1;
}
- if(!node)
+ if(!node) {
node = signer;
+ }
char *trailer;
xasprintf(&trailer, " %s %ld", signer, t);
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);
}
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);
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++;
}
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++;
}
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;
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++;
}
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);
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) {
break;
}
- if(!strncmp(item, text, strlen(text)))
+ if(!strncmp(item, text, strlen(text))) {
return xstrdup(strip_weight(item));
+ }
}
return NULL;
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;
}
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";
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 */
next = strtok(NULL, " \t\n");
}
- if(nargc == argc)
+ if(nargc == argc) {
continue;
+ }
if(!strcasecmp(nargv[argc], "exit") || !strcasecmp(nargv[argc], "quit")) {
free(nargv);
}
#ifdef HAVE_READLINE
- if(tty && found)
+
+ if(tty && found) {
add_history(copy);
+ }
+
#endif
if(!found) {
free(nargv);
- if(tty)
+ if(tty) {
printf("\n");
+ }
+
return result;
}
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);
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]);
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");
}
}
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;
}
}
return false;
}
- if(!netname && (netname = getenv("NETNAME")))
+ if(!netname && (netname = getenv("NETNAME"))) {
netname = xstrdup(netname);
+ }
/* netname "." is special: a "top-level name" */
return false;
}
- if(netname && !check_netname(netname, true))
+ if(netname && !check_netname(netname, true)) {
fprintf(stderr, "Warning: unsafe character in netname!\n");
+ }
return true;
}
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;
}
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
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;
}
}
#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
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;
}
#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;
}
}
/* drop privileges */
- if (!drop_privs())
+ if(!drop_privs()) {
goto end;
+ }
/* Start main loop. It only exits when tinc is killed. */
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);
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 {
}
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) {
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);
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;
}
}
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;
} 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);
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;
}
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;
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;
}
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) {
// 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;
}
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));
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);
}
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.
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));
}
}
};
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;
}
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) {
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];
}
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;
}
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;
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;
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);
};
conn = plug.vde_open(device, identname, &args);
+
if(!conn) {
logger(DEBUG_ALWAYS, LOG_ERR, "Could not open VDE socket %s", device);
return false;
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();
/*
- version.c -- version information
+ version.c -- version information
Copyright (C) 2014 Etienne Dechamps <etienne@edechamps.fr>
This program is free software; you can redistribute it and/or modify
#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
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
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;
}
#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);
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);
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);
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;
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;
}
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;
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;