Fix mono-directional connections with LINUX_SLL

This commit is contained in:
emanuele-f 2021-05-24 23:28:07 +02:00
parent a1eceefc6a
commit 3596ba67a8
4 changed files with 61 additions and 49 deletions

View File

@ -101,6 +101,18 @@ ssize_t xread(int fd, void *buf, size_t count) {
/* ******************************************************* */
void tupleSwapPeers(zdtun_5tuple_t *tuple) {
uint16_t tmp = tuple->dst_port;
tuple->dst_port = tuple->src_port;
tuple->src_port = tmp;
zdtun_ip_t tmp1 = tuple->dst_ip;
tuple->dst_ip = tuple->src_ip;
tuple->src_ip = tmp1;
}
/* ******************************************************* */
int jniCheckException(JNIEnv *env) {
jthrowable ex = (*env)->ExceptionOccurred(env);
if (ex) {

View File

@ -23,6 +23,7 @@
#include <jni.h>
#include <sys/types.h>
#include <android/log.h>
#include "zdtun.h"
extern int loglevel;
extern const char* logtag;
@ -37,6 +38,7 @@ extern void (*logcallback)(int lvl, const char *msg);
void log_android(int prio, const char *fmt, ...);
ssize_t xwrite(int fd, const void *buf, size_t count);
ssize_t xread(int fd, void *buf, size_t count);
void tupleSwapPeers(zdtun_5tuple_t *tuple);
jclass jniFindClass(JNIEnv *env, const char *name);
jmethodID jniGetMethodID(JNIEnv *env, jclass cls, const char *name, const char *signature);

View File

@ -410,7 +410,7 @@ static int is_tx_packet(pcapd_runtime_t *rt, const u_char *pkt, u_int16_t len) {
pkt += 14;
} else if((rt->dlink == DLT_LINUX_SLL) && (len >= SLL_HDR_LEN)) {
struct sll_header *sll = (struct sll_header*) pkt;
uint8_t pkttype = sll->sll_pkttype;
uint16_t pkttype = ntohs(sll->sll_pkttype);
if(pkttype == LINUX_SLL_HOST)
return 0; // RX
@ -511,13 +511,7 @@ static int run_pcap_dump(int uid_filter) {
if(zdtun_parse_pkt((const char*)pkt, hdr->caplen, &zpkt) == 0) {
if(!is_tx) {
// Packet from the internet, swap src and dst
uint16_t tmp = zpkt.tuple.dst_port;
zpkt.tuple.dst_port = zpkt.tuple.src_port;
zpkt.tuple.src_port = tmp;
zdtun_ip_t tmp1 = zpkt.tuple.dst_ip;
zpkt.tuple.dst_ip = zpkt.tuple.src_ip;
zpkt.tuple.src_ip = tmp1;
tupleSwapPeers(&zpkt.tuple);
}
int uid = uid_lru_find(lru, &zpkt.tuple);

View File

@ -187,10 +187,9 @@ static int connectPcapd(vpnproxy_data_t *proxy) {
/* ******************************************************* */
static void handle_packet(vpnproxy_data_t *proxy, pcap_conn_t **connections, pcapd_hdr_t *hdr, const char *buffer) {
zdtun_5tuple_t search;
zdtun_pkt_t pkt;
pcap_conn_t *conn = NULL;
uint8_t from_tun = (hdr->flags & PCAPD_FLAG_TX);
uint8_t from_tun = (hdr->flags & PCAPD_FLAG_TX); // NOTE: the direction uses an heuristic so it may be wrong
// NOTE: only IP packets supported
if(zdtun_parse_pkt(buffer, hdr->len, &pkt) != 0) {
@ -200,56 +199,61 @@ static void handle_packet(vpnproxy_data_t *proxy, pcap_conn_t **connections, pca
if(!from_tun) {
// Packet from the internet, swap src and dst
search.ipver = pkt.tuple.ipver;
search.ipproto = pkt.tuple.ipproto;
tupleSwapPeers(&pkt.tuple);
}
search.dst_port = pkt.tuple.src_port;
search.src_port = pkt.tuple.dst_port;
search.dst_ip = pkt.tuple.src_ip;
search.src_ip = pkt.tuple.dst_ip;
} else
search = pkt.tuple;
HASH_FIND(hh, *connections, &search, sizeof(zdtun_5tuple_t), conn);
HASH_FIND(hh, *connections, &pkt.tuple, sizeof(zdtun_5tuple_t), conn);
if(!conn) {
conn_data_t *data = new_connection(proxy, &search, hdr->uid);
// from_tun may be wrong, search in the other direction
from_tun = !from_tun;
tupleSwapPeers(&pkt.tuple);
if (!data)
return;
HASH_FIND(hh, *connections, &pkt.tuple, sizeof(zdtun_5tuple_t), conn);
conn = malloc(sizeof(pcap_conn_t));
if(!conn) {
// assume from_tun was correct
from_tun = !from_tun;
tupleSwapPeers(&pkt.tuple);
if (!conn) {
log_e("malloc(pcap_conn_t) failed with code %d/%s",
errno, strerror(errno));
return;
}
conn_data_t *data = new_connection(proxy, &pkt.tuple, hdr->uid);
conn->tuple = search;
conn->data = data;
if (!data)
return;
// TODO read from linux?
data->status = CONN_STATUS_CONNECTED;
conn = malloc(sizeof(pcap_conn_t));
HASH_ADD(hh, *connections, tuple, sizeof(search), conn);
if (!conn) {
log_e("malloc(pcap_conn_t) failed with code %d/%s",
errno, strerror(errno));
return;
}
data->incr_id = proxy->incr_id++;
conns_add(&proxy->new_conns, &search, data);
conn->tuple = pkt.tuple;
conn->data = data;
switch(conn->tuple.ipproto) {
case IPPROTO_TCP:
proxy->stats.num_tcp_conn++;
proxy->stats.num_tcp_opened++;
break;
case IPPROTO_UDP:
proxy->stats.num_udp_conn++;
proxy->stats.num_udp_opened++;
break;
case IPPROTO_ICMP:
proxy->stats.num_icmp_conn++;
proxy->stats.num_icmp_opened++;
break;
// TODO read from linux?
data->status = CONN_STATUS_CONNECTED;
HASH_ADD(hh, *connections, tuple, sizeof(zdtun_5tuple_t), conn);
data->incr_id = proxy->incr_id++;
conns_add(&proxy->new_conns, &pkt.tuple, data);
switch (conn->tuple.ipproto) {
case IPPROTO_TCP:
proxy->stats.num_tcp_conn++;
proxy->stats.num_tcp_opened++;
break;
case IPPROTO_UDP:
proxy->stats.num_udp_conn++;
proxy->stats.num_udp_opened++;
break;
case IPPROTO_ICMP:
proxy->stats.num_icmp_conn++;
proxy->stats.num_icmp_opened++;
break;
}
}
}