Native limit number of sessions

Refs #311
This commit is contained in:
M66B 2016-02-11 09:12:00 +01:00
parent 1212c49e9b
commit 09da6010da
3 changed files with 35 additions and 10 deletions

View File

@ -23,7 +23,9 @@ int max_tun_msg = 0;
extern int loglevel;
extern FILE *pcap_file;
int check_tun(const struct arguments *args, fd_set *rfds, fd_set *wfds, fd_set *efds) {
int check_tun(const struct arguments *args,
fd_set *rfds, fd_set *wfds, fd_set *efds,
int sessions, int maxsessions) {
// Check tun error
if (FD_ISSET(args->tun, efds)) {
log_android(ANDROID_LOG_ERROR, "tun %d exception", args->tun);
@ -64,7 +66,7 @@ int check_tun(const struct arguments *args, fd_set *rfds, fd_set *wfds, fd_set *
}
// Handle IP from tun
handle_ip(args, buffer, (size_t) length);
handle_ip(args, buffer, (size_t) length, sessions, maxsessions);
free(buffer);
}
@ -102,7 +104,9 @@ int is_upper_layer(int protocol) {
protocol == IPPROTO_ICMPV6);
}
void handle_ip(const struct arguments *args, const uint8_t *pkt, const size_t length) {
void handle_ip(const struct arguments *args,
const uint8_t *pkt, const size_t length,
int sessions, int maxsessions) {
uint8_t protocol;
void *saddr;
void *daddr;
@ -255,6 +259,18 @@ void handle_ip(const struct arguments *args, const uint8_t *pkt, const size_t le
}
flags[flen] = 0;
// Limit number of sessions
if (sessions >= maxsessions) {
if ((protocol == IPPROTO_ICMP || protocol == IPPROTO_ICMPV6) ||
(protocol == IPPROTO_UDP && !has_udp_session(args, pkt, payload)) ||
(protocol == IPPROTO_TCP && syn)) {
log_android(ANDROID_LOG_ERROR,
"%d of max %d sessions, dropping version %d protocol %d",
sessions, maxsessions, protocol, version);
return;
}
}
// Get uid
jint uid = -1;
if (protocol == IPPROTO_ICMP || protocol == IPPROTO_ICMPV6 ||

View File

@ -302,7 +302,9 @@ int get_tcp_timeout(const struct tcp_session *t, int sessions);
int get_selects(const struct arguments *args, fd_set *rfds, fd_set *wfds, fd_set *efds);
int check_tun(const struct arguments *args, fd_set *rfds, fd_set *wfds, fd_set *efds);
int check_tun(const struct arguments *args,
fd_set *rfds, fd_set *wfds, fd_set *efds,
int sessions, int maxsessions);
void check_icmp_sockets(const struct arguments *args, fd_set *rfds, fd_set *wfds, fd_set *efds);
@ -318,7 +320,9 @@ int is_lower_layer(int protocol);
int is_upper_layer(int protocol);
void handle_ip(const struct arguments *args, const uint8_t *buffer, size_t length);
void handle_ip(const struct arguments *args,
const uint8_t *buffer, size_t length,
int sessions, int maxsessions);
void init_icmp(const struct arguments *args);

View File

@ -59,11 +59,15 @@ void *handle_events(void *a) {
// Get SDK version
sdk = sdk_int(env);
int maxsessions = 1024;
struct rlimit rlim;
if (getrlimit(RLIMIT_NOFILE, &rlim))
log_android(ANDROID_LOG_WARN, "getrlimit error %d: %s", errno, strerror(errno));
else
log_android(ANDROID_LOG_WARN, "getrlimit soft %d hard %d", rlim.rlim_cur, rlim.rlim_max);
else {
maxsessions = rlim.rlim_cur * 80 / 100;
log_android(ANDROID_LOG_WARN, "getrlimit soft %d hard %d max sessions %d",
rlim.rlim_cur, rlim.rlim_max, maxsessions);
}
// Block SIGUSR1
sigemptyset(&blockset);
@ -90,11 +94,12 @@ void *handle_events(void *a) {
int isessions = check_icmp_sessions(args);
int usessions = check_udp_sessions(args);
int tsessions = check_tcp_sessions(args);
int sessions = isessions + usessions + tsessions;
// https://bugzilla.mozilla.org/show_bug.cgi?id=1093893
int idle = (tsessions + usessions + tsessions == 0 && sdk >= 16);
log_android(ANDROID_LOG_DEBUG, "sessions ICMP %d UDP %d TCP %d idle %d sdk %d",
isessions, usessions, tsessions, idle, sdk);
log_android(ANDROID_LOG_DEBUG, "sessions ICMP %d UDP %d TCP %d max %d/%d idle %d sdk %d",
isessions, usessions, tsessions, sessions, maxsessions, idle, sdk);
// Next event time
ts.tv_sec = (sdk < 16 ? 5 : get_select_timeout(isessions, usessions, tsessions));
@ -154,7 +159,7 @@ void *handle_events(void *a) {
// Check upstream
int error = 0;
if (check_tun(args, &rfds, &wfds, &efds) < 0)
if (check_tun(args, &rfds, &wfds, &efds, sessions, maxsessions) < 0)
error = 1;
else {
#ifdef PROFILE_EVENTS