/* Detect specific Linux Kernel features that we may use */ int mk_kernel_features() { int flags = 0; /* * FIXME: TCP Auto Corking: * * I found that running some benchmarks on Linux 3.16 with * tcp_autocorking enabled, it lead to lower performance, looks like * a manual cork fits better for our needs. * * I think there is something wrong that we need to clarify, by now * I've logged the following issue: * * https://github.com/monkey/monkey/issues/175 * if (mk_kernel_runver >= MK_KERNEL_VERSION(3, 14, 0) && mk_socket_tcp_autocorking() == MK_TRUE) { flags |= MK_KERNEL_TCP_AUTOCORKING; } */ /* SO_REUSEPORT */ if (mk_kernel_runver >= MK_KERNEL_VERSION(3, 9, 0)) { flags |= MK_KERNEL_SO_REUSEPORT; } /* TCP_FASTOPEN */ if (mk_kernel_runver >= MK_KERNEL_VERSION(3, 7, 0)) { flags |= MK_KERNEL_TCP_FASTOPEN; } config->kernel_features = flags; return flags; }
/* * Enable the TCP_FASTOPEN feature for server side implemented in * Linux Kernel >= 3.7, for more details read here: * * TCP Fast Open: expediting web services: http://lwn.net/Articles/508865/ */ int mk_socket_set_tcp_fastopen(int sockfd) { #if defined (__linux__) int qlen = 5; if (mk_kernel_runver >= MK_KERNEL_VERSION(3, 7, 0)) { return setsockopt(sockfd, SOL_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen)); } #endif (void) sockfd; return -1; }
int mk_kernel_version() { int a, b, c; int len; int pos; char *p, *t; char *tmp; struct utsname uts; if (uname(&uts) == -1) { mk_libc_error("uname"); } len = strlen(uts.release); /* Fixme: this don't support Linux Kernel 10.x.x :P */ a = (*uts.release - '0'); /* Second number */ p = (uts.release) + 2; pos = mk_string_char_search(p, '.', len - 2); if (pos <= 0) { /* Some Debian systems uses a different notation, e.g: 3.14-2-amd64 */ pos = mk_string_char_search(p, '-', len - 2); if (pos <= 0) { return -1; } } tmp = mk_string_copy_substr(p, 0, pos); if (!tmp) { return -1; } b = atoi(tmp); mk_mem_free(tmp); /* Last number (it needs filtering) */ t = p = p + pos + 1; do { t++; } while (isdigit(*t)); tmp = mk_string_copy_substr(p, 0, t - p); if (!tmp) { return -1; } c = atoi(tmp); mk_mem_free(tmp); MK_TRACE("Kernel detected: %i.%i.%i", a, b, c); return MK_KERNEL_VERSION(a, b, c); }