Browse Source

mdig : multithread digger

pull/31/head
bolvan 6 years ago
parent
commit
0d58f6171e
  1. BIN
      binaries/aarch64/mdig
  2. BIN
      binaries/armhf/mdig
  3. BIN
      binaries/mips32r1-lsb/mdig
  4. BIN
      binaries/mips32r1-msb/mdig
  5. BIN
      binaries/x86/mdig
  6. BIN
      binaries/x86_64/mdig
  7. 3
      changes.txt
  8. 32
      compile/openwrt/package/zapret/mdig/Makefile
  9. 1
      compile/openwrt/package/zapret/mdig/readme.txt
  10. 16
      ipset/get_reestr.sh
  11. 12
      mdig/Makefile
  12. 243
      mdig/mdig.c
  13. 12
      readme.txt

BIN
binaries/aarch64/mdig

Binary file not shown.

BIN
binaries/armhf/mdig

Binary file not shown.

BIN
binaries/mips32r1-lsb/mdig

Binary file not shown.

BIN
binaries/mips32r1-msb/mdig

Binary file not shown.

BIN
binaries/x86/mdig

Binary file not shown.

BIN
binaries/x86_64/mdig

Binary file not shown.

3
changes.txt

@ -99,3 +99,6 @@ tpws : added hostlist option
v20 v20
added ip2net. ip2net groups ips from iplist into subnets and reduces ipset size twice added ip2net. ip2net groups ips from iplist into subnets and reduces ipset size twice
v21
added mdig. get_reestr.sh is *real* again

32
compile/openwrt/package/zapret/mdig/Makefile

