return true;
}
+static void set_timeout(int sock, int timeout) {
+#ifdef _WIN32
+ DWORD tv = timeout;
+#else
+ struct timeval tv;
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout - tv.tv_sec * 1000) * 1000;
+#endif
+ setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv);
+ setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof tv);
+}
+
char *meshlink_get_external_address(meshlink_handle_t *mesh) {
char *hostname = NULL;
while(aip) {
int s = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol);
if(s >= 0) {
+ set_timeout(s, 5000);
if(connect(s, aip->ai_addr, aip->ai_addrlen)) {
closesocket(s);
s = -1;
return false;
}
+ set_timeout(mesh->sock, 5000);
+
if(connect(mesh->sock, ai->ai_addr, ai->ai_addrlen)) {
logger(mesh, MESHLINK_DEBUG, "Could not connect to %s port %s: %s\n", address, port, strerror(errno));
closesocket(mesh->sock);
pthread_mutex_unlock(&mesh->mesh_mutex);
}
-meshlink_channel_t *meshlink_channel_open(meshlink_handle_t *mesh, meshlink_node_t *node, uint16_t port, meshlink_channel_receive_cb_t cb, const void *data, size_t len) {
+meshlink_channel_t *meshlink_channel_open_ex(meshlink_handle_t *mesh, meshlink_node_t *node, uint16_t port, meshlink_channel_receive_cb_t cb, const void *data, size_t len, uint32_t flags) {
if(!mesh || !node) {
meshlink_errno = MESHLINK_EINVAL;
return NULL;
meshlink_channel_t *channel = xzalloc(sizeof *channel);
channel->node = n;
channel->receive_cb = cb;
- channel->c = utcp_connect(n->utcp, port, channel_recv, channel);
+ channel->c = utcp_connect_ex(n->utcp, port, channel_recv, channel, flags);
if(!channel->c) {
meshlink_errno = errno == ENOMEM ? MESHLINK_ENOMEM : MESHLINK_EINTERNAL;
free(channel);
return channel;
}
+meshlink_channel_t *meshlink_channel_open(meshlink_handle_t *mesh, meshlink_node_t *node, uint16_t port, meshlink_channel_receive_cb_t cb, const void *data, size_t len) {
+ return meshlink_channel_open_ex(mesh, node, port, cb, data, len, MESHLINK_CHANNEL_TCP);
+}
+
void meshlink_channel_shutdown(meshlink_handle_t *mesh, meshlink_channel_t *channel, int direction) {
if(!mesh || !channel) {
meshlink_errno = MESHLINK_EINVAL;
return retval;
}
+uint32_t meshlink_channel_get_flags(meshlink_handle_t *mesh, meshlink_channel_t *channel) {
+ if(!mesh || !channel) {
+ meshlink_errno = MESHLINK_EINVAL;
+ return -1;
+ }
+
+ return channel->c->flags;
+}
+
void update_node_status(meshlink_handle_t *mesh, node_t *n) {
if(n->status.reachable && mesh->channel_accept_cb && !n->utcp)
n->utcp = utcp_init(channel_accept, channel_pre_accept, channel_send, n);
static void __attribute__((constructor)) meshlink_init(void) {
crypto_init();
+ unsigned int seed;
+ randomize(&seed, sizeof seed);
+ srand(seed);
}
static void __attribute__((destructor)) meshlink_exit(void) {