updat code
This commit is contained in:
8
Makefile
8
Makefile
@@ -1,8 +1,10 @@
|
||||
|
||||
BIN=smartdns
|
||||
OBJS=smartdns.o fast_ping.o
|
||||
CFLAGS=-g -O0
|
||||
CFLAGS=-Iinclude
|
||||
OBJS=smartdns.o fast_ping.o lib/bitops.o
|
||||
CFLAGS=-g -O0 -Wall
|
||||
CFLAGS +=-Iinclude
|
||||
CXXFLAGS=-g -O0 -Wall -std=c++11
|
||||
CXXFLAGS +=-Iinclude
|
||||
|
||||
.PHONY: all
|
||||
|
||||
|
||||
111
fast_ping.c
111
fast_ping.c
@@ -2,6 +2,7 @@
|
||||
#include "atomic.h"
|
||||
#include "hashtable.h"
|
||||
#include <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <linux/filter.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/icmp6.h>
|
||||
@@ -45,6 +46,10 @@ struct ping_host_struct {
|
||||
|
||||
int fd;
|
||||
unsigned int seq;
|
||||
struct timeval last;
|
||||
int interval;
|
||||
int timeout;
|
||||
int send;
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addr_len;
|
||||
struct fast_ping_packet packet;
|
||||
@@ -54,7 +59,7 @@ struct fast_ping_struct {
|
||||
int run;
|
||||
pthread_t tid;
|
||||
pthread_mutex_t lock;
|
||||
int ident;
|
||||
unsigned short ident;
|
||||
|
||||
int epoll_fd;
|
||||
int fd_icmp;
|
||||
@@ -82,7 +87,7 @@ uint16_t _fast_ping_checksum(uint16_t *header, size_t len)
|
||||
return htons(~((sum >> 16) + (sum & 0xffff)));
|
||||
}
|
||||
|
||||
int fast_ping_result_callback(fast_ping_result result)
|
||||
void fast_ping_result_callback(fast_ping_result result)
|
||||
{
|
||||
ping_callback = result;
|
||||
}
|
||||
@@ -148,7 +153,7 @@ void _fast_ping_install_filter_v4(int sock)
|
||||
}
|
||||
}
|
||||
|
||||
static struct addrinfo *_fast_ping_getaddr(const u_char *host, int type, int protocol)
|
||||
static struct addrinfo *_fast_ping_getaddr(const char *host, int type, int protocol)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *result = NULL;
|
||||
@@ -170,7 +175,7 @@ errout:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int _fast_ping_getdomain(const u_char *host)
|
||||
static int _fast_ping_getdomain(const char *host)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *result = NULL;
|
||||
@@ -197,12 +202,12 @@ errout:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _fast_ping_host_get(struct ping_host_struct *ping_host)
|
||||
static void _fast_ping_host_get(struct ping_host_struct *ping_host)
|
||||
{
|
||||
atomic_inc(&ping_host->ref);
|
||||
}
|
||||
|
||||
int _fast_ping_host_put(struct ping_host_struct *ping_host)
|
||||
static void _fast_ping_host_put(struct ping_host_struct *ping_host)
|
||||
{
|
||||
pthread_mutex_lock(&ping.map_lock);
|
||||
if (atomic_dec_and_test(&ping_host->ref)) {
|
||||
@@ -214,7 +219,7 @@ int _fast_ping_host_put(struct ping_host_struct *ping_host)
|
||||
pthread_mutex_unlock(&ping.map_lock);
|
||||
|
||||
if (ping_host == NULL) {
|
||||
return -1;
|
||||
return ;
|
||||
}
|
||||
|
||||
free(ping_host);
|
||||
@@ -280,34 +285,48 @@ errout:
|
||||
|
||||
static int _fast_ping_sendping(struct ping_host_struct *ping_host)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if (ping_host->type == AF_INET) {
|
||||
return _fast_ping_sendping_v4(ping_host);
|
||||
ret = _fast_ping_sendping_v4(ping_host);
|
||||
} else if (ping_host->type == AF_INET6) {
|
||||
return _fast_ping_sendping_v6(ping_host);
|
||||
ret = _fast_ping_sendping_v6(ping_host);
|
||||
}
|
||||
|
||||
return -1;
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ping_host->send = 1;
|
||||
gettimeofday(&ping_host->last, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _fast_ping_create_sock(int protocol)
|
||||
{
|
||||
int fd;
|
||||
int fd = -1;
|
||||
struct ping_host_struct *icmp_host = NULL;
|
||||
struct epoll_event event;
|
||||
|
||||
fd = socket(AF_INET, SOCK_RAW, protocol);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "create icmp socket failed.\n");
|
||||
goto errout;
|
||||
}
|
||||
switch (protocol) {
|
||||
case IPPROTO_ICMP:
|
||||
fd = socket(AF_INET, SOCK_RAW, protocol);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "create icmp socket failed.\n");
|
||||
goto errout;
|
||||
}
|
||||
_fast_ping_install_filter_v4(fd);
|
||||
icmp_host = &ping.icmp_host;
|
||||
break;
|
||||
case IPPROTO_ICMPV6:
|
||||
fd = socket(AF_INET6, SOCK_RAW, protocol);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "create icmp socket failed.\n");
|
||||
goto errout;
|
||||
}
|
||||
_fast_ping_install_filter_v6(fd);
|
||||
icmp_host = &ping.icmp_host;
|
||||
icmp_host = &ping.icmp6_host;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -371,7 +390,6 @@ int fast_ping_start(const char *host, int timeout, void *userptr)
|
||||
struct addrinfo *gai = NULL;
|
||||
int domain = -1;
|
||||
int icmp_proto = 0;
|
||||
char ip[PING_MAX_HOSTLEN];
|
||||
uint32_t hostkey;
|
||||
uint32_t addrkey;
|
||||
|
||||
@@ -402,17 +420,20 @@ int fast_ping_start(const char *host, int timeout, void *userptr)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
memset(ping_host, 0, sizeof(ping_host));
|
||||
int interval = 1000;
|
||||
memset(ping_host, 0, sizeof(*ping_host));
|
||||
strncpy(ping_host->host, host, PING_MAX_HOSTLEN);
|
||||
ping_host->type = domain;
|
||||
ping_host->fd = _fast_ping_create_icmp(icmp_proto);
|
||||
ping_host->timeout = timeout;
|
||||
ping_host->interval = interval;
|
||||
memcpy(&ping_host->addr, gai->ai_addr, gai->ai_addrlen);
|
||||
ping_host->addr_len = gai->ai_addrlen;
|
||||
|
||||
atomic_set(&ping_host->ref, 0);
|
||||
|
||||
hostkey = hash_string(ping_host->host);
|
||||
addrkey = jhash(&ping_host->addr, ping_host->addr_len, 0);
|
||||
addrkey = jhash(&ping_host->addr, ping_host->addr_len, 0);
|
||||
pthread_mutex_lock(&ping.map_lock);
|
||||
_fast_ping_host_get(ping_host);
|
||||
hash_add(ping.hostmap, &ping_host->host_node, hostkey);
|
||||
@@ -467,12 +488,10 @@ void tv_sub(struct timeval *out, struct timeval *in)
|
||||
|
||||
static int _fast_ping_icmp6_packet(struct ping_host_struct *ping_host, u_char *packet_data, int data_len, struct timeval *tvrecv)
|
||||
{
|
||||
int hlen;
|
||||
int icmp_len;
|
||||
struct fast_ping_packet *packet = (struct fast_ping_packet *)packet_data;
|
||||
struct icmp6_hdr *icmp6 = &packet->icmp6;
|
||||
struct timeval tvresult = *tvrecv;
|
||||
double rtt;
|
||||
|
||||
if (icmp6->icmp6_type != ICMP6_ECHO_REPLY) {
|
||||
return -1;
|
||||
@@ -489,7 +508,7 @@ static int _fast_ping_icmp6_packet(struct ping_host_struct *ping_host, u_char *p
|
||||
|
||||
struct timeval *tvsend = &packet->msg.tv;
|
||||
tv_sub(&tvresult, tvsend);
|
||||
ping_callback(ping_host->host, ping_host->seq, &tvresult, ping_host->userptr);
|
||||
ping_callback(ping_host->host, PING_RESULT_RESPONSE, ping_host->seq, &tvresult, ping_host->userptr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -527,7 +546,7 @@ static int _fast_ping_icmp_packet(struct ping_host_struct *ping_host, u_char *pa
|
||||
struct timeval *tvsend = &packet->msg.tv;
|
||||
tv_sub(&tvresult, tvsend);
|
||||
|
||||
ping_callback(ping_host->host, ping_host->seq, &tvresult, ping_host->userptr);
|
||||
ping_callback(ping_host->host, PING_RESULT_RESPONSE, ping_host->seq, &tvresult, ping_host->userptr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -551,14 +570,7 @@ errout:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _fast_ping_create_tcp(struct ping_host_struct *ping_host)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _fast_ping_ping_host(struct ping_host_struct *ping_host) {}
|
||||
|
||||
static int _fast_ping_gethost_by_addr(u_char *host, struct sockaddr *addr, socklen_t addr_len)
|
||||
static int _fast_ping_gethost_by_addr(char *host, struct sockaddr *addr, socklen_t addr_len)
|
||||
{
|
||||
struct sockaddr_storage *addr_store = (struct sockaddr_storage *)addr;
|
||||
host[0] = 0;
|
||||
@@ -603,7 +615,7 @@ static int _fast_ping_process(struct ping_host_struct *ping_host, struct timeval
|
||||
goto errout;
|
||||
}
|
||||
|
||||
addrkey = jhash(&from, from_len, 0);
|
||||
addrkey = jhash(&from, from_len, 0);
|
||||
pthread_mutex_lock(&ping.map_lock);
|
||||
hash_for_each_possible(ping.addrmap, recv_ping_host, addr_node, addrkey)
|
||||
{
|
||||
@@ -617,6 +629,8 @@ static int _fast_ping_process(struct ping_host_struct *ping_host, struct timeval
|
||||
return -1;
|
||||
}
|
||||
|
||||
recv_ping_host->send = 0;
|
||||
|
||||
_fast_ping_recvping(recv_ping_host, inpacket, len, now);
|
||||
return 0;
|
||||
errout:
|
||||
@@ -628,10 +642,24 @@ static void _fast_ping_period_run()
|
||||
struct ping_host_struct *ping_host;
|
||||
struct hlist_node *tmp;
|
||||
int i = 0;
|
||||
struct timeval now;
|
||||
struct timeval interval;
|
||||
uint64_t millisecond;
|
||||
gettimeofday(&now, 0);
|
||||
|
||||
pthread_mutex_lock(&ping.map_lock);
|
||||
hash_for_each_safe(ping.addrmap, i, tmp, ping_host, addr_node)
|
||||
{
|
||||
_fast_ping_sendping(ping_host);
|
||||
interval = now;
|
||||
tv_sub(&interval, &ping_host->last);
|
||||
millisecond = interval.tv_sec * 1000 + interval.tv_usec / 1000;
|
||||
if (millisecond > ping_host->timeout && ping_host->send == 1) {
|
||||
ping_callback(ping_host->host, PING_RESULT_TIMEOUT, ping_host->seq, &interval, ping_host->userptr);
|
||||
ping_host->send = 0;
|
||||
}
|
||||
if (millisecond >= ping_host->interval) {
|
||||
_fast_ping_sendping(ping_host);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&ping.map_lock);
|
||||
}
|
||||
@@ -643,14 +671,19 @@ static void *_fast_ping_work(void *arg)
|
||||
int i;
|
||||
struct timeval last = { 0 };
|
||||
struct timeval now = { 0 };
|
||||
struct timeval diff = {0};
|
||||
uint millisec = 0;
|
||||
|
||||
while (ping.run) {
|
||||
if (last.tv_sec != now.tv_sec) {
|
||||
diff = now;
|
||||
tv_sub(&diff, &last);
|
||||
millisec = diff.tv_sec * 1000 + diff.tv_usec / 1000;
|
||||
if (millisec >= 100) {
|
||||
_fast_ping_period_run();
|
||||
last = now;
|
||||
}
|
||||
|
||||
num = epoll_wait(ping.epoll_fd, events, PING_MAX_EVENTS, 1000);
|
||||
num = epoll_wait(ping.epoll_fd, events, PING_MAX_EVENTS, 100);
|
||||
if (num < 0) {
|
||||
gettimeofday(&now, 0);
|
||||
usleep(100000);
|
||||
@@ -727,7 +760,7 @@ errout:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fast_ping_exit()
|
||||
void fast_ping_exit()
|
||||
{
|
||||
if (ping.tid > 0) {
|
||||
void *ret = NULL;
|
||||
@@ -737,12 +770,12 @@ int fast_ping_exit()
|
||||
|
||||
if (ping.fd_icmp > 0) {
|
||||
close(ping.fd_icmp);
|
||||
ping.fd_icmp < 0;
|
||||
ping.fd_icmp = -1;
|
||||
}
|
||||
|
||||
if (ping.fd_icmp6 > 0) {
|
||||
close(ping.fd_icmp6);
|
||||
ping.fd_icmp6 < 0;
|
||||
ping.fd_icmp6 = -1;
|
||||
}
|
||||
|
||||
pthread_mutex_destroy(&ping.lock);
|
||||
|
||||
11
fast_ping.h
11
fast_ping.h
@@ -13,8 +13,13 @@ typedef enum {
|
||||
FAST_PING_UDP
|
||||
} FAST_PING_TYPE;
|
||||
|
||||
typedef void (*fast_ping_result)(const char *host, int seqno, struct timeval *tv, void *userptr);
|
||||
int fast_ping_result_callback(fast_ping_result result);
|
||||
typedef enum {
|
||||
PING_RESULT_RESPONSE = 1,
|
||||
PING_RESULT_TIMEOUT = 2,
|
||||
} FAST_PING_RESULT;
|
||||
|
||||
typedef void (*fast_ping_result)(const char *host, FAST_PING_RESULT result, int seqno, struct timeval *tv, void *userptr);
|
||||
void fast_ping_result_callback(fast_ping_result result);
|
||||
|
||||
int fast_ping_start(const char *host, int timeout, void *userptr);
|
||||
|
||||
@@ -22,7 +27,7 @@ int fast_ping_stop(const char *host);
|
||||
|
||||
int fast_ping_init();
|
||||
|
||||
int fast_ping_exit();
|
||||
void fast_ping_exit();
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#ifndef _GENERIC_ATOMIC_H
|
||||
#define _GENERIC_ATOMIC_H
|
||||
|
||||
|
||||
/* Check GCC version, just to be safe */
|
||||
#if !defined(__GNUC__) || (__GNUC__ < 4) || (__GNUC_MINOR__ < 1)
|
||||
# error atomic.h works only with GCC newer than version 4.1
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "bitops.h"
|
||||
#include "findbit.h"
|
||||
|
||||
|
||||
#define DECLARE_BITMAP(name,bits) \
|
||||
unsigned long name[BITS_TO_LONGS(bits)]
|
||||
@@ -101,7 +103,7 @@ static inline int test_and_set_bit(int nr, unsigned long *addr)
|
||||
*/
|
||||
static inline unsigned long *bitmap_alloc(int nbits)
|
||||
{
|
||||
return calloc(1, BITS_TO_LONGS(nbits) * sizeof(unsigned long));
|
||||
return (unsigned long *)calloc(1, BITS_TO_LONGS(nbits) * sizeof(unsigned long));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
162
include/bitops.h
162
include/bitops.h
@@ -2,6 +2,10 @@
|
||||
#ifndef _GENERIC_BITOPS_H_
|
||||
#define _GENERIC_BITOPS_H_
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include "gcc_builtin.h"
|
||||
|
||||
#ifndef __WORDSIZE
|
||||
#define __WORDSIZE (__SIZEOF_LONG__ * 8)
|
||||
#endif
|
||||
@@ -24,6 +28,164 @@ extern unsigned int __sw_hweight32(unsigned int w);
|
||||
extern unsigned long __sw_hweight64(uint64_t w);
|
||||
|
||||
|
||||
#define ffz(x) __ffs(~(x))
|
||||
|
||||
/**
|
||||
* fls - find last (most-significant) bit set
|
||||
* @x: the word to search
|
||||
*
|
||||
* This is defined the same way as ffs.
|
||||
* Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
|
||||
*/
|
||||
|
||||
/**
|
||||
* __ffs - find first bit in word.
|
||||
* @word: The word to search
|
||||
*
|
||||
* Undefined if no bit exists, so code should check against 0 first.
|
||||
*/
|
||||
static inline unsigned long __ffs(unsigned long word)
|
||||
{
|
||||
int num = 0;
|
||||
|
||||
#if __BITS_PER_LONG == 64
|
||||
if ((word & 0xffffffff) == 0) {
|
||||
num += 32;
|
||||
word >>= 32;
|
||||
}
|
||||
#endif
|
||||
if ((word & 0xffff) == 0) {
|
||||
num += 16;
|
||||
word >>= 16;
|
||||
}
|
||||
if ((word & 0xff) == 0) {
|
||||
num += 8;
|
||||
word >>= 8;
|
||||
}
|
||||
if ((word & 0xf) == 0) {
|
||||
num += 4;
|
||||
word >>= 4;
|
||||
}
|
||||
if ((word & 0x3) == 0) {
|
||||
num += 2;
|
||||
word >>= 2;
|
||||
}
|
||||
if ((word & 0x1) == 0)
|
||||
num += 1;
|
||||
return num;
|
||||
}
|
||||
|
||||
static inline int fls(int x)
|
||||
{
|
||||
int r = 32;
|
||||
|
||||
if (!x)
|
||||
return 0;
|
||||
if (!(x & 0xffff0000u)) {
|
||||
x <<= 16;
|
||||
r -= 16;
|
||||
}
|
||||
if (!(x & 0xff000000u)) {
|
||||
x <<= 8;
|
||||
r -= 8;
|
||||
}
|
||||
if (!(x & 0xf0000000u)) {
|
||||
x <<= 4;
|
||||
r -= 4;
|
||||
}
|
||||
if (!(x & 0xc0000000u)) {
|
||||
x <<= 2;
|
||||
r -= 2;
|
||||
}
|
||||
if (!(x & 0x80000000u)) {
|
||||
x <<= 1;
|
||||
r -= 1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* fls64 - find last set bit in a 64-bit word
|
||||
* @x: the word to search
|
||||
*
|
||||
* This is defined in a similar way as the libc and compiler builtin
|
||||
* ffsll, but returns the position of the most significant set bit.
|
||||
*
|
||||
* fls64(value) returns 0 if value is 0 or the position of the last
|
||||
* set bit if value is nonzero. The last (most significant) bit is
|
||||
* at position 64.
|
||||
*/
|
||||
#if BITS_PER_LONG == 32
|
||||
static inline int fls64(uint64_t x)
|
||||
{
|
||||
uint32_t h = x >> 32;
|
||||
if (h)
|
||||
return fls(h) + 32;
|
||||
return fls(x);
|
||||
}
|
||||
#elif BITS_PER_LONG == 64
|
||||
static inline int fls64(uint64_t x)
|
||||
{
|
||||
if (x == 0)
|
||||
return 0;
|
||||
return __fls(x) + 1;
|
||||
}
|
||||
#else
|
||||
#error BITS_PER_LONG not 32 or 64
|
||||
#endif
|
||||
|
||||
/**
|
||||
* hweightN - returns the hamming weight of a N-bit word
|
||||
* @x: the word to weigh
|
||||
*
|
||||
* The Hamming Weight of a number is the total number of bits set in it.
|
||||
*/
|
||||
|
||||
static inline unsigned int hweight32(unsigned int w)
|
||||
{
|
||||
unsigned int res = w - ((w >> 1) & 0x55555555);
|
||||
res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
|
||||
res = (res + (res >> 4)) & 0x0F0F0F0F;
|
||||
res = res + (res >> 8);
|
||||
return (res + (res >> 16)) & 0x000000FF;
|
||||
}
|
||||
|
||||
static inline unsigned int hweight16(unsigned int w)
|
||||
{
|
||||
unsigned int res = w - ((w >> 1) & 0x5555);
|
||||
res = (res & 0x3333) + ((res >> 2) & 0x3333);
|
||||
res = (res + (res >> 4)) & 0x0F0F;
|
||||
return (res + (res >> 8)) & 0x00FF;
|
||||
}
|
||||
|
||||
static inline unsigned int hweight8(unsigned int w)
|
||||
{
|
||||
unsigned int res = w - ((w >> 1) & 0x55);
|
||||
res = (res & 0x33) + ((res >> 2) & 0x33);
|
||||
return (res + (res >> 4)) & 0x0F;
|
||||
}
|
||||
|
||||
static inline unsigned long hweight64(uint64_t w)
|
||||
{
|
||||
#if BITS_PER_LONG == 32
|
||||
return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w);
|
||||
#elif BITS_PER_LONG == 64
|
||||
#ifdef ARCH_HAS_FAST_MULTIPLIER
|
||||
w -= (w >> 1) & 0x5555555555555555ul;
|
||||
w = (w & 0x3333333333333333ul) + ((w >> 2) & 0x3333333333333333ul);
|
||||
w = (w + (w >> 4)) & 0x0f0f0f0f0f0f0f0ful;
|
||||
return (w * 0x0101010101010101ul) >> 56;
|
||||
#else
|
||||
uint64_t res = w - ((w >> 1) & 0x5555555555555555ul);
|
||||
res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul);
|
||||
res = (res + (res >> 4)) & 0x0F0F0F0F0F0F0F0Ful;
|
||||
res = res + (res >> 8);
|
||||
res = res + (res >> 16);
|
||||
return (res + (res >> 32)) & 0x00000000000000FFul;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#define for_each_set_bit(bit, addr, size) \
|
||||
for ((bit) = find_first_bit((addr), (size)); \
|
||||
(bit) < (size); \
|
||||
|
||||
78
include/findbit.h
Normal file
78
include/findbit.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_
|
||||
#define _TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_
|
||||
|
||||
#ifndef find_next_bit
|
||||
/**
|
||||
* find_next_bit - find the next set bit in a memory region
|
||||
* @addr: The address to base the search on
|
||||
* @offset: The bitnumber to start searching at
|
||||
* @size: The bitmap size in bits
|
||||
*
|
||||
* Returns the bit number for the next set bit
|
||||
* If no bits are set, returns @size.
|
||||
*/
|
||||
extern unsigned long find_next_bit(const unsigned long *addr, unsigned long
|
||||
size, unsigned long offset);
|
||||
#endif
|
||||
|
||||
#ifndef find_next_and_bit
|
||||
/**
|
||||
* find_next_and_bit - find the next set bit in both memory regions
|
||||
* @addr1: The first address to base the search on
|
||||
* @addr2: The second address to base the search on
|
||||
* @offset: The bitnumber to start searching at
|
||||
* @size: The bitmap size in bits
|
||||
*
|
||||
* Returns the bit number for the next set bit
|
||||
* If no bits are set, returns @size.
|
||||
*/
|
||||
extern unsigned long find_next_and_bit(const unsigned long *addr1,
|
||||
const unsigned long *addr2, unsigned long size,
|
||||
unsigned long offset);
|
||||
#endif
|
||||
|
||||
#ifndef find_next_zero_bit
|
||||
|
||||
/**
|
||||
* find_next_zero_bit - find the next cleared bit in a memory region
|
||||
* @addr: The address to base the search on
|
||||
* @offset: The bitnumber to start searching at
|
||||
* @size: The bitmap size in bits
|
||||
*
|
||||
* Returns the bit number of the next zero bit
|
||||
* If no bits are zero, returns @size.
|
||||
*/
|
||||
unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
|
||||
unsigned long offset);
|
||||
#endif
|
||||
|
||||
#ifndef find_first_bit
|
||||
|
||||
/**
|
||||
* find_first_bit - find the first set bit in a memory region
|
||||
* @addr: The address to start the search at
|
||||
* @size: The maximum number of bits to search
|
||||
*
|
||||
* Returns the bit number of the first set bit.
|
||||
* If no bits are set, returns @size.
|
||||
*/
|
||||
extern unsigned long find_first_bit(const unsigned long *addr,
|
||||
unsigned long size);
|
||||
|
||||
#endif /* find_first_bit */
|
||||
|
||||
#ifndef find_first_zero_bit
|
||||
|
||||
/**
|
||||
* find_first_zero_bit - find the first cleared bit in a memory region
|
||||
* @addr: The address to start the search at
|
||||
* @size: The maximum number of bits to search
|
||||
*
|
||||
* Returns the bit number of the first cleared bit.
|
||||
* If no bits are zero, returns @size.
|
||||
*/
|
||||
unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size);
|
||||
#endif
|
||||
|
||||
#endif /*_TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_ */
|
||||
118
include/gcc_builtin.h
Normal file
118
include/gcc_builtin.h
Normal file
@@ -0,0 +1,118 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _TOOLS_LINUX_COMPILER_H_
|
||||
#define _TOOLS_LINUX_COMPILER_H_
|
||||
|
||||
#ifndef __compiletime_error
|
||||
# define __compiletime_error(message)
|
||||
#endif
|
||||
|
||||
/* Optimization barrier */
|
||||
/* The "volatile" is due to gcc bugs */
|
||||
#define barrier() __asm__ __volatile__("": : :"memory")
|
||||
|
||||
#ifndef __always_inline
|
||||
# define __always_inline inline __attribute__((always_inline))
|
||||
#endif
|
||||
|
||||
#ifndef noinline
|
||||
#define noinline
|
||||
#endif
|
||||
|
||||
/* Are two types/vars the same type (ignoring qualifiers)? */
|
||||
#ifndef __same_type
|
||||
# define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
|
||||
#endif
|
||||
|
||||
#ifdef __ANDROID__
|
||||
/*
|
||||
* FIXME: Big hammer to get rid of tons of:
|
||||
* "warning: always_inline function might not be inlinable"
|
||||
*
|
||||
* At least on android-ndk-r12/platforms/android-24/arch-arm
|
||||
*/
|
||||
#undef __always_inline
|
||||
#define __always_inline inline
|
||||
#endif
|
||||
|
||||
#define __user
|
||||
#define __rcu
|
||||
#define __read_mostly
|
||||
|
||||
#ifndef __attribute_const__
|
||||
# define __attribute_const__
|
||||
#endif
|
||||
|
||||
#ifndef __maybe_unused
|
||||
# define __maybe_unused __attribute__((unused))
|
||||
#endif
|
||||
|
||||
#ifndef __used
|
||||
# define __used __attribute__((__unused__))
|
||||
#endif
|
||||
|
||||
#ifndef __packed
|
||||
# define __packed __attribute__((__packed__))
|
||||
#endif
|
||||
|
||||
#ifndef __force
|
||||
# define __force
|
||||
#endif
|
||||
|
||||
#ifndef __weak
|
||||
# define __weak __attribute__((weak))
|
||||
#endif
|
||||
|
||||
#ifndef likely
|
||||
# define likely(x) __builtin_expect(!!(x), 1)
|
||||
#endif
|
||||
|
||||
#ifndef unlikely
|
||||
# define unlikely(x) __builtin_expect(!!(x), 0)
|
||||
#endif
|
||||
|
||||
#ifndef __init
|
||||
# define __init
|
||||
#endif
|
||||
|
||||
#ifndef noinline
|
||||
# define noinline
|
||||
#endif
|
||||
|
||||
#define uninitialized_var(x) x = *(&(x))
|
||||
|
||||
#ifndef __fallthrough
|
||||
# define __fallthrough
|
||||
#endif
|
||||
|
||||
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
|
||||
|
||||
#ifndef max
|
||||
#define max(x, y) ({ \
|
||||
typeof(x) _max1 = (x); \
|
||||
typeof(y) _max2 = (y); \
|
||||
(void) (&_max1 == &_max2); \
|
||||
_max1 > _max2 ? _max1 : _max2; })
|
||||
#endif
|
||||
|
||||
#ifndef min
|
||||
#define min(x, y) ({ \
|
||||
typeof(x) _min1 = (x); \
|
||||
typeof(y) _min2 = (y); \
|
||||
(void) (&_min1 == &_min2); \
|
||||
_min1 < _min2 ? _min1 : _min2; })
|
||||
#endif
|
||||
|
||||
#ifndef roundup
|
||||
#define roundup(x, y) ( \
|
||||
{ \
|
||||
const typeof(y) __y = y; \
|
||||
(((x) + (__y - 1)) / __y) * __y; \
|
||||
} \
|
||||
)
|
||||
#endif
|
||||
|
||||
#define __round_mask(x, y) ((__typeof__(x))((y)-1))
|
||||
#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
|
||||
#define round_down(x, y) ((x) & ~__round_mask(x, y))
|
||||
|
||||
#endif /* _TOOLS_LINUX_COMPILER_H */
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef _GENERIC_HASH_H
|
||||
#define _GENERIC_HASH_H
|
||||
|
||||
#include "bitmap.h"
|
||||
#include "jhash.h"
|
||||
|
||||
/* Fast hashing routine for ints, longs and pointers.
|
||||
@@ -113,6 +114,17 @@ int __ilog2_u64(uint64_t n)
|
||||
__ilog2_u64(n) \
|
||||
)
|
||||
|
||||
|
||||
#if BITS_PER_LONG == 32
|
||||
#define GOLDEN_RATIO_PRIME GOLDEN_RATIO_32
|
||||
#define hash_long(val, bits) hash_32(val, bits)
|
||||
#elif BITS_PER_LONG == 64
|
||||
#define hash_long(val, bits) hash_64(val, bits)
|
||||
#define GOLDEN_RATIO_PRIME GOLDEN_RATIO_64
|
||||
#else
|
||||
#error Wordsize not 32 or 64
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This hash multiplies the input by a large odd number and takes the
|
||||
* high bits. Since multiplication propagates changes to the most
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
#include "list.h"
|
||||
#include "hash.h"
|
||||
#include "bitmap.h"
|
||||
|
||||
#ifndef __same_type
|
||||
# define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
|
||||
@@ -149,5 +148,4 @@ static inline void hash_del(struct hlist_node *node)
|
||||
hlist_for_each_entry_safe(obj, tmp,\
|
||||
&name[hash_min(key, HASH_BITS(name))], member)
|
||||
|
||||
|
||||
#endif
|
||||
@@ -79,7 +79,7 @@ static inline uint32_t __get_unaligned_cpu32(const void *p)
|
||||
static inline uint32_t jhash(const void *key, uint32_t length, uint32_t initval)
|
||||
{
|
||||
uint32_t a, b, c;
|
||||
const uint8_t *k = key;
|
||||
const uint8_t *k = (uint8_t *)key;
|
||||
|
||||
/* Set up the internal state */
|
||||
a = b = c = JHASH_INITVAL + length + initval;
|
||||
|
||||
@@ -60,46 +60,46 @@ static inline void INIT_LIST_HEAD(struct list_head *list)
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert a new entry between two known consecutive entries.
|
||||
* Insert a add entry between two known consecutive entries.
|
||||
*
|
||||
* This is only for internal list manipulation where we know
|
||||
* the prev/next entries already!
|
||||
*/
|
||||
static inline void __list_add(struct list_head *new,
|
||||
static inline void __list_add(struct list_head *add,
|
||||
struct list_head *prev,
|
||||
struct list_head *next)
|
||||
{
|
||||
next->prev = new;
|
||||
new->next = next;
|
||||
new->prev = prev;
|
||||
prev->next = new;
|
||||
next->prev = add;
|
||||
add->next = next;
|
||||
add->prev = prev;
|
||||
prev->next = add;
|
||||
}
|
||||
|
||||
/**
|
||||
* list_add - add a new entry
|
||||
* @new: new entry to be added
|
||||
* list_add - add a add entry
|
||||
* @add: add entry to be added
|
||||
* @head: list head to add it after
|
||||
*
|
||||
* Insert a new entry after the specified head.
|
||||
* Insert a add entry after the specified head.
|
||||
* This is good for implementing stacks.
|
||||
*/
|
||||
static inline void list_add(struct list_head *new, struct list_head *head)
|
||||
static inline void list_add(struct list_head *add, struct list_head *head)
|
||||
{
|
||||
__list_add(new, head, head->next);
|
||||
__list_add(add, head, head->next);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* list_add_tail - add a new entry
|
||||
* @new: new entry to be added
|
||||
* list_add_tail - add a add entry
|
||||
* @add: add entry to be added
|
||||
* @head: list head to add it before
|
||||
*
|
||||
* Insert a new entry before the specified head.
|
||||
* Insert a add entry before the specified head.
|
||||
* This is useful for implementing queues.
|
||||
*/
|
||||
static inline void list_add_tail(struct list_head *new, struct list_head *head)
|
||||
static inline void list_add_tail(struct list_head *add, struct list_head *head)
|
||||
{
|
||||
__list_add(new, head->prev, head);
|
||||
__list_add(add, head->prev, head);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -129,30 +129,30 @@ static inline void __list_del_entry(struct list_head *entry)
|
||||
static inline void list_del(struct list_head *entry)
|
||||
{
|
||||
__list_del(entry->prev, entry->next);
|
||||
entry->next = LIST_POISON1;
|
||||
entry->prev = LIST_POISON2;
|
||||
entry->next = (struct list_head *)LIST_POISON1;
|
||||
entry->prev = (struct list_head *)LIST_POISON2;
|
||||
}
|
||||
|
||||
/**
|
||||
* list_replace - replace old entry by new one
|
||||
* list_replace - replace old entry by add one
|
||||
* @old : the element to be replaced
|
||||
* @new : the new element to insert
|
||||
* @add : the add element to insert
|
||||
*
|
||||
* If @old was empty, it will be overwritten.
|
||||
*/
|
||||
static inline void list_replace(struct list_head *old,
|
||||
struct list_head *new)
|
||||
struct list_head *add)
|
||||
{
|
||||
new->next = old->next;
|
||||
new->next->prev = new;
|
||||
new->prev = old->prev;
|
||||
new->prev->next = new;
|
||||
add->next = old->next;
|
||||
add->next->prev = add;
|
||||
add->prev = old->prev;
|
||||
add->prev->next = add;
|
||||
}
|
||||
|
||||
static inline void list_replace_init(struct list_head *old,
|
||||
struct list_head *new)
|
||||
struct list_head *add)
|
||||
{
|
||||
list_replace(old, new);
|
||||
list_replace(old, add);
|
||||
INIT_LIST_HEAD(old);
|
||||
}
|
||||
|
||||
@@ -265,7 +265,7 @@ static inline void __list_cut_position(struct list_head *list,
|
||||
|
||||
/**
|
||||
* list_cut_position - cut a list into two
|
||||
* @list: a new list to add all removed entries
|
||||
* @list: a add list to add all removed entries
|
||||
* @head: a list with entries
|
||||
* @entry: an entry within head, could be the head itself
|
||||
* and if so we won't cut the list
|
||||
@@ -307,7 +307,7 @@ static inline void __list_splice(const struct list_head *list,
|
||||
|
||||
/**
|
||||
* list_splice - join two lists, this is designed for stacks
|
||||
* @list: the new list to add.
|
||||
* @list: the add list to add.
|
||||
* @head: the place to add it in the first list.
|
||||
*/
|
||||
static inline void list_splice(const struct list_head *list,
|
||||
@@ -319,7 +319,7 @@ static inline void list_splice(const struct list_head *list,
|
||||
|
||||
/**
|
||||
* list_splice_tail - join two lists, each list being a queue
|
||||
* @list: the new list to add.
|
||||
* @list: the add list to add.
|
||||
* @head: the place to add it in the first list.
|
||||
*/
|
||||
static inline void list_splice_tail(struct list_head *list,
|
||||
@@ -331,7 +331,7 @@ static inline void list_splice_tail(struct list_head *list,
|
||||
|
||||
/**
|
||||
* list_splice_init - join two lists and reinitialise the emptied list.
|
||||
* @list: the new list to add.
|
||||
* @list: the add list to add.
|
||||
* @head: the place to add it in the first list.
|
||||
*
|
||||
* The list at @list is reinitialised
|
||||
@@ -347,7 +347,7 @@ static inline void list_splice_init(struct list_head *list,
|
||||
|
||||
/**
|
||||
* list_splice_tail_init - join two lists and reinitialise the emptied list
|
||||
* @list: the new list to add.
|
||||
* @list: the add list to add.
|
||||
* @head: the place to add it in the first list.
|
||||
*
|
||||
* Each of the lists is a queue.
|
||||
@@ -644,8 +644,8 @@ static inline void __hlist_del(struct hlist_node *n)
|
||||
static inline void hlist_del(struct hlist_node *n)
|
||||
{
|
||||
__hlist_del(n);
|
||||
n->next = LIST_POISON1;
|
||||
n->pprev = LIST_POISON2;
|
||||
n->next = (struct hlist_node *)LIST_POISON1;
|
||||
n->pprev = (struct hlist_node **)LIST_POISON2;
|
||||
}
|
||||
|
||||
static inline void hlist_del_init(struct hlist_node *n)
|
||||
@@ -703,11 +703,11 @@ static inline bool hlist_fake(struct hlist_node *h)
|
||||
* reference of the first entry if it exists.
|
||||
*/
|
||||
static inline void hlist_move_list(struct hlist_head *old,
|
||||
struct hlist_head *new)
|
||||
struct hlist_head *add)
|
||||
{
|
||||
new->first = old->first;
|
||||
if (new->first)
|
||||
new->first->pprev = &new->first;
|
||||
add->first = old->first;
|
||||
if (add->first)
|
||||
add->first->pprev = &add->first;
|
||||
old->first = NULL;
|
||||
}
|
||||
|
||||
|
||||
154
lib/bitops.c
Normal file
154
lib/bitops.c
Normal file
@@ -0,0 +1,154 @@
|
||||
|
||||
#include "bitmap.h"
|
||||
#include "bitops.h"
|
||||
|
||||
/*
|
||||
* This is a common helper function for find_next_bit, find_next_zero_bit, and
|
||||
* find_next_and_bit. The differences are:
|
||||
* - The "invert" argument, which is XORed with each fetched word before
|
||||
* searching it for one bits.
|
||||
* - The optional "addr2", which is anded with "addr1" if present.
|
||||
*/
|
||||
static inline unsigned long _find_next_bit(const unsigned long *addr1,
|
||||
const unsigned long *addr2, unsigned long nbits,
|
||||
unsigned long start, unsigned long invert)
|
||||
{
|
||||
unsigned long tmp;
|
||||
|
||||
if (unlikely(start >= nbits))
|
||||
return nbits;
|
||||
|
||||
tmp = addr1[start / BITS_PER_LONG];
|
||||
if (addr2)
|
||||
tmp &= addr2[start / BITS_PER_LONG];
|
||||
tmp ^= invert;
|
||||
|
||||
/* Handle 1st word. */
|
||||
tmp &= BITMAP_FIRST_WORD_MASK(start);
|
||||
start = round_down(start, BITS_PER_LONG);
|
||||
|
||||
while (!tmp) {
|
||||
start += BITS_PER_LONG;
|
||||
if (start >= nbits)
|
||||
return nbits;
|
||||
|
||||
tmp = addr1[start / BITS_PER_LONG];
|
||||
if (addr2)
|
||||
tmp &= addr2[start / BITS_PER_LONG];
|
||||
tmp ^= invert;
|
||||
}
|
||||
|
||||
return min(start + __ffs(tmp), nbits);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the next set bit in a memory region.
|
||||
*/
|
||||
unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
|
||||
unsigned long offset)
|
||||
{
|
||||
return _find_next_bit(addr, NULL, size, offset, 0UL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the first set bit in a memory region.
|
||||
*/
|
||||
unsigned long find_first_bit(const unsigned long *addr, unsigned long size)
|
||||
{
|
||||
unsigned long idx;
|
||||
|
||||
for (idx = 0; idx * BITS_PER_LONG < size; idx++) {
|
||||
if (addr[idx])
|
||||
return min(idx * BITS_PER_LONG + __ffs(addr[idx]), size);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the first cleared bit in a memory region.
|
||||
*/
|
||||
unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size)
|
||||
{
|
||||
unsigned long idx;
|
||||
|
||||
for (idx = 0; idx * BITS_PER_LONG < size; idx++) {
|
||||
if (addr[idx] != ~0UL)
|
||||
return min(idx * BITS_PER_LONG + ffz(addr[idx]), size);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
|
||||
unsigned long offset)
|
||||
{
|
||||
return _find_next_bit(addr, NULL, size, offset, ~0UL);
|
||||
}
|
||||
|
||||
unsigned long find_next_and_bit(const unsigned long *addr1,
|
||||
const unsigned long *addr2, unsigned long size,
|
||||
unsigned long offset)
|
||||
{
|
||||
return _find_next_bit(addr1, addr2, size, offset, 0UL);
|
||||
}
|
||||
|
||||
/**
|
||||
* hweightN - returns the hamming weight of a N-bit word
|
||||
* @x: the word to weigh
|
||||
*
|
||||
* The Hamming Weight of a number is the total number of bits set in it.
|
||||
*/
|
||||
|
||||
unsigned int __sw_hweight32(unsigned int w)
|
||||
{
|
||||
#ifdef CONFIG_ARCH_HAS_FAST_MULTIPLIER
|
||||
w -= (w >> 1) & 0x55555555;
|
||||
w = (w & 0x33333333) + ((w >> 2) & 0x33333333);
|
||||
w = (w + (w >> 4)) & 0x0f0f0f0f;
|
||||
return (w * 0x01010101) >> 24;
|
||||
#else
|
||||
unsigned int res = w - ((w >> 1) & 0x55555555);
|
||||
res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
|
||||
res = (res + (res >> 4)) & 0x0F0F0F0F;
|
||||
res = res + (res >> 8);
|
||||
return (res + (res >> 16)) & 0x000000FF;
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned int __sw_hweight16(unsigned int w)
|
||||
{
|
||||
unsigned int res = w - ((w >> 1) & 0x5555);
|
||||
res = (res & 0x3333) + ((res >> 2) & 0x3333);
|
||||
res = (res + (res >> 4)) & 0x0F0F;
|
||||
return (res + (res >> 8)) & 0x00FF;
|
||||
}
|
||||
|
||||
unsigned int __sw_hweight8(unsigned int w)
|
||||
{
|
||||
unsigned int res = w - ((w >> 1) & 0x55);
|
||||
res = (res & 0x33) + ((res >> 2) & 0x33);
|
||||
return (res + (res >> 4)) & 0x0F;
|
||||
}
|
||||
|
||||
unsigned long __sw_hweight64(uint64_t w)
|
||||
{
|
||||
#if BITS_PER_LONG == 32
|
||||
return __sw_hweight32((unsigned int)(w >> 32)) +
|
||||
__sw_hweight32((unsigned int)w);
|
||||
#elif BITS_PER_LONG == 64
|
||||
#ifdef CONFIG_ARCH_HAS_FAST_MULTIPLIER
|
||||
w -= (w >> 1) & 0x5555555555555555ul;
|
||||
w = (w & 0x3333333333333333ul) + ((w >> 2) & 0x3333333333333333ul);
|
||||
w = (w + (w >> 4)) & 0x0f0f0f0f0f0f0f0ful;
|
||||
return (w * 0x0101010101010101ul) >> 56;
|
||||
#else
|
||||
uint64_t res = w - ((w >> 1) & 0x5555555555555555ul);
|
||||
res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul);
|
||||
res = (res + (res >> 4)) & 0x0F0F0F0F0F0F0F0Ful;
|
||||
res = res + (res >> 8);
|
||||
res = res + (res >> 16);
|
||||
return (res + (res >> 32)) & 0x00000000000000FFul;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
180
smartdns.c
180
smartdns.c
@@ -1,132 +1,136 @@
|
||||
#include "fast_ping.h"
|
||||
#include "hashtable.h"
|
||||
#include "list.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "fast_ping.h"
|
||||
#include "list.h"
|
||||
#include "bitmap.h"
|
||||
#include "hashtable.h"
|
||||
|
||||
void smartdns_ping_result(const char *host, int seqno, struct timeval *tv, void *userptr)
|
||||
void smartdns_ping_result(const char *host, FAST_PING_RESULT result, int seqno, struct timeval *tv, void *userptr)
|
||||
{
|
||||
double rtt = tv->tv_sec * 1000.0 + tv->tv_usec / 1000.0;
|
||||
printf("%16s: seq=%d time=%.3f\n", host, seqno, rtt);
|
||||
if (result == PING_RESULT_RESPONSE) {
|
||||
double rtt = tv->tv_sec * 1000.0 + tv->tv_usec / 1000.0;
|
||||
printf("%16s: seq=%d time=%.3f\n", host, seqno, rtt);
|
||||
} else if (result == PING_RESULT_TIMEOUT) {
|
||||
printf("%16s: seq=%d timeout\n", host, seqno);
|
||||
}
|
||||
}
|
||||
|
||||
int smartdns_init()
|
||||
{
|
||||
int ret;
|
||||
int ret;
|
||||
|
||||
ret = fast_ping_init();
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "start ping failed.\n");
|
||||
goto errout;
|
||||
}
|
||||
ret = fast_ping_init();
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "start ping failed.\n");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
fast_ping_result_callback(smartdns_ping_result);
|
||||
fast_ping_result_callback(smartdns_ping_result);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
errout:
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int smartdns_run()
|
||||
{
|
||||
sleep(1);
|
||||
fast_ping_start("192.168.1.1", 2000, 0);
|
||||
fast_ping_start("192.168.1.35", 2000, 0);
|
||||
fast_ping_start("14.215.177.38", 2000, 0);
|
||||
fast_ping_start("113.96.161.87", 2000, 0);
|
||||
//fast_ping_start("::1", 2000, 0);
|
||||
while (1) {
|
||||
sleep(10);
|
||||
//fast_ping_stop("192.168.1.35");
|
||||
}
|
||||
fast_ping_start("192.168.1.1", 2000, 0);
|
||||
fast_ping_start("192.168.1.35", 2000, 0);
|
||||
fast_ping_start("14.215.177.38", 2000, 0);
|
||||
fast_ping_start("113.96.161.87", 2000, 0);
|
||||
fast_ping_start("::1", 2000, 0);
|
||||
fast_ping_start("12.4.3.1", 1000, 0);
|
||||
while (1) {
|
||||
sleep(10);
|
||||
//fast_ping_stop("192.168.1.35");
|
||||
}
|
||||
}
|
||||
|
||||
void smartdns_exit()
|
||||
{
|
||||
fast_ping_exit();
|
||||
fast_ping_exit();
|
||||
}
|
||||
|
||||
struct data {
|
||||
struct list_head list;
|
||||
int n;
|
||||
struct list_head list;
|
||||
int n;
|
||||
};
|
||||
|
||||
void list_test()
|
||||
{
|
||||
struct list_head head ;
|
||||
struct list_head *iter;
|
||||
int i = 0;
|
||||
struct list_head head;
|
||||
struct list_head *iter;
|
||||
int i = 0;
|
||||
|
||||
INIT_LIST_HEAD(&head);
|
||||
INIT_LIST_HEAD(&head);
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
struct data *h = malloc(sizeof(struct data));
|
||||
h->n = i;
|
||||
list_add(&h->list, &head);
|
||||
}
|
||||
for (i = 0; i < 10; i++) {
|
||||
struct data *h = malloc(sizeof(struct data));
|
||||
h->n = i;
|
||||
list_add(&h->list, &head);
|
||||
}
|
||||
|
||||
list_for_each(iter, &head) {
|
||||
struct data *d= list_entry(iter, struct data, list);
|
||||
list_for_each(iter, &head)
|
||||
{
|
||||
struct data *d = list_entry(iter, struct data, list);
|
||||
printf("%d\n", d->n);
|
||||
}
|
||||
}
|
||||
|
||||
struct data_hash {
|
||||
struct hlist_node node;
|
||||
int n;
|
||||
char str[32];
|
||||
struct hlist_node node;
|
||||
int n;
|
||||
char str[32];
|
||||
};
|
||||
|
||||
int hash_test()
|
||||
{
|
||||
DEFINE_HASHTABLE(ht, 7);
|
||||
struct data_hash *temp;
|
||||
struct data_hash *obj;
|
||||
int i;
|
||||
int j;
|
||||
int key;
|
||||
DEFINE_HASHTABLE(ht, 7);
|
||||
struct data_hash *temp;
|
||||
struct data_hash *obj;
|
||||
int i;
|
||||
int key;
|
||||
|
||||
for (i = 11; i < 17; i++) {
|
||||
temp = malloc(sizeof(struct data_hash));
|
||||
temp->n = i * i;
|
||||
hash_add(ht, &temp->node, temp->n);
|
||||
}
|
||||
for (i = 11; i < 17; i++) {
|
||||
temp = malloc(sizeof(struct data_hash));
|
||||
temp->n = i * i;
|
||||
hash_add(ht, &temp->node, temp->n);
|
||||
}
|
||||
|
||||
for (i = 11; i < 17; i++) {
|
||||
key = i * i;
|
||||
hash_for_each_possible(ht, obj, node, key) {
|
||||
printf("value: %d\n", obj->n);
|
||||
};
|
||||
}
|
||||
for (i = 11; i < 17; i++) {
|
||||
key = i * i;
|
||||
hash_for_each_possible(ht, obj, node, key)
|
||||
{
|
||||
printf("value: %d\n", obj->n);
|
||||
};
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hash_string_test()
|
||||
{
|
||||
DEFINE_HASHTABLE(ht, 7);
|
||||
struct data_hash *temp;
|
||||
struct data_hash *obj;
|
||||
int i;
|
||||
int j;
|
||||
int key;
|
||||
DEFINE_HASHTABLE(ht, 7);
|
||||
struct data_hash *temp;
|
||||
struct data_hash *obj;
|
||||
int i;
|
||||
int key;
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
temp = malloc(sizeof(struct data_hash));
|
||||
sprintf(temp->str, "%d", i);
|
||||
hash_add(ht, &temp->node, hash_string(temp->str));
|
||||
}
|
||||
for (i = 0; i < 10; i++) {
|
||||
temp = malloc(sizeof(struct data_hash));
|
||||
sprintf(temp->str, "%d", i);
|
||||
hash_add(ht, &temp->node, hash_string(temp->str));
|
||||
}
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
char key_str[32];
|
||||
sprintf(key_str, "%d", i);
|
||||
key = hash_string(key_str);
|
||||
hash_for_each_possible(ht, obj, node, key) {
|
||||
printf("i = %d value: %s\n", i, obj->str);
|
||||
};
|
||||
}
|
||||
for (i = 0; i < 10; i++) {
|
||||
char key_str[32];
|
||||
sprintf(key_str, "%d", i);
|
||||
key = hash_string(key_str);
|
||||
hash_for_each_possible(ht, obj, node, key)
|
||||
{
|
||||
printf("i = %d value: %s\n", i, obj->str);
|
||||
};
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -171,19 +175,19 @@ int rbtree_test()
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret;
|
||||
int ret;
|
||||
|
||||
atexit(smartdns_exit);
|
||||
atexit(smartdns_exit);
|
||||
|
||||
ret = smartdns_init();
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "init smartdns failed.\n");
|
||||
goto errout;
|
||||
}
|
||||
ret = smartdns_init();
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "init smartdns failed.\n");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
return smartdns_run();
|
||||
return smartdns_run();
|
||||
|
||||
errout:
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
Reference in New Issue
Block a user