mirror of https://github.com/M66B/NetGuard.git
Native socket eof/error handling
This commit is contained in:
parent
e525ec7050
commit
49b15e261d
|
@ -98,8 +98,6 @@ int openSocket(JNIEnv *, jobject, const struct sockaddr_in *);
|
||||||
|
|
||||||
int getLocalPort(const int);
|
int getLocalPort(const int);
|
||||||
|
|
||||||
int canWrite(const int);
|
|
||||||
|
|
||||||
int writeTCP(const struct session *, uint8_t *, uint16_t, uint16_t, int, int, int, int);
|
int writeTCP(const struct session *, uint8_t *, uint16_t, uint16_t, int, int, int, int);
|
||||||
|
|
||||||
jint getUid(const int, const int, const void *, const uint16_t);
|
jint getUid(const int, const int, const void *, const uint16_t);
|
||||||
|
@ -298,7 +296,6 @@ void *handle_events(void *a) {
|
||||||
if (cur->state == TCP_SYN_RECV ||
|
if (cur->state == TCP_SYN_RECV ||
|
||||||
cur->state == TCP_ESTABLISHED ||
|
cur->state == TCP_ESTABLISHED ||
|
||||||
cur->state == TCP_CLOSE_WAIT) {
|
cur->state == TCP_CLOSE_WAIT) {
|
||||||
// TODO can write
|
|
||||||
if (writeTCP(cur, NULL, 0, 0, 0, 1, 0, args->tun) < 0) { // FIN
|
if (writeTCP(cur, NULL, 0, 0, 0, 1, 0, args->tun) < 0) { // FIN
|
||||||
ng_log(ANDROID_LOG_ERROR,
|
ng_log(ANDROID_LOG_ERROR,
|
||||||
"write FIN lport %u error %d: %s",
|
"write FIN lport %u error %d: %s",
|
||||||
|
@ -343,6 +340,7 @@ void *handle_events(void *a) {
|
||||||
|
|
||||||
} else if (cur->state != TCP_TIME_WAIT) {
|
} else if (cur->state != TCP_TIME_WAIT) {
|
||||||
if (cur->state == TCP_LISTEN) {
|
if (cur->state == TCP_LISTEN) {
|
||||||
|
FD_SET(cur->socket, &efds);
|
||||||
FD_SET(cur->socket, &wfds);
|
FD_SET(cur->socket, &wfds);
|
||||||
if (cur->socket > max)
|
if (cur->socket > max)
|
||||||
max = cur->socket;
|
max = cur->socket;
|
||||||
|
@ -350,6 +348,7 @@ void *handle_events(void *a) {
|
||||||
else if (cur->state == TCP_ESTABLISHED ||
|
else if (cur->state == TCP_ESTABLISHED ||
|
||||||
cur->state == TCP_SYN_RECV ||
|
cur->state == TCP_SYN_RECV ||
|
||||||
cur->state == TCP_CLOSE_WAIT) {
|
cur->state == TCP_CLOSE_WAIT) {
|
||||||
|
FD_SET(cur->socket, &efds);
|
||||||
FD_SET(cur->socket, &rfds);
|
FD_SET(cur->socket, &rfds);
|
||||||
if (cur->socket > max)
|
if (cur->socket > max)
|
||||||
max = cur->socket;
|
max = cur->socket;
|
||||||
|
@ -447,105 +446,104 @@ void *handle_events(void *a) {
|
||||||
// Check sockets
|
// Check sockets
|
||||||
struct session *cur = session;
|
struct session *cur = session;
|
||||||
while (cur != NULL) {
|
while (cur != NULL) {
|
||||||
// Check socket exception
|
|
||||||
if (FD_ISSET(cur->socket, &efds)) {
|
if (FD_ISSET(cur->socket, &efds)) {
|
||||||
|
// Socket exception
|
||||||
int serr;
|
int serr;
|
||||||
socklen_t optlen = sizeof(serr);
|
socklen_t optlen = sizeof(int);
|
||||||
if (getsockopt(cur->socket, SOL_SOCKET, SO_ERROR, &serr, &optlen) < 0) {
|
int err = getsockopt(cur->socket, SOL_SOCKET, SO_ERROR, &serr, &optlen);
|
||||||
|
if (err < 0)
|
||||||
ng_log(ANDROID_LOG_ERROR,
|
ng_log(ANDROID_LOG_ERROR,
|
||||||
"getsockopt lport %u error %d: %s",
|
"getsockopt lport %u error %d: %s",
|
||||||
cur->lport, errno, strerror(errno));
|
cur->lport, errno, strerror(errno));
|
||||||
// TODO initiate finish
|
if (err < 0 || serr) {
|
||||||
cur->state = TCP_TIME_WAIT; // will close socket
|
|
||||||
cur = cur->next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (serr) {
|
|
||||||
ng_log(ANDROID_LOG_ERROR, "lport %u SO_ERROR %d: %s",
|
ng_log(ANDROID_LOG_ERROR, "lport %u SO_ERROR %d: %s",
|
||||||
cur->lport, serr, strerror(serr));
|
cur->lport, serr, strerror(serr));
|
||||||
// TODO initiate FIN
|
if (err < 0 || (serr && serr != EINTR)) {
|
||||||
if (serr != EINTR)
|
if (writeTCP(cur, NULL, 0, 0, 0, 0, 1, args->tun) < 0) // RST
|
||||||
cur->state = TCP_TIME_WAIT; // will close socket
|
ng_log(ANDROID_LOG_ERROR,
|
||||||
cur = cur->next;
|
"write RST error %d: %s",
|
||||||
continue;
|
errno, strerror((errno)));
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cur->state == TCP_LISTEN) {
|
|
||||||
// Check socket connect
|
|
||||||
if (FD_ISSET(cur->socket, &wfds) && canWrite(args->tun)) {
|
|
||||||
// Log
|
|
||||||
char dest[20];
|
|
||||||
inet_ntop(AF_INET, &(cur->daddr), dest, sizeof(dest));
|
|
||||||
ng_log(ANDROID_LOG_DEBUG, "Connected lport %u %s/%u",
|
|
||||||
cur->lport, dest, ntohs(cur->dest));
|
|
||||||
|
|
||||||
// TODO can write
|
|
||||||
if (writeTCP(cur, NULL, 0, 1, 1, 0, 0, args->tun) < 0) { // SYN+ACK
|
|
||||||
ng_log(ANDROID_LOG_ERROR,
|
|
||||||
"write SYN+ACK error %d: %s",
|
|
||||||
errno, strerror((errno)));
|
|
||||||
// Remote will retry
|
|
||||||
cur->state = TCP_TIME_WAIT; // will close socket
|
|
||||||
cur = cur->next;
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
cur->local_seq++; // local SYN
|
|
||||||
cur->remote_seq++; // remote SYN
|
|
||||||
cur->state = TCP_SYN_RECV;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// Assume socket okay
|
||||||
|
if (cur->state == TCP_LISTEN) {
|
||||||
|
// Check socket connect
|
||||||
|
if (FD_ISSET(cur->socket, &wfds)) {
|
||||||
|
// Log
|
||||||
|
char dest[20];
|
||||||
|
inet_ntop(AF_INET, &(cur->daddr), dest, sizeof(dest));
|
||||||
|
ng_log(ANDROID_LOG_DEBUG, "Connected lport %u %s/%u",
|
||||||
|
cur->lport, dest, ntohs(cur->dest));
|
||||||
|
|
||||||
else if (cur->state == TCP_SYN_RECV ||
|
if (writeTCP(cur, NULL, 0, 1, 1, 0, 0, args->tun) < 0) { // SYN+ACK
|
||||||
cur->state == TCP_ESTABLISHED ||
|
ng_log(ANDROID_LOG_ERROR,
|
||||||
cur->state == TCP_CLOSE_WAIT) {
|
"write SYN+ACK error %d: %s",
|
||||||
// Check socket read
|
errno, strerror((errno)));
|
||||||
if (FD_ISSET(cur->socket, &rfds)) {
|
// Remote will retry
|
||||||
// TODO window size
|
cur->state = TCP_TIME_WAIT; // will close socket
|
||||||
uint8_t buffer[MAXPKT];
|
cur = cur->next;
|
||||||
ssize_t bytes = recv(cur->socket, buffer, MAXPKT, 0);
|
continue;
|
||||||
if (bytes <= 0) {
|
} else {
|
||||||
// Socket remotely closed / error
|
cur->local_seq++; // local SYN
|
||||||
|
cur->remote_seq++; // remote SYN
|
||||||
|
cur->state = TCP_SYN_RECV;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (cur->state == TCP_SYN_RECV ||
|
||||||
|
cur->state == TCP_ESTABLISHED ||
|
||||||
|
cur->state == TCP_CLOSE_WAIT) {
|
||||||
|
// Check socket read
|
||||||
|
if (FD_ISSET(cur->socket, &rfds)) {
|
||||||
|
// TODO window size
|
||||||
|
uint8_t buffer[MAXPKT];
|
||||||
|
ssize_t bytes = recv(cur->socket, buffer, MAXPKT, 0);
|
||||||
if (bytes < 0) {
|
if (bytes < 0) {
|
||||||
|
// Socket error
|
||||||
ng_log(ANDROID_LOG_ERROR,
|
ng_log(ANDROID_LOG_ERROR,
|
||||||
"recv lport %u error %d: %s",
|
"recv lport %u error %d: %s",
|
||||||
cur->lport, errno, strerror(errno));
|
cur->lport, errno, strerror(errno));
|
||||||
if (errno == EINTR) {
|
if (errno != EINTR) {
|
||||||
cur = cur->next;
|
if (writeTCP(cur, NULL, 0, 0, 0, 0, 1, args->tun) < 0) // RST
|
||||||
continue;
|
ng_log(ANDROID_LOG_ERROR,
|
||||||
|
"write RST error %d: %s",
|
||||||
|
errno, strerror((errno)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (bytes == 0) {
|
||||||
|
// Socket peer closed
|
||||||
ng_log(ANDROID_LOG_DEBUG,
|
ng_log(ANDROID_LOG_DEBUG,
|
||||||
"recv empty lport %u state %s",
|
"recv empty lport %u state %s",
|
||||||
cur->lport, strstate(cur->state));
|
cur->lport, strstate(cur->state));
|
||||||
|
|
||||||
// TODO can write
|
if (writeTCP(cur, NULL, 0, 0, 0, 1, 0, args->tun) < 0) // FIN
|
||||||
if (writeTCP(cur, NULL, 0, 0, 0, 1, 0, args->tun) < 0) // FIN
|
ng_log(ANDROID_LOG_ERROR,
|
||||||
ng_log(ANDROID_LOG_ERROR,
|
"write FIN lport %u error %d: %s",
|
||||||
"write FIN lport %u error %d: %s",
|
cur->lport, errno, strerror((errno)));
|
||||||
cur->lport, errno, strerror((errno)));
|
else {
|
||||||
else {
|
cur->local_seq++; // local FIN
|
||||||
cur->local_seq++; // local FIN
|
if (cur->state == TCP_SYN_RECV || cur->state == TCP_ESTABLISHED)
|
||||||
if (cur->state == TCP_SYN_RECV || cur->state == TCP_ESTABLISHED)
|
cur->state = TCP_FIN_WAIT1;
|
||||||
cur->state = TCP_FIN_WAIT1;
|
else // close wait
|
||||||
else // close wait
|
cur->state = TCP_LAST_ACK;
|
||||||
cur->state = TCP_LAST_ACK;
|
ng_log(ANDROID_LOG_DEBUG, "Half close state %s",
|
||||||
ng_log(ANDROID_LOG_DEBUG, "Half close state %s",
|
strstate(cur->state));
|
||||||
strstate(cur->state));
|
}
|
||||||
|
} else {
|
||||||
|
// Socket read
|
||||||
|
ng_log(ANDROID_LOG_DEBUG,
|
||||||
|
"recv lport %u bytes %d state %s",
|
||||||
|
cur->lport, bytes, strstate(cur->state));
|
||||||
|
if (writeTCP(cur, buffer, bytes, 0, 0, 0, 0, args->tun) < 0) // ACK
|
||||||
|
ng_log(ANDROID_LOG_ERROR,
|
||||||
|
"write ACK lport %u error %d: %s",
|
||||||
|
cur->lport, errno, strerror((errno)));
|
||||||
|
else
|
||||||
|
cur->local_seq += bytes; // received from socket
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
ng_log(ANDROID_LOG_DEBUG,
|
|
||||||
"recv lport %u bytes %d state %s",
|
|
||||||
cur->lport, bytes, strstate(cur->state));
|
|
||||||
// TODO can write
|
|
||||||
if (writeTCP(cur, buffer, bytes, 0, 0, 0, 0, args->tun) < 0) // ACK
|
|
||||||
ng_log(ANDROID_LOG_ERROR,
|
|
||||||
"write ACK lport %u error %d: %s",
|
|
||||||
cur->lport, errno, strerror((errno)));
|
|
||||||
else
|
|
||||||
cur->local_seq += bytes; // received from socket
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -808,7 +806,6 @@ void handle_tcp(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
rst.daddr = iphdr->daddr;
|
rst.daddr = iphdr->daddr;
|
||||||
rst.dest = tcphdr->dest;
|
rst.dest = tcphdr->dest;
|
||||||
|
|
||||||
// TODO can write
|
|
||||||
if (writeTCP(&rst, NULL, 0, 0, 0, 0, 1, args->tun) < 0)
|
if (writeTCP(&rst, NULL, 0, 0, 0, 0, 1, args->tun) < 0)
|
||||||
ng_log(ANDROID_LOG_ERROR,
|
ng_log(ANDROID_LOG_ERROR,
|
||||||
"write RST error %d: %s",
|
"write RST error %d: %s",
|
||||||
|
@ -872,7 +869,6 @@ void handle_tcp(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ok) {
|
if (ok) {
|
||||||
// TODO can write
|
|
||||||
if (writeTCP(cur, NULL, 0, 1 + datalen, 0, 0, 0, args->tun) < 0) // ACK
|
if (writeTCP(cur, NULL, 0, 1 + datalen, 0, 0, 0, args->tun) < 0) // ACK
|
||||||
ng_log(ANDROID_LOG_ERROR,
|
ng_log(ANDROID_LOG_ERROR,
|
||||||
"write ACK error %d: %s",
|
"write ACK error %d: %s",
|
||||||
|
@ -901,7 +897,6 @@ void handle_tcp(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
int confirm = cur->local_seq - ntohl(tcphdr->ack_seq);
|
int confirm = cur->local_seq - ntohl(tcphdr->ack_seq);
|
||||||
ng_log(ANDROID_LOG_INFO, "Simultaneous close %d", confirm);
|
ng_log(ANDROID_LOG_INFO, "Simultaneous close %d", confirm);
|
||||||
|
|
||||||
// TODO can write
|
|
||||||
if (writeTCP(cur, NULL, 0, confirm, 0, 0, 0, args->tun) < 0) // ACK
|
if (writeTCP(cur, NULL, 0, confirm, 0, 0, 0, args->tun) < 0) // ACK
|
||||||
ng_log(ANDROID_LOG_ERROR,
|
ng_log(ANDROID_LOG_ERROR,
|
||||||
"write ACK error %d: %s",
|
"write ACK error %d: %s",
|
||||||
|
@ -940,7 +935,6 @@ void handle_tcp(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
// Remote will retry
|
// Remote will retry
|
||||||
} else {
|
} else {
|
||||||
// TODO can write
|
|
||||||
if (writeTCP(cur, NULL, 0, datalen, 0, 0, 0, args->tun) < 0) // ACK
|
if (writeTCP(cur, NULL, 0, datalen, 0, 0, 0, args->tun) < 0) // ACK
|
||||||
ng_log(ANDROID_LOG_ERROR,
|
ng_log(ANDROID_LOG_ERROR,
|
||||||
"write data error %d: %s",
|
"write data error %d: %s",
|
||||||
|
@ -1059,16 +1053,6 @@ int getLocalPort(const int sock) {
|
||||||
return ntohs(sin.sin_port);
|
return ntohs(sin.sin_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
int canWrite(const int fd) {
|
|
||||||
struct timeval tv;
|
|
||||||
tv.tv_sec = 0;
|
|
||||||
tv.tv_usec = 0;
|
|
||||||
fd_set wfds;
|
|
||||||
FD_ZERO(&wfds);
|
|
||||||
FD_SET(fd, &wfds);
|
|
||||||
return (select(fd + 1, NULL, &wfds, NULL, &tv) > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int writeTCP(const struct session *cur,
|
int writeTCP(const struct session *cur,
|
||||||
uint8_t *data, uint16_t datalen, uint16_t confirm,
|
uint8_t *data, uint16_t datalen, uint16_t confirm,
|
||||||
int syn, int fin, int rst, int tun) {
|
int syn, int fin, int rst, int tun) {
|
||||||
|
|
Loading…
Reference in New Issue