|
@@ -1,4 +1,9 @@
|
|
|
|
|
+#define _GNU_SOURCE
|
|
|
#include <netdb.h>
|
|
#include <netdb.h>
|
|
|
|
|
+#include <signal.h>
|
|
|
|
|
+#include <unistd.h>
|
|
|
|
|
+#include <unistd.h>
|
|
|
|
|
+#include <fcntl.h>
|
|
|
#include "ntpclient.h"
|
|
#include "ntpclient.h"
|
|
|
|
|
|
|
|
|
|
|
|
@@ -59,7 +64,49 @@ static int get_addr(ipaddr_t *addr, struct addrinfo *info)
|
|
|
}
|
|
}
|
|
|
return 0;
|
|
return 0;
|
|
|
}
|
|
}
|
|
|
-NTPClient* createNTPClient(const char* ntp_server, int port) {
|
|
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+//#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)
|
|
|
|
|
+{
|
|
|
|
|
+ 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));
|
|
NTPClient* client = (NTPClient*)malloc(sizeof(NTPClient));
|
|
|
if (!client) {
|
|
if (!client) {
|
|
|
perror("createNTPClient, malloc failed\n");
|
|
perror("createNTPClient, malloc failed\n");
|
|
@@ -78,15 +125,63 @@ NTPClient* createNTPClient(const char* ntp_server, int port) {
|
|
|
hints.ai_protocol = 0;//IPPROTO_UDP;
|
|
hints.ai_protocol = 0;//IPPROTO_UDP;
|
|
|
|
|
|
|
|
sprintf(tmp, "%d", port);
|
|
sprintf(tmp, "%d", port);
|
|
|
- err = getaddrinfo(ntp_server, tmp, &hints, &res);
|
|
|
|
|
|
|
+#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;
|
|
|
|
|
+
|
|
|
|
|
+ err = getaddrinfo_a(GAI_NOWAIT, &pcb, 1, &sig);
|
|
|
if(err){
|
|
if(err){
|
|
|
printf(" getaddrinfo from %sfailed, %s\n", ntp_server, gai_strerror(err));
|
|
printf(" getaddrinfo from %sfailed, %s\n", ntp_server, gai_strerror(err));
|
|
|
free(client); return NULL;
|
|
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;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 设置套接字为非阻塞模式
|
|
|
|
|
+ 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
|
|
|
|
|
|
|
|
for(rp=res; rp; rp=rp->ai_next){
|
|
for(rp=res; rp; rp=rp->ai_next){
|
|
|
get_addr(&ipa, rp);
|
|
get_addr(&ipa, rp);
|
|
|
- printf("22 socket to %s:%d ", ipa.ip, ipa.port);
|
|
|
|
|
|
|
+ printf("socket to %s:%d ", ipa.ip, ipa.port);
|
|
|
|
|
|
|
|
fd = socket(rp->ai_family, rp->ai_socktype, 0);
|
|
fd = socket(rp->ai_family, rp->ai_socktype, 0);
|
|
|
if (fd>=0) {
|
|
if (fd>=0) {
|
|
@@ -98,10 +193,10 @@ NTPClient* createNTPClient(const char* ntp_server, int port) {
|
|
|
printf("failed!\n");
|
|
printf("failed!\n");
|
|
|
}
|
|
}
|
|
|
freeaddrinfo(res);
|
|
freeaddrinfo(res);
|
|
|
-
|
|
|
|
|
if(fd<0) {
|
|
if(fd<0) {
|
|
|
free(client); return NULL;
|
|
free(client); return NULL;
|
|
|
}
|
|
}
|
|
|
|
|
+#endif
|
|
|
printf("___createNTPClient ok!\n");
|
|
printf("___createNTPClient ok!\n");
|
|
|
|
|
|
|
|
return client;
|
|
return client;
|