diff options
Diffstat (limited to 'sock.c')
-rw-r--r-- | sock.c | 176 |
1 files changed, 176 insertions, 0 deletions
@@ -0,0 +1,176 @@ +#include <sys/types.h> +#include <sys/socket.h> +#include <fcntl.h> +#include <arpa/inet.h> +#include <linux/if_ether.h> +#include <linux/tcp.h> + +#include "sock.h" +#include "die.h" +#include "str.h" +#include "built_in.h" + +int af_socket(int af) +{ + int sock; + + if (unlikely(af != AF_INET && af != AF_INET6)) + panic("Wrong AF socket type!\n"); + + sock = socket(af, SOCK_DGRAM, 0); + if (unlikely(sock < 0)) + panic("Creation AF socket failed!\n"); + + return sock; +} + +int pf_socket(void) +{ + int sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); + if (unlikely(sock < 0)) + panic("Creation of PF socket failed!\n"); + + return sock; +} + +void set_sock_prio(int fd, int prio) +{ + int ret, val = prio; + + ret = setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &val, sizeof(val)); + if (unlikely(ret)) + panic("Cannot set socket priority!\n"); +} + +void set_nonblocking(int fd) +{ + int ret = fcntl(fd, F_SETFL, fcntl(fd, F_GETFD, 0) | O_NONBLOCK); + if (unlikely(ret < 0)) + panic("Cannot fcntl!\n"); +} + +int set_nonblocking_sloppy(int fd) +{ + return fcntl(fd, F_SETFL, fcntl(fd, F_GETFD, 0) | O_NONBLOCK); +} + +void set_socket_keepalive(int fd) +{ + int ret, one = 1; + + ret = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(one)); + if (unlikely(ret)) + panic("Cannot set TCP keepalive!\n"); +} + +void set_tcp_nodelay(int fd) +{ + int one = 1; + setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)); +} + +int set_ipv6_only(int fd) +{ + int one = 1; + return setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one)); +} + +int set_reuseaddr(int fd) +{ + int ret, one = 1; + + ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); + if (unlikely(ret < 0)) + panic("Cannot reuse addr!\n"); + + return 0; +} + +void set_mtu_disc_dont(int fd) +{ + int mtu = IP_PMTUDISC_DONT, ret; + + ret = setsockopt(fd, SOL_IP, IP_MTU_DISCOVER, &mtu, sizeof(mtu)); + if (unlikely(ret)) + panic("Cannot set MTU discovery options!\n"); +} + +enum { + sock_rmem_max = 0, + sock_rmem_def, + sock_wmem_max, + sock_wmem_def, +}; + +#define SMEM_SUG_MAX 104857600 +#define SMEM_SUG_DEF 4194304 + +static const char *const sock_mem[] = { + [sock_rmem_max] = "/proc/sys/net/core/rmem_max", + [sock_rmem_def] = "/proc/sys/net/core/rmem_default", + [sock_wmem_max] = "/proc/sys/net/core/wmem_max", + [sock_wmem_def] = "/proc/sys/net/core/wmem_default", +}; + +static int get_system_socket_mem(int which) +{ + int fd, val = -1; + ssize_t ret; + const char *file = sock_mem[which]; + char buff[64]; + + fd = open(file, O_RDONLY); + if (fd < 0) + return val; + + ret = read(fd, buff, sizeof(buff)); + if (ret > 0) + val = atoi(buff); + + close(fd); + return val; +} + +static void set_system_socket_mem(int which, int val) +{ + int fd; + const char *file = sock_mem[which]; + ssize_t ret; + char buff[64]; + + fd = open(file, O_WRONLY); + if (fd < 0) + return; + + memset(buff, 0, sizeof(buff)); + slprintf(buff, sizeof(buff), "%d", val); + + ret = write(fd, buff, strlen(buff)); + ret = ret; + + close(fd); +} + +void set_system_socket_memory(int *vals, size_t len) +{ + bug_on(len != 4); + + if ((vals[0] = get_system_socket_mem(sock_rmem_max)) < SMEM_SUG_MAX) + set_system_socket_mem(sock_rmem_max, SMEM_SUG_MAX); + if ((vals[1] = get_system_socket_mem(sock_rmem_def)) < SMEM_SUG_DEF) + set_system_socket_mem(sock_rmem_def, SMEM_SUG_DEF); + if ((vals[2] = get_system_socket_mem(sock_wmem_max)) < SMEM_SUG_MAX) + set_system_socket_mem(sock_wmem_max, SMEM_SUG_MAX); + if ((vals[3] = get_system_socket_mem(sock_wmem_def)) < SMEM_SUG_DEF) + set_system_socket_mem(sock_wmem_def, SMEM_SUG_DEF); +} + +void reset_system_socket_memory(int *vals, size_t len) +{ + bug_on(len != 4); + + set_system_socket_mem(sock_rmem_max, vals[0]); + set_system_socket_mem(sock_rmem_def, vals[1]); + set_system_socket_mem(sock_wmem_max, vals[2]); + set_system_socket_mem(sock_wmem_def, vals[3]); +} |