@ -0,0 +1,32 @@
#
include $(TOPDIR)/rules.mk
PKG_NAME:=mdig
PKG_RELEASE:=1
include $(INCLUDE_DIR)/package.mk
define Package/mdig
SECTION:=net
CATEGORY:=Network
TITLE:=mdig
SUBMENU:=Zapret
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./mdig/* $(PKG_BUILD_DIR)/
endef
define Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR) $(TARGET_CONFIGURE_OPTS)
endef
define Package/mdig/install
$(INSTALL_DIR) $(1)/opt/zapret/mdig
$(INSTALL_BIN) $(PKG_BUILD_DIR)/mdig $(1)/opt/zapret/mdig
endef
$(eval $(call BuildPackage,mdig))

1
compile/openwrt/package/zapret/mdig/readme.txt

@ -0,0 +1 @@
Copy "mdig" folder here !

16
ipset/get_reestr.sh

@ -12,6 +12,18 @@ ZIPLISTTMP=$TMPDIR/zapret-ip.txt
#ZURL=https://reestr.rublacklist.net/api/current #ZURL=https://reestr.rublacklist.net/api/current
ZURL=https://raw.githubusercontent.com/zapret-info/z-i/master/dump.csv ZURL=https://raw.githubusercontent.com/zapret-info/z-i/master/dump.csv
MDIG=$EXEDIR/../mdig/mdig
MDIG_THREADS=30
digger()
{
if [ -x $MDIG ]; then
$MDIG --family=4 --threads=$MDIG_THREADS <$1
else
dig A +short +time=8 +tries=2 -f $1
fi
}
getuser getuser
curl -k --fail --max-time 300 --max-filesize 41943040 "$ZURL" >$ZREESTR || curl -k --fail --max-time 300 --max-filesize 41943040 "$ZURL" >$ZREESTR ||
@ -30,12 +42,12 @@ echo preparing dig list ..
cut -f2 -d';' $ZREESTR | grep -avE '^$|\*|:' >$ZDIG cut -f2 -d';' $ZREESTR | grep -avE '^$|\*|:' >$ZDIG
rm -f $ZREESTR rm -f $ZREESTR
echo digging started ... echo digging started ...
dig A +short +time=8 +tries=2 -f $ZDIG | grep -E '^[^;].*[^\.]$' | grep -vE '^192\.168\.[0-9]+\.[0-9]+$' | grep -vE '^127\.[0-9]+\.[0-9]+\.[0-9]+$' | grep -vE '^10\.[0-9]+\.[0-9]+\.[0-9]+$' >$ZIPLISTTMP || { digger $ZDIG | grep -E '^[^;].*[^\.]$' | grep -vE '^192\.168\.[0-9]+\.[0-9]+$' | grep -vE '^127\.[0-9]+\.[0-9]+\.[0-9]+$' | grep -vE '^10\.[0-9]+\.[0-9]+\.[0-9]+$' >$ZIPLISTTMP || {
rm -f $ZDIG rm -f $ZDIG
exit 1 exit 1
} }
rm -f $ZDIG $ZIPLIST rm -f $ZDIG $ZIPLIST
sort $ZIPLISTTMP | uniq >$ZIPLIST sort -u $ZIPLISTTMP >$ZIPLIST
rm -f $ZIPLISTTMP rm -f $ZIPLISTTMP
"$EXEDIR/create_ipset.sh" "$EXEDIR/create_ipset.sh"

12
mdig/Makefile

@ -0,0 +1,12 @@
CC ?= gcc
CFLAGS += -s -O3
LIBS =
SRC_FILES = *.c
all: mdig
mdig: $(SRC_FILES)
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LIBS)
clean:
rm -f mdig *.o

243
mdig/mdig.c

@ -0,0 +1,243 @@
// multi thread dns resolver
// domain list <stdin
// ip list >stdout
// errors, verbose >stderr
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <getopt.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#define RESOLVER_EAGAIN_ATTEMPTS 3
void trimstr(char *s)
{
char *p;
for (p = s + strlen(s) - 1; p >= s && (*p == '\n' || *p == '\r'); p--) *p = '\0';
}
const char* eai_str(int r)
{
switch (r)
{
case EAI_NONAME:
return "EAI_NONAME";
case EAI_AGAIN:
return "EAI_AGAIN";
case EAI_ADDRFAMILY:
return "EAI_ADDRFAMILY";
case EAI_BADFLAGS:
return "EAI_BADFLAGS";
case EAI_FAIL:
return "EAI_FAIL";
case EAI_MEMORY:
return "EAI_MEMORY";
case EAI_FAMILY:
return "EAI_FAMILY";
case EAI_NODATA:
return "EAI_NODATA";
case EAI_SERVICE:
return "EAI_SERVICE";
case EAI_SOCKTYPE:
return "EAI_SOCKTYPE";
case EAI_SYSTEM:
return "EAI_SYSTEM";
default:
return "UNKNOWN";
}
}
#define FAMILY4 1
#define FAMILY6 2
static struct
{
char verbose;
char family;
int threads;
pthread_mutex_t flock;
} glob;
// get next domain. return 0 if failure
static char interlocked_get_dom(char *dom, size_t size)
{
char *s;
pthread_mutex_lock(&glob.flock);
s = fgets(dom, size, stdin);
pthread_mutex_unlock(&glob.flock);
if (!s) return 0;
trimstr(s);
return 1;
}
static void interlocked_fprintf(FILE *stream, const char * format, ...)
{
va_list args;
va_start(args, format);
pthread_mutex_lock(&glob.flock);
vfprintf(stream, format, args);
pthread_mutex_unlock(&glob.flock);
va_end(args);
}
#define ELOG(format, ...) interlocked_fprintf(stderr, "[%d] " format "\n", tid, ##__VA_ARGS__)
#define VLOG(format, ...) {if (glob.verbose) ELOG(format, ##__VA_ARGS__);}
static void print_addrinfo(struct addrinfo *ai, char family)
{
char str[64];
while (ai)
{
switch (ai->ai_family)
{
case AF_INET:
if (inet_ntop(ai->ai_family, &((struct sockaddr_in*)ai->ai_addr)->sin_addr, str, sizeof(str)))
interlocked_fprintf(stdout, "%s\n", str);
break;
case AF_INET6:
if (inet_ntop(ai->ai_family, &((struct sockaddr_in6*)ai->ai_addr)->sin6_addr, str, sizeof(str)))
interlocked_fprintf(stdout, "%s\n", str);
break;
}
ai = ai->ai_next;
}
}
static void *t_resolver(void *arg)
{
int tid = (int)(size_t)arg;
int i,r;
char dom[256];
struct addrinfo hints;
struct addrinfo *result;
VLOG("started");
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = (glob.family == FAMILY4) ? AF_INET : (glob.family == FAMILY6) ? AF_INET6 : AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;
while (interlocked_get_dom(dom, sizeof(dom)))
{
if (*dom)
{
VLOG("resolving %s", dom);
for (i = 0; i < RESOLVER_EAGAIN_ATTEMPTS; i++)
{
if (r = getaddrinfo(dom, NULL, &hints, &result))
{
ELOG("failed to resolve %s : result %d (%s)", dom, r, eai_str(r));
if (r == EAI_AGAIN) continue; // temporary failure. should retry
}
else
{
print_addrinfo(result, glob.family);
freeaddrinfo(result);
}
break;
}
}
}
VLOG("ended");
return NULL;
}
static int run_threads()
{
int i, thread;
pthread_t *t;
if (pthread_mutex_init(&glob.flock, NULL) != 0)
{
fprintf(stderr, "mutex init failed\n");
return 10;
}
t = (pthread_t*)malloc(sizeof(pthread_t)*glob.threads);
if (!t)
{
fprintf(stderr, "out of memory\n");
pthread_mutex_destroy(&glob.flock);
return 11;
}
for (thread = 0; thread < glob.threads; thread++)
{
if (pthread_create(t + thread, NULL, t_resolver, (void*)(size_t)thread))
{
interlocked_fprintf(stderr, "failed to create thread #%d\n", thread);
break;
}
}
for (i = 0; i < thread; i++)
{
pthread_join(t[i], NULL);
}
free(t);
pthread_mutex_destroy(&glob.flock);
return thread ? 0 : 12;
}
static void exithelp()
{
printf(
" --threads=<threads_number>\n"
" --family=<4|6|46>\t; ipv4, ipv6, ipv4+ipv6\n"
" --verbose\t\t; print query progress to stderr\n"
);
exit(1);
}
int main(int argc, char **argv)
{
int ret, v, option_index = 0;
static const struct option long_options[] = {
{"threads",required_argument,0,0}, // optidx=0
{"family",required_argument,0,0}, // optidx=1
{"verbose",no_argument,0,0}, // optidx=2
{"help",no_argument,0,0}, // optidx=3
{NULL,0,NULL,0}
};
glob.verbose = '\0';
glob.family = FAMILY4;
glob.threads = 1;
while ((v = getopt_long_only(argc, argv, "", long_options, &option_index)) != -1)
{
if (v) exithelp();
switch (option_index)
{
case 0: /* threads */
glob.threads = optarg ? atoi(optarg) : 0;
if (glob.threads <= 0 || glob.threads > 100)
{
fprintf(stderr, "thread number must be within 1..100\n");
return 1;
}
break;
case 1: /* family */
if (!strcmp(optarg, "4"))
glob.family = FAMILY4;
else if (!strcmp(optarg, "6"))
glob.family = FAMILY6;
else if (!strcmp(optarg, "46"))
glob.family = FAMILY4 | FAMILY6;
else
{
fprintf(stderr, "ip family must be 4,6 or 46\n");
return 1;;
}
break;
case 2: /* verbose */
glob.verbose = '\1';
break;
case 3: /* help */
exithelp();
break;
}
}
return run_threads();
}

