|
|
@@ -5,7 +5,7 @@
|
|
|
#include <unistd.h>
|
|
|
#include <fcntl.h>
|
|
|
#include "ntpclient.h"
|
|
|
-
|
|
|
+#include "thread.h"
|
|
|
|
|
|
#define NTP_PORT 123
|
|
|
#define NTP_PACKET_SIZE 48
|
|
|
@@ -66,57 +66,13 @@ static int get_addr(ipaddr_t *addr, struct addrinfo *info)
|
|
|
}
|
|
|
|
|
|
|
|
|
-//#define GETADDR_ASYNC
|
|
|
-//#define GETADDR_SYNC_TIMEOUT
|
|
|
-
|
|
|
-#ifdef GETADDR_ASYNC
|
|
|
-static timer_t tmrId=NULL;
|
|
|
-static struct gaicb hostReq;
|
|
|
-static void timer_fn(union sigval value)
|
|
|
-{
|
|
|
- printf("___ XXXXXXXXXXXXXXXXXXX\n");
|
|
|
- gai_cancel(&hostReq);
|
|
|
- timer_delete(tmrId);
|
|
|
-}
|
|
|
-static int start_timer(int flag)
|
|
|
+static void *tmp_thread(void *arg)
|
|
|
{
|
|
|
- struct sigevent sev;
|
|
|
- struct itimerspec its={0};
|
|
|
-
|
|
|
- memset(&sev, 0, sizeof(sev));
|
|
|
- sev.sigev_value.sival_ptr = &tmrId;
|
|
|
- sev.sigev_notify = SIGEV_THREAD;
|
|
|
- sev.sigev_notify_function = timer_fn;
|
|
|
- sev.sigev_value.sival_int = 11;
|
|
|
- sev.sigev_notify_attributes = NULL;
|
|
|
- if (timer_create(CLOCK_REALTIME, &sev, &tmrId) == -1) {
|
|
|
- perror("timer_create");
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- its.it_value.tv_sec = 2;
|
|
|
- its.it_value.tv_nsec = 0;
|
|
|
- its.it_interval.tv_sec = 0;
|
|
|
- its.it_interval.tv_nsec = 0;
|
|
|
- if (timer_settime(tmrId, 0, &its, NULL) == -1) {
|
|
|
- perror("timer_settime");
|
|
|
- return -1;
|
|
|
- }
|
|
|
- return 0;
|
|
|
-}
|
|
|
-#endif
|
|
|
-
|
|
|
-NTPClient* createNTPClient(const char* ntp_server, int port, int timeout_sec) {
|
|
|
- NTPClient* client = (NTPClient*)malloc(sizeof(NTPClient));
|
|
|
- if (!client) {
|
|
|
- perror("createNTPClient, malloc failed\n");
|
|
|
- return NULL;
|
|
|
- }
|
|
|
-
|
|
|
ipaddr_t ipa;
|
|
|
int r,fd=-1,err;
|
|
|
struct addrinfo hints;
|
|
|
struct addrinfo *res=NULL,*rp;
|
|
|
+ NTPClient *pc=(NTPClient*)arg;
|
|
|
char tmp[32];
|
|
|
|
|
|
memset(&hints, 0, sizeof hints);
|
|
|
@@ -124,60 +80,17 @@ NTPClient* createNTPClient(const char* ntp_server, int port, int timeout_sec) {
|
|
|
hints.ai_socktype = SOCK_DGRAM;
|
|
|
hints.ai_protocol = 0;//IPPROTO_UDP;
|
|
|
|
|
|
- sprintf(tmp, "%d", port);
|
|
|
-#ifdef GETADDR_ASYNC
|
|
|
- struct sigevent sig;
|
|
|
- struct gaicb *pcb=&hostReq;
|
|
|
-
|
|
|
- hostReq.ar_name = strdup(ntp_server);
|
|
|
- hostReq.ar_service = strdup(tmp); //the port we will listen on
|
|
|
- hostReq.ar_request = &hints;
|
|
|
-
|
|
|
- sig.sigev_notify = SIGEV_SIGNAL;
|
|
|
- sig.sigev_value.sival_ptr = &hostReq;
|
|
|
- sig.sigev_signo = SIGRTMIN;
|
|
|
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
|
|
+ pthread_testcancel();
|
|
|
|
|
|
- err = getaddrinfo_a(GAI_NOWAIT, &pcb, 1, &sig);
|
|
|
+ sprintf(tmp, "%d", pc->port);
|
|
|
+ printf("___getaddrinfo in\n");
|
|
|
+ err = getaddrinfo(pc->server, tmp, &hints, &res);
|
|
|
if(err){
|
|
|
- printf(" getaddrinfo from %sfailed, %s\n", ntp_server, gai_strerror(err));
|
|
|
- free(client); return NULL;
|
|
|
- }
|
|
|
-#else
|
|
|
-
|
|
|
-#ifdef GETADDR_SYNC_TIMEOUT
|
|
|
- fd_set fds;
|
|
|
- struct timeval tv;
|
|
|
- fd = socket(AF_INET, SOCK_DGRAM, 0);
|
|
|
- if (fd < 0) {
|
|
|
- perror("socket error");
|
|
|
- free(client);
|
|
|
- return NULL;
|
|
|
+ printf("___getaddrinfo from %s failed, %s\n", pc->server, gai_strerror(err));
|
|
|
+ pthread_exit(NULL);
|
|
|
}
|
|
|
- // 设置套接字为非阻塞模式
|
|
|
- int flags = fcntl(fd, F_GETFL, 0);
|
|
|
- fcntl(fd, F_SETFL, flags | O_NONBLOCK);
|
|
|
-#endif
|
|
|
-
|
|
|
- err = getaddrinfo(ntp_server, tmp, &hints, &res);
|
|
|
- if(err){
|
|
|
- printf(" getaddrinfo from %s failed, %s\n", ntp_server, gai_strerror(err));
|
|
|
- close(fd);
|
|
|
- free(client); return NULL;
|
|
|
- }
|
|
|
-
|
|
|
-#ifdef GETADDR_SYNC_TIMEOUT
|
|
|
- FD_ZERO(&fds); FD_SET(fd, &fds);
|
|
|
- tv.tv_sec = timeout_sec; tv.tv_usec = 0;
|
|
|
- int n = select(fd, NULL, &fds, NULL, &tv);
|
|
|
- if (n <= 0) { // 0:超时 <0:出错
|
|
|
- close(fd);
|
|
|
- freeaddrinfo(res);
|
|
|
- free(client);
|
|
|
- printf("___ %s !!\n", (n==0)?"timeout":"error");
|
|
|
- return NULL;
|
|
|
- }
|
|
|
- close(fd);
|
|
|
-#endif
|
|
|
+ printf("___getaddrinfo out\n");
|
|
|
|
|
|
for(rp=res; rp; rp=rp->ai_next){
|
|
|
get_addr(&ipa, rp);
|
|
|
@@ -185,18 +98,44 @@ NTPClient* createNTPClient(const char* ntp_server, int port, int timeout_sec) {
|
|
|
|
|
|
fd = socket(rp->ai_family, rp->ai_socktype, 0);
|
|
|
if (fd>=0) {
|
|
|
- client->sockfd = fd;
|
|
|
- client->server_addr = *rp->ai_addr;
|
|
|
+ pc->sockfd = fd;
|
|
|
+ pc->server_addr = *rp->ai_addr;
|
|
|
printf("ok!\n");
|
|
|
break;
|
|
|
}
|
|
|
printf("failed!\n");
|
|
|
}
|
|
|
freeaddrinfo(res);
|
|
|
- if(fd<0) {
|
|
|
+ pc->flag = 1;
|
|
|
+
|
|
|
+ pthread_exit(NULL);
|
|
|
+}
|
|
|
+NTPClient* createNTPClient(const char* ntp_server, int port, int timeout_sec) {
|
|
|
+ NTPClient* client = (NTPClient*)malloc(sizeof(NTPClient));
|
|
|
+ if (!client) {
|
|
|
+ perror("createNTPClient, malloc failed\n");
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ pthread_t tid;
|
|
|
+ client->server = (char*)ntp_server;
|
|
|
+ client->port = port;
|
|
|
+ client->flag = 0;
|
|
|
+ pthread_create(&tid, NULL, tmp_thread, client);
|
|
|
+ for(int i=0; i<timeout_sec; i++) {
|
|
|
+ if(client->flag==1) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ sleep(1);
|
|
|
+ }
|
|
|
+ if(client->flag==0) {
|
|
|
+ printf("___getaddrinfo timeout, cancel thread %lu\n", (unsigned long)tid);
|
|
|
+ pthread_cancel(tid);//SIGTERM
|
|
|
+ pthread_join(tid, NULL);
|
|
|
+ printf("___cancel ok!\n");
|
|
|
+
|
|
|
free(client); return NULL;
|
|
|
}
|
|
|
-#endif
|
|
|
printf("___createNTPClient ok!\n");
|
|
|
|
|
|
return client;
|