#include #include #include #include #include #include #include static int silent_mode = 0; static unsigned send_delay = 0; char* xgetenv(const char* name){ char* rv = getenv(name); return rv ? rv : ""; } __attribute__ ((constructor)) void slowloris_init(){ silent_mode = strtoul(xgetenv("SLOWLORIS_SILENT"), NULL, 10); send_delay = strtoul(xgetenv("SLOWLORIS_DELAY"), NULL, 10); if(!silent_mode){ printf("preload-slowloris active\nDelay: %d\n", send_delay); } } int socket(int domain, int type, int protocol){ static int (*real_socket) (int, int, int) = NULL; if(!real_socket){ real_socket = dlsym(RTLD_NEXT, "socket"); } int fd = real_socket(domain, type, protocol); int enable = 1; if(domain == AF_INET && type == SOCK_STREAM){ if(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable)) < 0){ if(!silent_mode){ perror("setsockopt/tcp_nodelay"); } } } return fd; } ssize_t send(int sockfd, const void* buf, size_t len, int flags){ static ssize_t (*real_send) (int, void*, size_t, int) = NULL; if(!real_send){ real_send = dlsym(RTLD_NEXT, "send"); } ssize_t rv = 0; for(size_t u = 0; u < len; u++){ ssize_t sent = real_send(sockfd, buf + u, 1, flags); if(sent < 0){ return -1; } rv += sent; if(send_delay){ usleep(send_delay); } } return rv; }