|
|
|
@ -7,18 +7,23 @@ |
|
|
|
#include "android_udp_log.h" |
|
|
|
#include "android_udp_log.h" |
|
|
|
#include "../libutun_lite/instance_lite.h" |
|
|
|
#include "../libutun_lite/instance_lite.h" |
|
|
|
#include "../../../lib/u_async.h" |
|
|
|
#include "../../../lib/u_async.h" |
|
|
|
|
|
|
|
#include "../../../lib/platform_compat.h" |
|
|
|
|
|
|
|
#include "../../../lib/socket_compat.h" |
|
|
|
#include <string.h> |
|
|
|
#include <string.h> |
|
|
|
#include <stdlib.h> |
|
|
|
#include <stdlib.h> |
|
|
|
#include <errno.h> |
|
|
|
#include <errno.h> |
|
|
|
#include <sys/socket.h> |
|
|
|
|
|
|
|
#include <netinet/in.h> |
|
|
|
|
|
|
|
#include <arpa/inet.h> |
|
|
|
|
|
|
|
#include <unistd.h> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define UDP_BUF_SIZE 65536 |
|
|
|
#define UDP_BUF_SIZE 65536 |
|
|
|
#define UDP_FLUSH_BYTES 16384 |
|
|
|
#define UDP_FLUSH_BYTES 16384 |
|
|
|
#define UDP_FLUSH_TB 2000 /* 200ms in uasync timebase (0.1ms units) */ |
|
|
|
#define UDP_FLUSH_TB 2000 /* 200ms in uasync timebase (0.1ms units) */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __ANDROID__ |
|
|
|
|
|
|
|
#include <android/log.h> |
|
|
|
|
|
|
|
#define ULOG(fmt, ...) __android_log_print(ANDROID_LOG_DEBUG, "utun-udplog", fmt, ##__VA_ARGS__) |
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
#define ULOG(fmt, ...) fprintf(stderr, "utun-udplog: " fmt "\n", ##__VA_ARGS__) |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
static int g_udp_fd = -1; |
|
|
|
static int g_udp_fd = -1; |
|
|
|
static struct sockaddr_in g_udp_addr; |
|
|
|
static struct sockaddr_in g_udp_addr; |
|
|
|
static int g_udp_has_addr = 0; |
|
|
|
static int g_udp_has_addr = 0; |
|
|
|
@ -26,6 +31,9 @@ static int g_udp_stopping = 0; |
|
|
|
static char g_udp_buf[UDP_BUF_SIZE]; |
|
|
|
static char g_udp_buf[UDP_BUF_SIZE]; |
|
|
|
static int g_udp_buf_len = 0; |
|
|
|
static int g_udp_buf_len = 0; |
|
|
|
static void* g_udp_timer = NULL; |
|
|
|
static void* g_udp_timer = NULL; |
|
|
|
|
|
|
|
static int g_udp_sent_first = 0; |
|
|
|
|
|
|
|
static int64_t g_udp_total_sent = 0; |
|
|
|
|
|
|
|
static int g_udp_send_errors = 0; |
|
|
|
|
|
|
|
|
|
|
|
static void udp_reschedule_timer(void) { |
|
|
|
static void udp_reschedule_timer(void) { |
|
|
|
if (g_udp_stopping) return; |
|
|
|
if (g_udp_stopping) return; |
|
|
|
@ -35,19 +43,30 @@ static void udp_reschedule_timer(void) { |
|
|
|
|
|
|
|
|
|
|
|
static void udp_open_socket(void) { |
|
|
|
static void udp_open_socket(void) { |
|
|
|
if (g_udp_fd >= 0 || !g_udp_has_addr) return; |
|
|
|
if (g_udp_fd >= 0 || !g_udp_has_addr) return; |
|
|
|
g_udp_fd = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, 0); |
|
|
|
g_udp_fd = (int)socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, 0); |
|
|
|
if (g_udp_fd < 0) return; |
|
|
|
if (g_udp_fd < 0) { ULOG("socket() failed: %s (errno=%d)", strerror(errno), errno); return; } |
|
|
|
if (connect(g_udp_fd, (struct sockaddr*)&g_udp_addr, sizeof(g_udp_addr)) < 0) { |
|
|
|
if (connect(g_udp_fd, (struct sockaddr*)&g_udp_addr, sizeof(g_udp_addr)) < 0) { |
|
|
|
|
|
|
|
ULOG("connect() to %s:%d failed: %s (errno=%d)", |
|
|
|
|
|
|
|
inet_ntoa(g_udp_addr.sin_addr), (int)ntohs(g_udp_addr.sin_port), strerror(errno), errno); |
|
|
|
close(g_udp_fd); g_udp_fd = -1; return; |
|
|
|
close(g_udp_fd); g_udp_fd = -1; return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
ULOG("socket opened fd=%d -> %s:%d", g_udp_fd, |
|
|
|
|
|
|
|
inet_ntoa(g_udp_addr.sin_addr), (int)ntohs(g_udp_addr.sin_port)); |
|
|
|
udp_reschedule_timer(); |
|
|
|
udp_reschedule_timer(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void udp_do_send(const char* data, int len) { |
|
|
|
static void udp_do_send(const char* data, int len) { |
|
|
|
if (g_udp_fd < 0) { udp_open_socket(); if (g_udp_fd < 0) return; } |
|
|
|
if (g_udp_fd < 0) { udp_open_socket(); if (g_udp_fd < 0) return; } |
|
|
|
ssize_t sent = send(g_udp_fd, data, len, MSG_DONTWAIT); |
|
|
|
ssize_t sent = send(g_udp_fd, data, len, MSG_DONTWAIT); |
|
|
|
(void)sent; |
|
|
|
if (sent >= 0) { |
|
|
|
if (sent < 0 && (errno == ECONNREFUSED || errno == ENETUNREACH || errno == EHOSTUNREACH)) { |
|
|
|
g_udp_total_sent += sent; |
|
|
|
|
|
|
|
if (!g_udp_sent_first) { ULOG("first send OK: %zd bytes, total=%lld", sent, (long long)g_udp_total_sent); g_udp_sent_first = 1; } |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
g_udp_send_errors++; |
|
|
|
|
|
|
|
if (g_udp_send_errors <= 3 || g_udp_send_errors % 100 == 0) |
|
|
|
|
|
|
|
ULOG("send() error #%d: %s (errno=%d)", g_udp_send_errors, strerror(errno), errno); |
|
|
|
|
|
|
|
if (errno == ECONNREFUSED || errno == ENETUNREACH || errno == EHOSTUNREACH) { |
|
|
|
close(g_udp_fd); |
|
|
|
close(g_udp_fd); |
|
|
|
g_udp_fd = -1; |
|
|
|
g_udp_fd = -1; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -66,13 +85,19 @@ void udp_trampoline(void* arg) { |
|
|
|
void udp_log_set_target(const char* ip, int port) { |
|
|
|
void udp_log_set_target(const char* ip, int port) { |
|
|
|
g_udp_buf_len = 0; |
|
|
|
g_udp_buf_len = 0; |
|
|
|
g_udp_stopping = 0; |
|
|
|
g_udp_stopping = 0; |
|
|
|
|
|
|
|
g_udp_sent_first = 0; |
|
|
|
|
|
|
|
g_udp_total_sent = 0; |
|
|
|
|
|
|
|
g_udp_send_errors = 0; |
|
|
|
|
|
|
|
if (g_udp_fd >= 0) { close(g_udp_fd); g_udp_fd = -1; } |
|
|
|
if (ip && port > 0) { |
|
|
|
if (ip && port > 0) { |
|
|
|
memset(&g_udp_addr, 0, sizeof(g_udp_addr)); |
|
|
|
memset(&g_udp_addr, 0, sizeof(g_udp_addr)); |
|
|
|
g_udp_addr.sin_family = AF_INET; |
|
|
|
g_udp_addr.sin_family = AF_INET; |
|
|
|
g_udp_addr.sin_port = htons((unsigned short)port); |
|
|
|
g_udp_addr.sin_port = htons((unsigned short)port); |
|
|
|
g_udp_has_addr = (inet_pton(AF_INET, ip, &g_udp_addr.sin_addr) == 1); |
|
|
|
g_udp_has_addr = (inet_pton(AF_INET, ip, &g_udp_addr.sin_addr) == 1); |
|
|
|
|
|
|
|
ULOG("set target %s:%d -> has_addr=%d", ip, port, g_udp_has_addr); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
g_udp_has_addr = 0; |
|
|
|
g_udp_has_addr = 0; |
|
|
|
|
|
|
|
ULOG("set target disabled (ip=%s port=%d)", ip ? ip : "null", port); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -103,6 +128,7 @@ void udp_log_cancel_timer(void) { |
|
|
|
void udp_log_stop(void) { |
|
|
|
void udp_log_stop(void) { |
|
|
|
g_udp_stopping = 1; |
|
|
|
g_udp_stopping = 1; |
|
|
|
if (g_udp_buf_len > 0) { udp_do_send(g_udp_buf, g_udp_buf_len); g_udp_buf_len = 0; } |
|
|
|
if (g_udp_buf_len > 0) { udp_do_send(g_udp_buf, g_udp_buf_len); g_udp_buf_len = 0; } |
|
|
|
|
|
|
|
ULOG("stop: total_sent=%lld bytes, errors=%d", (long long)g_udp_total_sent, g_udp_send_errors); |
|
|
|
if (g_udp_fd >= 0) { close(g_udp_fd); g_udp_fd = -1; } |
|
|
|
if (g_udp_fd >= 0) { close(g_udp_fd); g_udp_fd = -1; } |
|
|
|
g_udp_has_addr = 0; |
|
|
|
g_udp_has_addr = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|