diff options
| -rwxr-xr-x | PICA_node.c | 59 | ||||
| -rw-r--r-- | PICA_nodewait.c | 83 | ||||
| -rw-r--r-- | PICA_nodewait.h | 17 |
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 |
