return false;
}
- //while(ai) {
+ bool success = false;
+
for(struct addrinfo *aip = ai; aip; aip = aip->ai_next) {
- int fd = socket(aip->ai_family, SOCK_STREAM, IPPROTO_TCP);
+ /* Try to bind to TCP. */
- if(!fd) {
- freeaddrinfo(ai);
- return false;
+ int tcp_fd = socket(aip->ai_family, SOCK_STREAM, IPPROTO_TCP);
+
+ if(tcp_fd == -1) {
+ continue;
}
- int result = bind(fd, aip->ai_addr, aip->ai_addrlen);
- closesocket(fd);
+ int result = bind(tcp_fd, aip->ai_addr, aip->ai_addrlen);
+ closesocket(tcp_fd);
if(result) {
- freeaddrinfo(ai);
- return false;
+ if(errno == EADDRINUSE) {
+ /* If this port is in use for any address family, avoid it. */
+ success = false;
+ break;
+ } else {
+ continue;
+ }
}
+
+ /* If TCP worked, then we require that UDP works as well. */
+
+ int udp_fd = socket(aip->ai_family, SOCK_DGRAM, IPPROTO_UDP);
+
+ if(udp_fd == -1) {
+ success = false;
+ break;
+ }
+
+ result = bind(udp_fd, aip->ai_addr, aip->ai_addrlen);
+ closesocket(udp_fd);
+
+ if(result) {
+ success = false;
+ break;
+ }
+
+ success = true;
}
freeaddrinfo(ai);
- return true;
+ return success;
}
static int check_port(meshlink_handle_t *mesh) {
}
bool meshlink_start(meshlink_handle_t *mesh) {
- assert(mesh->self);
- assert(mesh->private_key);
-
if(!mesh) {
meshlink_errno = MESHLINK_EINVAL;
return false;
pthread_mutex_lock(&mesh->mutex);
+ assert(mesh->self);
+ assert(mesh->private_key);
assert(mesh->self->ecdsa);
assert(!memcmp((uint8_t *)mesh->self->ecdsa + 64, (uint8_t *)mesh->private_key + 64, 32));
}
bool meshlink_verify(meshlink_handle_t *mesh, meshlink_node_t *source, const void *data, size_t len, const void *signature, size_t siglen) {
- if(!mesh || !data || !len || !signature) {
+ if(!mesh || !source || !data || !len || !signature) {
meshlink_errno = MESHLINK_EINVAL;
return false;
}