Skip to content

Commit

Permalink
Fix some broken TCP connections due to big packets
Browse files Browse the repository at this point in the history
  • Loading branch information
emanuele-f committed Jan 11, 2021
1 parent 94ff148 commit c4af4c8
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 11 deletions.
2 changes: 1 addition & 1 deletion app/src/main/jni/vpnproxy-jni/pcap.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ static uint8_t pcap_buffer[sizeof(struct pcaprec_hdr_s) + SNAPLEN];

static void write_pcap(int fd, const struct sockaddr *srv, size_t srv_size, const void *ptr, size_t len) {
if(sendto(fd, ptr, len, 0, srv, srv_size) < 0)
__android_log_print(ANDROID_LOG_ERROR, PCAP_TAG, "sendto error[%d]: %s", errno, strerror(errno));
__android_log_print(ANDROID_LOG_ERROR, PCAP_TAG, "sendto(%u) error[%d]: %s", len, errno, strerror(errno));
}

/* ******************************************************* */
Expand Down
32 changes: 22 additions & 10 deletions app/src/main/jni/vpnproxy-jni/vpnproxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ static void protectSocketCallback(zdtun_t *tun, socket_t sock) {

/* ******************************************************* */

static char* getApplicationByUid(vpnproxy_data_t *proxy, jint uid, char *buf, size_t bufsize) {
static char* getApplicationByUid(vpnproxy_data_t *proxy, jint uid, char *buf, int bufsize) {
JNIEnv *env = proxy->env;
const char *value = NULL;

Expand Down Expand Up @@ -228,7 +228,7 @@ const char *getL7ProtoName(struct ndpi_detection_module_struct *mod, ndpi_protoc
/* ******************************************************* */

static void process_ndpi_packet(conn_data_t *data, vpnproxy_data_t *proxy, const char *packet,
ssize_t size, uint8_t from_tap) {
int size, uint8_t from_tap) {
bool giveup = ((data->sent_pkts + data->rcvd_pkts) >= MAX_DPI_PACKETS);

data->l7proto = ndpi_detection_process_packet(proxy->ndpi, data->ndpi_flow, (const u_char *)packet,
Expand Down Expand Up @@ -310,7 +310,7 @@ static bool shouldIgnoreApp(vpnproxy_data_t *proxy, int uid) {

/* ******************************************************* */

static void account_packet(zdtun_t *tun, const char *packet, ssize_t size, uint8_t from_tap, const zdtun_conn_t *conn_info) {
static void account_packet(zdtun_t *tun, const char *packet, int size, uint8_t from_tap, const zdtun_conn_t *conn_info) {
struct sockaddr_in servaddr = {0};
conn_data_t *data = zdtun_conn_get_userdata(conn_info);
vpnproxy_data_t *proxy;
Expand Down Expand Up @@ -607,12 +607,21 @@ static void check_tls_mitm(zdtun_t *tun, struct vpnproxy_data *proxy, zdtun_pkt_

/* ******************************************************* */

static int net2tap(zdtun_t *tun, char *pkt_buf, ssize_t pkt_size, const zdtun_conn_t *conn_info) {
static int net2tap(zdtun_t *tun, char *pkt_buf, int pkt_size, const zdtun_conn_t *conn_info) {
vpnproxy_data_t *proxy = (vpnproxy_data_t*) zdtun_userdata(tun);

// TODO return value check
write(proxy->tapfd, pkt_buf, pkt_size);
return 0;
int rv = write(proxy->tapfd, pkt_buf, pkt_size);

if(rv < 0)
log_android(ANDROID_LOG_ERROR,
"tap write (%d) failed [%d]: %s", pkt_size, errno, strerror(errno));
else if(rv != pkt_size)
log_android(ANDROID_LOG_WARN,
"partial tap write (%d / %d)", rv, pkt_size);
else
rv = 0;

return rv;
}

/* ******************************************************* */
Expand Down Expand Up @@ -819,8 +828,6 @@ static int run_tun(JNIEnv *env, jclass vpn, int tapfd, jint sdk) {
/* NOTE: must match ConnDescriptor::setData */
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IIIJJJJIIII)V");

log_android(ANDROID_LOG_ERROR, "CLASS: %u", cls.vpn_service);

vpnproxy_data_t proxy = {
.tapfd = tapfd,
.sdk = sdk,
Expand Down Expand Up @@ -887,6 +894,11 @@ static int run_tun(JNIEnv *env, jclass vpn, int tapfd, jint sdk) {
return(-2);
}

// Limit the segments size for two reasons:
// 1. to be able to encapsulate the packets for the UDP export
// 2. to avoid ENOBUFS while writing to the tapfd (for big packets).
zdtun_set_max_window_size(tun, 32768);

log_android(ANDROID_LOG_DEBUG, "Starting packet loop [tapfd=%d]", tapfd);

notifyServiceStatus(&proxy, "started");
Expand Down Expand Up @@ -915,7 +927,7 @@ static int run_tun(JNIEnv *env, jclass vpn, int tapfd, jint sdk) {
int max_fd;
fd_set fdset;
fd_set wrfds;
ssize_t size;
int size;
struct timeval timeout = {.tv_sec = 0, .tv_usec = 500*1000}; // wake every 500 ms

zdtun_fds(tun, &max_fd, &fdset, &wrfds);
Expand Down

0 comments on commit c4af4c8

Please sign in to comment.