12
readme.txt

@ -1,4 +1,4 @@
zapret v.20 zapret v.21
Для чего это надо Для чего это надо
----------------- -----------------
@ -194,6 +194,11 @@ tiera : Требуется сплит http запросов в течение в
несколько Мб и продолжает расти. На роутерах openwrt /tmp представляет собой tmpfs , то есть ramdisk. несколько Мб и продолжает расти. На роутерах openwrt /tmp представляет собой tmpfs , то есть ramdisk.
В случае роутера с 32 мб памяти ее не хватит, и будут проблемы. В этом случае используйте В случае роутера с 32 мб памяти ее не хватит, и будут проблемы. В этом случае используйте
следующий скрипт. следующий скрипт.
get_reestr.sh может использовать мультипоточный ресолвер mdig (собственная разработка) или
стандартный однопоточный dig от bind. При наличии скомпилированного mdig или скопированного в zapret/mdig бинарика
используется он, в противном случае dig.
Реестр РКН уже настолько огромен, что однопоточный ресолв займет вечность, а многопоточный хоть и тоже много времени,
но хотя бы оно конечно. В скрипте можно настроить количество потоков.
3) ipset/get_anizapret.sh. быстро и без нагрузки на роутер получает лист с antizapret.prostovpn.org. 3) ipset/get_anizapret.sh. быстро и без нагрузки на роутер получает лист с antizapret.prostovpn.org.
@ -252,6 +257,9 @@ Debian 7 изначально содержит ядро 3.2. Оно не уме
Собрать ip2net : Собрать ip2net :
cd /opt/zapret/ip2net cd /opt/zapret/ip2net
make make
Собрать mdig :
cd /opt/zapret/mdig
make
Скопировать /opt/zapret/init.d/debian7/zapret в /etc/init.d. Скопировать /opt/zapret/init.d/debian7/zapret в /etc/init.d.
В /etc/init.d/zapret выбрать пераметр "ISP". В зависимости от него будут применены нужные правила. В /etc/init.d/zapret выбрать пераметр "ISP". В зависимости от него будут применены нужные правила.
Там же выбрать параметр SLAVE_ETH, соответствующий названию внутреннего сетевого интерфейса. Там же выбрать параметр SLAVE_ETH, соответствующий названию внутреннего сетевого интерфейса.
@ -331,7 +339,7 @@ opkg install iptables-mod-extra iptables-mod-nfqueue iptables-mod-filter iptable
Скорее всего таковой найдется. Если нет - вам придется собирать самостоятельно. Скорее всего таковой найдется. Если нет - вам придется собирать самостоятельно.
Скопировать директорию "zapret" в /opt на роутер. Скопировать директорию "zapret" в /opt на роутер.
Скопировать работающий бинарик nfqws в /opt/zapret/nfq, tpws в /opt/zapret/tpws, ip2net в /opt/zapret/ip2net. Скопировать работающий бинарик nfqws в /opt/zapret/nfq, tpws в /opt/zapret/tpws, ip2net в /opt/zapret/ip2net, mdig в /opt/zapret/mdig.
Скопировать /opt/zapret/init.d/zapret в /etc/init.d. Скопировать /opt/zapret/init.d/zapret в /etc/init.d.
В /etc/init.d/zapret выбрать пераметр "ISP". В зависимости от него будут применены нужные правила. В /etc/init.d/zapret выбрать пераметр "ISP". В зависимости от него будут применены нужные правила.
/etc/init.d/zapret enable /etc/init.d/zapret enable

Loading…
Cancel
Save