Native log downstream UDP, refactoring, cleanup

This commit is contained in:
M66B 2016-01-20 16:52:38 +01:00
parent af917422c9
commit ac30913034
5 changed files with 96 additions and 74 deletions

View File

@ -25,7 +25,7 @@
#JNI callback
-keep class eu.faircode.netguard.SinkholeService {
void logPacket(int, java.lang.String, int, java.lang.String, int, int, java.lang.String, int, boolean);
void logPacket(long, int, java.lang.String, int, int, java.lang.String, int, boolean);
}
#Support library

View File

@ -92,13 +92,21 @@ public class DatabaseHelper extends SQLiteOpenHelper {
// Location
public DatabaseHelper insertLog(
int version, String ip, int protocol, int port, String flags,
int uid, int connection, boolean interactive, boolean allowed) {
long time,
int version,
String ip,
int protocol,
int port,
String flags,
int uid,
int connection,
boolean interactive,
boolean allowed) {
synchronized (mContext.getApplicationContext()) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put("time", new Date().getTime());
cv.put("time", time);
cv.put("version", version);
cv.put("ip", ip);

View File

@ -773,12 +773,16 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS
// Called from native code
private void logPacket(
long time,
int version,
String saddr, int sport,
String daddr, int dport,
int protocol, String flags,
int uid, boolean allowed) {
String daddr,
int protocol,
int dport,
String flags,
int uid,
boolean allowed) {
new DatabaseHelper(SinkholeService.this).insertLog(
time,
version,
daddr,
protocol,

View File

@ -392,7 +392,7 @@ int get_selects(const struct arguments *args, fd_set *rfds, fd_set *wfds, fd_set
log_android(ANDROID_LOG_WARN, "Idle %s/%u lport %u", dest, ntohs(t->dest), t->lport);
write_rst(t, args->tun);
write_rst(args, t, args->tun);
}
if (t->state == TCP_TIME_WAIT) {
@ -517,7 +517,7 @@ void check_udp_sockets(const struct arguments *args, fd_set *rfds, fd_set *wfds,
inet_ntop(AF_INET, &(cur->daddr), dest, sizeof(dest));
log_android(ANDROID_LOG_INFO, "UDP recv bytes %d for %s/%u @tun",
bytes, dest, ntohs(cur->dest));
write_udp(cur, buffer, bytes, args->tun);
write_udp(args, cur, buffer, bytes, args->tun);
}
}
}
@ -547,7 +547,7 @@ void check_tcp_sockets(const struct arguments *args, fd_set *rfds, fd_set *wfds,
log_android(ANDROID_LOG_ERROR, "lport %u SO_ERROR %d: %s",
cur->lport, serr, strerror(serr));
write_rst(cur, args->tun);
write_rst(args, cur, args->tun);
}
else {
// Assume socket okay
@ -562,7 +562,7 @@ void check_tcp_sockets(const struct arguments *args, fd_set *rfds, fd_set *wfds,
log_android(ANDROID_LOG_INFO, "Connected %s/%u lport %u",
dest, ntohs(cur->dest), cur->lport);
if (write_syn_ack(cur, args->tun) >= 0) {
if (write_syn_ack(args, cur, args->tun) >= 0) {
cur->local_seq++; // local SYN
cur->remote_seq++; // remote SYN
cur->state = TCP_SYN_RECV;
@ -586,7 +586,7 @@ void check_tcp_sockets(const struct arguments *args, fd_set *rfds, fd_set *wfds,
cur->lport, errno, strerror(errno));
if (errno != EINTR)
write_rst(cur, args->tun);
write_rst(args, cur, args->tun);
}
else if (bytes == 0) {
// Socket eof
@ -594,7 +594,7 @@ void check_tcp_sockets(const struct arguments *args, fd_set *rfds, fd_set *wfds,
log_android(ANDROID_LOG_DEBUG, "recv empty lport %u state %s",
cur->lport, strstate(cur->state));
if (write_fin(cur, args->tun) >= 0) {
if (write_fin(args, cur, args->tun) >= 0) {
cur->local_seq++; // local FIN
if (cur->state == TCP_SYN_RECV || cur->state == TCP_ESTABLISHED)
@ -615,7 +615,7 @@ void check_tcp_sockets(const struct arguments *args, fd_set *rfds, fd_set *wfds,
cur->lport, bytes, strstate(cur->state));
// Forward to tun
if (write_data(cur, buffer, bytes, args->tun) >= 0)
if (write_data(args, cur, buffer, bytes, args->tun) >= 0)
cur->local_seq += bytes;
}
}
@ -803,7 +803,7 @@ void handle_ip(const struct arguments *args, const uint8_t *buffer, const uint16
// Log traffic
if (args->log) {
if (!args->filter || syn || protocol != IPPROTO_TCP)
log_java(args, version, source, sport, dest, dport, protocol, flags, uid, allowed);
log_packet(args, time(NULL), version, dest, protocol, dport, flags, uid, allowed);
}
}
@ -840,6 +840,7 @@ jboolean handle_udp(const struct arguments *args, const uint8_t *buffer, uint16_
struct udp_session *u = malloc(sizeof(struct udp_session));
u->time = time(NULL);
u->uid = uid;
u->version = 4;
u->saddr = iphdr->saddr;
u->source = udphdr->source;
u->daddr = iphdr->daddr;
@ -855,15 +856,6 @@ jboolean handle_udp(const struct arguments *args, const uint8_t *buffer, uint16_
else {
protect_socket(args, u->socket);
//struct sockaddr_in uaddr;
//uaddr.sin_family = AF_INET;
//uaddr.sin_addr.s_addr = INADDR_ANY;
//uaddr.sin_port = 0;
//if (bind(usock, (struct sockaddr *) &uaddr, sizeof(struct sockaddr)) < 0) {
// log_android(ANDROID_LOG_ERROR, "UDP bind error %d: %s", errno, strerror(errno));
// return 0;
//}
if (last == NULL)
udp_session = u;
else
@ -951,6 +943,7 @@ jboolean handle_tcp(const struct arguments *args, const uint8_t *buffer, uint16_
struct tcp_session *syn = malloc(sizeof(struct tcp_session));
syn->time = time(NULL);
syn->uid = uid;
syn->version = 4;
syn->remote_seq = ntohl(tcphdr->seq); // ISN remote
syn->local_seq = rand(); // ISN local
syn->remote_start = syn->remote_seq;
@ -989,12 +982,13 @@ jboolean handle_tcp(const struct arguments *args, const uint8_t *buffer, uint16_
struct tcp_session rst;
memset(&rst, 0, sizeof(struct tcp_session));
rst.version = 4;
rst.remote_seq = ntohl(tcphdr->seq);
rst.saddr = iphdr->saddr;
rst.source = tcphdr->source;
rst.daddr = iphdr->daddr;
rst.dest = tcphdr->dest;
write_rst(&rst, args->tun);
write_rst(args, &rst, args->tun);
return 0;
}
@ -1039,7 +1033,7 @@ jboolean handle_tcp(const struct arguments *args, const uint8_t *buffer, uint16_
ntohl(tcphdr->seq) == cur->remote_seq) {
if (datalen)
log_android(ANDROID_LOG_WARN, "FIN session %s/%u lport %u data %u",
log_android(ANDROID_LOG_INFO, "FIN session %s/%u lport %u data %u",
dest, ntohs(cur->dest), cur->lport, datalen);
// Forward last data to socket
@ -1060,7 +1054,7 @@ jboolean handle_tcp(const struct arguments *args, const uint8_t *buffer, uint16_
}
if (ok) {
if (write_ack(cur, 1 + datalen, args->tun) >= 0) {
if (write_ack(args, cur, 1 + datalen, args->tun) >= 0) {
cur->remote_seq += (1 + datalen); // FIN + data from tun
if (cur->state == TCP_ESTABLISHED /* && !tcphdr->ack */)
cur->state = TCP_CLOSE_WAIT;
@ -1077,7 +1071,7 @@ jboolean handle_tcp(const struct arguments *args, const uint8_t *buffer, uint16_
strstate(cur->state), tcphdr->ack);
}
} else
write_rst(cur, args->tun);
write_rst(args, cur, args->tun);
}
else {
// Special case or hack if you like
@ -1090,7 +1084,7 @@ jboolean handle_tcp(const struct arguments *args, const uint8_t *buffer, uint16_
log_android(ANDROID_LOG_INFO,
"Simultaneous close %s/%u lport %u confirm %d",
dest, ntohs(cur->dest), cur->lport, confirm);
write_ack(cur, confirm, args->tun);
write_ack(args, cur, confirm, args->tun);
}
else
log_android(ANDROID_LOG_WARN,
@ -1124,9 +1118,9 @@ jboolean handle_tcp(const struct arguments *args, const uint8_t *buffer, uint16_
if (datalen) {
log_android(ANDROID_LOG_DEBUG, "send socket data %u", datalen);
if (send_socket(cur->socket, buffer + dataoff, datalen) < 0)
write_rst(cur, args->tun);
write_rst(args, cur, args->tun);
else {
if (write_ack(cur, datalen, args->tun) >= 0)
if (write_ack(args, cur, datalen, args->tun) >= 0)
cur->remote_seq += datalen;
}
}
@ -1161,9 +1155,9 @@ jboolean handle_tcp(const struct arguments *args, const uint8_t *buffer, uint16_
if (datalen) {
log_android(ANDROID_LOG_DEBUG, "send socket data %u", datalen);
if (send_socket(cur->socket, buffer + dataoff, datalen) < 0)
write_rst(cur, args->tun);
write_rst(args, cur, args->tun);
else {
if (write_ack(cur, datalen, args->tun) >= 0)
if (write_ack(args, cur, datalen, args->tun) >= 0)
cur->remote_seq += datalen;
}
}
@ -1270,8 +1264,8 @@ ssize_t send_socket(int sock, uint8_t *buffer, uint16_t len) {
return res;
}
int write_syn_ack(struct tcp_session *cur, int tun) {
if (write_tcp(cur, NULL, 0, 1, 1, 1, 0, 0, tun) < 0) {
int write_syn_ack(const struct arguments *args, struct tcp_session *cur, int tun) {
if (write_tcp(args, cur, NULL, 0, 1, 1, 1, 0, 0, tun) < 0) {
log_android(ANDROID_LOG_ERROR, "write SYN+ACK error %d: %s",
errno, strerror((errno)));
cur->state = TCP_TIME_WAIT;
@ -1280,8 +1274,8 @@ int write_syn_ack(struct tcp_session *cur, int tun) {
return 0;
}
int write_ack(struct tcp_session *cur, int bytes, int tun) {
if (write_tcp(cur, NULL, 0, bytes, 0, 1, 0, 0, tun) < 0) {
int write_ack(const struct arguments *args, struct tcp_session *cur, int bytes, int tun) {
if (write_tcp(args, cur, NULL, 0, bytes, 0, 1, 0, 0, tun) < 0) {
log_android(ANDROID_LOG_ERROR, "write ACK error %d: %s",
errno, strerror((errno)));
cur->state = TCP_TIME_WAIT;
@ -1290,8 +1284,9 @@ int write_ack(struct tcp_session *cur, int bytes, int tun) {
return 0;
}
int write_data(struct tcp_session *cur, const uint8_t *buffer, uint16_t length, int tun) {
if (write_tcp(cur, buffer, length, 0, 0, 1, 0, 0, tun) < 0) {
int write_data(const struct arguments *args, struct tcp_session *cur, const uint8_t *buffer,
uint16_t length, int tun) {
if (write_tcp(args, cur, buffer, length, 0, 0, 1, 0, 0, tun) < 0) {
log_android(ANDROID_LOG_ERROR, "write data ACK lport %u error %d: %s",
cur->lport, errno, strerror((errno)));
cur->state = TCP_TIME_WAIT;
@ -1299,8 +1294,8 @@ int write_data(struct tcp_session *cur, const uint8_t *buffer, uint16_t length,
}
int write_fin(struct tcp_session *cur, int tun) {
if (write_tcp(cur, NULL, 0, 0, 0, 0, 1, 0, tun) < 0) {
int write_fin(const struct arguments *args, struct tcp_session *cur, int tun) {
if (write_tcp(args, cur, NULL, 0, 0, 0, 0, 1, 0, tun) < 0) {
log_android(ANDROID_LOG_ERROR,
"write FIN lport %u error %d: %s",
cur->lport, errno, strerror((errno)));
@ -1310,15 +1305,16 @@ int write_fin(struct tcp_session *cur, int tun) {
return 0;
}
void write_rst(struct tcp_session *cur, int tun) {
void write_rst(const struct arguments *args, struct tcp_session *cur, int tun) {
log_android(ANDROID_LOG_WARN, "Sending RST");
if (write_tcp(cur, NULL, 0, 0, 0, 0, 0, 1, tun) < 0)
if (write_tcp(args, cur, NULL, 0, 0, 0, 0, 0, 1, tun) < 0)
log_android(ANDROID_LOG_ERROR, "write RST error %d: %s",
errno, strerror((errno)));
cur->state = TCP_TIME_WAIT;
}
int write_udp(const struct udp_session *cur, uint8_t *data, uint16_t datalen, int tun) {
int write_udp(const struct arguments *args, const struct udp_session *cur,
uint8_t *data, uint16_t datalen, int tun) {
#ifdef PROFILE
float mselapsed;
struct timeval start, end;
@ -1370,6 +1366,8 @@ int write_udp(const struct udp_session *cur, uint8_t *data, uint16_t datalen, in
log_android(ANDROID_LOG_INFO, "tun UDP write %f", mselapsed);
#endif
log_packet(args, time(NULL), cur->version, to, ip->protocol, ntohs(udp->dest), "", cur->uid, 1);
// Write pcap record
if (pcap_fn != NULL)
write_pcap_rec(buffer, len);
@ -1380,7 +1378,7 @@ int write_udp(const struct udp_session *cur, uint8_t *data, uint16_t datalen, in
}
int write_tcp(const struct tcp_session *cur,
int write_tcp(const struct arguments *args, const struct tcp_session *cur,
uint8_t *data, uint16_t datalen, uint16_t confirm,
int syn, int ack, int fin, int rst, int tun) {
#ifdef PROFILE
@ -1645,12 +1643,16 @@ void log_android(int prio, const char *fmt, ...) {
}
}
void log_java(
const struct arguments *args, jint version,
const char *source, jint sport,
const char *dest, jint dport,
jint protocol, const char *flags,
jint uid, jboolean allowed) {
void log_packet(
const struct arguments *args,
jlong time,
jint version,
const char *dest,
jint protocol,
jint dport,
const char *flags,
jint uid,
jboolean allowed) {
#ifdef PROFILE
float mselapsed;
struct timeval start, end;
@ -1660,22 +1662,22 @@ void log_java(
JNIEnv *env = args->env;
jobject instance = args->instance;
jclass cls = (*env)->GetObjectClass(env, instance);
jmethodID mid = (*env)->GetMethodID(
env, cls, "logPacket",
"(ILjava/lang/String;ILjava/lang/String;IILjava/lang/String;IZ)V");
char *signature = "(JILjava/lang/String;IILjava/lang/String;IZ)V";
jmethodID mid = (*env)->GetMethodID(env, cls, "logPacket", signature);
if (mid == 0)
log_android(ANDROID_LOG_ERROR, "logPacket not found");
log_android(ANDROID_LOG_ERROR, "Method logPacket%s not found", signature);
else {
jstring jsource = (*env)->NewStringUTF(env, source);
jstring jdest = (*env)->NewStringUTF(env, dest);
jstring jflags = (*env)->NewStringUTF(env, flags);
(*env)->CallVoidMethod(env, instance, mid,
time,
version,
jsource, sport,
jdest, dport,
protocol, jflags,
uid, allowed);
(*env)->DeleteLocalRef(env, jsource);
jdest,
protocol,
dport,
jflags,
uid,
allowed);
(*env)->DeleteLocalRef(env, jdest);
(*env)->DeleteLocalRef(env, jflags);

View File

@ -30,6 +30,7 @@ struct udp_session {
// TODO UDPv6
time_t time;
jint uid;
int version;
int32_t saddr; // network notation
__be16 source; // network notation
int32_t daddr; // network notation
@ -42,6 +43,7 @@ struct tcp_session {
// TODO TCPv6
time_t time;
jint uid;
int version;
uint32_t remote_seq; // confirmed bytes received, host notation
uint32_t local_seq; // confirmed bytes sent, host notation
uint32_t remote_start;
@ -108,19 +110,21 @@ int get_local_port(const int sock);
ssize_t send_socket(int sock, uint8_t *buffer, uint16_t len);
int write_syn_ack(struct tcp_session *cur, int tun);
int write_syn_ack(const struct arguments *args, struct tcp_session *cur, int tun);
int write_ack(struct tcp_session *cur, int bytes, int tun);
int write_ack(const struct arguments *args, struct tcp_session *cur, int bytes, int tun);
int write_data(struct tcp_session *cur, const uint8_t *buffer, uint16_t length, int tun);
int write_data(const struct arguments *args, struct tcp_session *cur,
const uint8_t *buffer, uint16_t length, int tun);
int write_fin(struct tcp_session *cur, int tun);
int write_fin(const struct arguments *args, struct tcp_session *cur, int tun);
void write_rst(struct tcp_session *cur, int tun);
void write_rst(const struct arguments *args, struct tcp_session *cur, int tun);
int write_udp(const struct udp_session *cur, uint8_t *data, uint16_t datalen, int tun);
int write_udp(const struct arguments *args, const struct udp_session *cur,
uint8_t *data, uint16_t datalen, int tun);
int write_tcp(const struct tcp_session *cur,
int write_tcp(const struct arguments *args, const struct tcp_session *cur,
uint8_t *data, uint16_t datalen, uint16_t confirm,
int syn, int ack, int fin, int rst, int tun);
@ -131,11 +135,15 @@ uint16_t calc_checksum(uint8_t *buffer, uint16_t length);
void log_android(int prio, const char *fmt, ...);
void log_java(const struct arguments *args, jint version,
const char *source, jint sport,
const char *dest, jint dport,
jint protocol, const char *flags,
jint uid, jboolean allowed);
void log_packet(const struct arguments *args,
jlong time,
jint version,
const char *dest,
jint protocol,
jint dport,
const char *flags,
jint uid,
jboolean allowed);
void write_pcap(const void *ptr, size_t len);