summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xPICA_node.c59
-rw-r--r--PICA_nodewait.c83
-rw-r--r--PICA_nodewait.h17
3 files changed, 134 insertions, 25 deletions
diff --git a/PICA_node.c b/PICA_node.c
index 3de27df..68ead20 100755
--- a/PICA_node.c
+++ b/PICA_node.c
@@ -2609,7 +2609,45 @@ struct nodewait *kill_ptr = 0, *nw = nodewait_list;
while(nw)
{
PICA_debug3("checking nodewait pointer %p", nw);
- if (PICA_NODEWAIT_FINISHED_OK == nw->state)
+ switch(nw->state)
+ {
+ case PICA_NODEWAIT_RESOLVED:
+ {
+ int skip = 0;
+ struct nodelink *nl;
+
+ nl = nodelink_list_head;
+
+ while(nl && !skip)//check existing connections
+ {
+ struct addrinfo *p_ai = nw->ai;
+
+ while(p_ai) //IPv6
+ {
+ struct sockaddr_in in = *(struct sockaddr_in*)p_ai->ai_addr;
+
+ if (nl->addr.sin_family == in.sin_family && nl->addr.sin_addr.s_addr == in.sin_addr.s_addr && nl->addr.sin_port == in.sin_port)
+ {
+ skip = 1;
+ break;
+ }
+
+ p_ai = p_ai->ai_next;
+ }
+ nl = nl->next;
+ }
+
+ if (!skip)
+ nodewait_start_connect(nw);
+ else
+ {
+ PICA_debug3("skipping node %.255s %u , connection already exist", nw->addr.addr, nw->addr.port);
+ kill_ptr = nw;
+ }
+ }
+ break;
+
+ case PICA_NODEWAIT_CONNECTED:
{
struct nodelink *nlp;
@@ -2628,14 +2666,25 @@ while(nw)
PICA_nodeaddr_update(nodecfg.nodes_db_file, &nw->addr, 1);
kill_ptr = nw;
}
+ break;
- if (PICA_NODEWAIT_FINISHED_ERR == nw->state)
+ case PICA_NODEWAIT_RESOLVING_FAILED:
{
- PICA_debug1("connection to %.255s %u failed", nw->addr.addr, nw->addr.port);
+ PICA_debug1("resolving %.255s %u failed: %s", nw->addr.addr, nw->addr.port, gai_strerror(nw->ai_errorcode));
PICA_nodeaddr_update(nodecfg.nodes_db_file, &nw->addr, 0);
kill_ptr = nw;
}
+ break;
+ case PICA_NODEWAIT_CONNECT_FAILED:
+ {
+ PICA_debug1("connection to %.255s %u failed", nw->addr.addr, nw->addr.port);
+ PICA_nodeaddr_update(nodecfg.nodes_db_file, &nw->addr, 0);
+ kill_ptr = nw;
+ }
+ break;
+ }
+
nw = nw->next;
if (kill_ptr)
@@ -2787,7 +2836,7 @@ while(nap)
if (0 == strncmp(nap->addr, my_addr, 256) && nap->port == atoi(nodecfg.listen_port))
{
- PICA_debug1("Skipping self address %.255s port %u", nap->addr, nap->port);
+ PICA_debug3("Skipping self address %.255s port %u", nap->addr, nap->port);
skip = 1;
}
@@ -2817,7 +2866,7 @@ while(nap)
}
if (!skip)
- nodewait_start_connection(nap);
+ nodewait_start_resolve(nap);
nap=nap->next;
}
diff --git a/PICA_nodewait.c b/PICA_nodewait.c
index 50d02f3..00afdce 100644
--- a/PICA_nodewait.c
+++ b/PICA_nodewait.c
@@ -53,6 +53,9 @@ while(p)
//
//free resources
//
+ if (nw->ai)
+ freeaddrinfo(nw->ai);
+
free(nw);
return;
@@ -64,16 +67,16 @@ while(p)
}
#ifdef WIN32
-static DWORD WINAPI nodewait_thread (void *arg)
+static DWORD WINAPI nodewait_resolve_thread (void *arg)
#else
-static void *nodewait_thread (void *arg)
+static void *nodewait_resolve_thread (void *arg)
#endif
{
struct nodewait *nw = (struct nodewait *)arg;
-struct addrinfo h,*r,*ap;
+struct addrinfo h;
char portbuf[8];
-nw->state = PICA_NODEWAIT_RUNNING;
+nw->state = PICA_NODEWAIT_RESOLVING;
memset(&h,0,sizeof(struct addrinfo));
@@ -90,10 +93,29 @@ h.ai_protocol=IPPROTO_TCP;
sprintf(portbuf,"%u",nw->addr.port);
-if (0!=getaddrinfo(nw->addr.addr, portbuf, &h, &r))
- return 0;
+nw->ai_errorcode = getaddrinfo(nw->addr.addr, portbuf, &h, &nw->ai);
+
+if (nw->ai_errorcode)
+ nw->state = PICA_NODEWAIT_RESOLVING_FAILED;
+else
+ nw->state = PICA_NODEWAIT_RESOLVED;
+
+return 0;
+}
+
+
+#ifdef WIN32
+static DWORD WINAPI nodewait_connect_thread (void *arg)
+#else
+static void *nodewait_connect_thread (void *arg)
+#endif
+{
+struct nodewait *nw = (struct nodewait *)arg;
+struct addrinfo *ap;
-ap = r;
+nw->state = PICA_NODEWAIT_CONNECTING;
+
+ap = nw->ai;
while(ap)
{
@@ -120,18 +142,16 @@ while(ap)
if (ap)
{
nw->nc.addr=*((struct sockaddr_in*)(ap->ai_addr));
- freeaddrinfo(r);
- nw->state = PICA_NODEWAIT_FINISHED_OK;
+ nw->state = PICA_NODEWAIT_CONNECTED;
return 1;
}
-freeaddrinfo(r);
-nw->state = PICA_NODEWAIT_FINISHED_ERR;
+nw->state = PICA_NODEWAIT_CONNECT_FAILED;
return 0;
}
-void nodewait_start_connection(struct PICA_nodeaddr *a)
+void nodewait_start_resolve(struct PICA_nodeaddr *a)
{
struct nodewait *nw;
#ifndef WIN32
@@ -149,7 +169,39 @@ if (!nw)
nw ->addr = *a;
-PICA_debug1("starting connection to node %.255s %u ...", nw->addr.addr, nw->addr.port);
+PICA_debug1("starting to resolve node address %.255s %u ...", nw->addr.addr, nw->addr.port);
+
+#ifndef WIN32
+if (0 != pthread_attr_init(&attr))
+ PICA_error("pthread_attr_init() call failed.");
+
+pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+if (0 != pthread_create(&thr, &attr, nodewait_resolve_thread, (void*)nw))
+ PICA_error("unable to create thread: %s", strerror(errno));
+
+pthread_attr_destroy(&attr);
+#else
+thread_h = CreateThread(NULL, 4096, nodewait_resolve_thread, (void*)nw, 0, &thread_id);
+
+if (NULL != thread_h)
+ CloseHandle(thread_h);
+else
+ PICA_error("unable to create thread: %u", GetLastError());
+#endif
+}
+
+void nodewait_start_connect(struct nodewait *nw)
+{
+#ifndef WIN32
+pthread_t thr;
+pthread_attr_t attr;
+#else
+DWORD thread_id;
+HANDLE thread_h;
+#endif
+
+PICA_debug1("connecting to node %.255s %u ...", nw->addr.addr, nw->addr.port);
#ifndef WIN32
if (0 != pthread_attr_init(&attr))
@@ -157,16 +209,17 @@ if (0 != pthread_attr_init(&attr))
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-if (0 != pthread_create(&thr, &attr, nodewait_thread, (void*)nw))
+if (0 != pthread_create(&thr, &attr, nodewait_connect_thread, (void*)nw))
PICA_error("unable to create thread: %s", strerror(errno));
pthread_attr_destroy(&attr);
#else
-thread_h = CreateThread(NULL, 4096, nodewait_thread, (void*)nw, 0, &thread_id);
+thread_h = CreateThread(NULL, 4096, nodewait_connect_thread, (void*)nw, 0, &thread_id);
if (NULL != thread_h)
CloseHandle(thread_h);
else
PICA_error("unable to create thread: %u", GetLastError());
#endif
+
}
diff --git a/PICA_nodewait.h b/PICA_nodewait.h
index 614db09..e471c18 100644
--- a/PICA_nodewait.h
+++ b/PICA_nodewait.h
@@ -5,9 +5,12 @@
#include "PICA_node.h"
#define PICA_NODEWAIT_NEW 1
-#define PICA_NODEWAIT_RUNNING 2
-#define PICA_NODEWAIT_FINISHED_OK 3
-#define PICA_NODEWAIT_FINISHED_ERR 4
+#define PICA_NODEWAIT_RESOLVING 5
+#define PICA_NODEWAIT_RESOLVED 6
+#define PICA_NODEWAIT_CONNECTING 7
+#define PICA_NODEWAIT_CONNECTED 8
+#define PICA_NODEWAIT_RESOLVING_FAILED 9
+#define PICA_NODEWAIT_CONNECT_FAILED 10
struct nodewait
{
@@ -24,7 +27,10 @@ time_t tmst;
// } addrptr;
struct PICA_nodeaddr addr;
-
+
+struct addrinfo *ai;
+int ai_errorcode;
+
struct nodewait *next;
};
@@ -32,6 +38,7 @@ extern struct nodewait *nodewait_list;
struct nodewait *nodewait_list_addnew();
void nodewait_list_delete(struct nodewait *nw);
-void nodewait_start_connection(struct PICA_nodeaddr *a);
+void nodewait_start_resolve(struct PICA_nodeaddr *a);
+void nodewait_start_connect(struct nodewait *nw);
#endif