source: benchmark/io/http/socket.cfa @ 5c27b6a

Last change on this file since 5c27b6a was 32d1383, checked in by Thierry Delisle <tdelisle@…>, 2 years ago

Committing http server when I know it works

  • Property mode set to 100644
File size: 2.2 KB
Line 
1#define _GNU_SOURCE
2
3#include "socket.hfa"
4
5#include <errno.h>
6#include <string.h>
7extern "C" {
8        #include <sys/socket.h>
9        #include <netinet/in.h>
10        #include <netinet/tcp.h>
11}
12
13#include <fstream.hfa>
14#include <time.hfa>
15#include <thread.hfa>
16
17#include "options.hfa"
18
19int prepaddr(struct sockaddr_in & address) {
20        int addrlen = sizeof(address);
21        memset( (char *)&address, '\0', addrlen );
22        address.sin_family = AF_INET;
23        address.sin_addr.s_addr = htonl(INADDR_ANY);
24        address.sin_port = htons( options.socket.port );
25        return addrlen;
26}
27
28int listener(struct sockaddr_in & address, int addrlen) {
29        int type = SOCK_STREAM;
30        // if(options.socket.reuseport) type |= SOCK_NONBLOCK;
31        int sockfd = socket(AF_INET, type, 0);
32        if(sockfd < 0) {
33                abort( "socket error: (%d) %s\n", (int)errno, strerror(errno) );
34        }
35
36        int on = 1;
37        const struct linger l = { 1, 0 };
38        if (setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0)
39                abort( "setsockopt SO_LINGER error: (%d) %s\n", (int)errno, strerror(errno) );
40
41        if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (const void*)&on, sizeof(on)) < 0)
42                abort( "setsockopt SO_LINGER error: (%d) %s\n", (int)errno, strerror(errno) );
43
44        if(options.socket.reuseport) {
45                // if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void*)&on, sizeof(on)))
46                //      abort( "setsockopt SO_REUSEADDR error: (%d) %s\n", (int)errno, strerror(errno) );
47                if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)) < 0)
48                        abort( "setsockopt SO_REUSEPORT error: (%d) %s\n", (int)errno, strerror(errno) );
49        }
50
51        int ret = 0;
52        int waited = 0;
53        for() {
54                __CONST_SOCKADDR_ARG addr;
55                addr.__sockaddr__ = (struct sockaddr *)&address;
56                socklen_t addrlen = sizeof(address);
57                ret = bind( sockfd, addr, addrlen );
58                if(ret < 0) {
59                        if(errno == EADDRINUSE) {
60                                if(waited == 0) {
61                                        if(!options.interactive) abort | "Port already in use in non-interactive mode. Aborting";
62                                        sout | "Waiting for port";
63                                } else {
64                                        sout | "\r" | waited | nonl;
65                                        flush( sout );
66                                }
67                                waited ++;
68                                sleep( 1`s );
69                                continue;
70                        }
71                        abort( "bind error: (%d) %s\n", (int)errno, strerror(errno) );
72                }
73                break;
74        }
75
76        ret = listen( sockfd, options.socket.backlog );
77        if(ret < 0) {
78                abort( "listen error: (%d) %s\n", (int)errno, strerror(errno) );
79        }
80
81        return sockfd;
82}
Note: See TracBrowser for help on using the repository browser.