Branch data Line data Source code
1 : : /**
2 : : * \file
3 : : *
4 : : * \author Georg Hopp
5 : : *
6 : : * \copyright
7 : : * Copyright © 2012 Georg Hopp
8 : : *
9 : : * This program is free software: you can redistribute it and/or modify
10 : : * it under the terms of the GNU General Public License as published by
11 : : * the Free Software Foundation, either version 3 of the License, or
12 : : * (at your option) any later version.
13 : : *
14 : : * This program is distributed in the hope that it will be useful,
15 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : : * GNU General Public License for more details.
18 : : *
19 : : * You should have received a copy of the GNU General Public License
20 : : * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 : : */
22 : :
23 : : #include <fcntl.h>
24 : : #include <unistd.h>
25 : : #include <stdlib.h>
26 : :
27 : : #include <openssl/ssl.h>
28 : : #include <openssl/err.h>
29 : :
30 : : #include "class.h"
31 : : #include "server.h"
32 : : #include "socket.h"
33 : : #include "logger.h"
34 : :
35 : : #include "utils/memory.h"
36 : :
37 : :
38 : : void serverCloseConn(Server, unsigned int);
39 : :
40 : :
41 : : static
42 : : int
43 : 1 : serverCtor(void * _this, va_list * params)
44 : : {
45 : 1 : Server this = _this;
46 : : in_port_t port;
47 : : unsigned int backlog;
48 : :
49 : 1 : this->max_fds = sysconf(_SC_OPEN_MAX);
50 : 1 : if (this->max_fds <= 10) { // reserve 10 handles for internal use.
51 : : /**
52 : : * \todo some logging would be appropriate :)
53 : : */
54 : 0 : return -1;
55 : : }
56 : 1 : this->max_fds -= 10;
57 : :
58 : 1 : this->logger = va_arg(* params, Logger);
59 : 1 : this->worker = va_arg(* params, void *);
60 : 1 : port = va_arg(* params, int);
61 : 1 : backlog = va_arg(* params, unsigned int);
62 : :
63 : 1 : loggerLog(this->logger,
64 : : LOGGER_INFO,
65 : : "accept up to %zu connections",
66 : : this->max_fds);
67 : :
68 : 1 : this->fds = memCalloc(sizeof(struct pollfd), this->max_fds);
69 : 1 : this->conns = memCalloc(sizeof(struct conns), this->max_fds);
70 : :
71 : 1 : this->sock = new(Sock, this->logger, port);
72 : 1 : socketNonblock(this->sock);
73 : :
74 : 1 : this->sockSSL = new(Sock, this->logger, port+1);
75 : 1 : socketNonblock(this->sockSSL);
76 : :
77 : 1 : SSL_library_init();
78 : 1 : OpenSSL_add_all_algorithms();
79 : 1 : SSL_load_error_strings();
80 : 1 : this->ctx = SSL_CTX_new(SSLv23_server_method());
81 : 1 : SSL_CTX_set_cipher_list(
82 : : this->ctx,
83 : : "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AES:RSA+3DES:!ADH:!AECDH:!MD5:!DSS");
84 : 1 : SSL_CTX_use_certificate_file(
85 : : this->ctx,
86 : : CONFIGDIR "/taskrambler.crt",
87 : : SSL_FILETYPE_PEM);
88 : :
89 : 1 : SSL_CTX_use_RSAPrivateKey_file(
90 : : this->ctx,
91 : : CONFIGDIR "/taskrambler.pem",
92 : : SSL_FILETYPE_PEM);
93 : :
94 : 1 : socketListen(this->sock, backlog);
95 : 1 : socketListen(this->sockSSL, backlog);
96 : :
97 : 1 : (this->fds)[0].fd = this->sock->handle;
98 : 1 : (this->fds)[0].events = POLLIN;
99 : 1 : (this->fds)[1].fd = this->sockSSL->handle;
100 : 1 : (this->fds)[1].events = POLLIN;
101 : 1 : this->nfds = 2;
102 : :
103 : 1 : return 0;
104 : : }
105 : :
106 : : static
107 : : void
108 : 2 : serverDtor(void * _this)
109 : : {
110 : 2 : Server this = _this;
111 : : int i;
112 : :
113 : 7 : for (i=0; i<this->nfds; i++) {
114 : 8 : if (this->sock->handle != (this->fds)[i].fd &&
115 : 3 : this->sockSSL->handle != (this->fds)[i].fd) {
116 : 1 : serverCloseConn(this, i);
117 : : }
118 : : }
119 : :
120 : 2 : MEM_FREE(this->fds);
121 : 2 : MEM_FREE(this->conns);
122 : :
123 : 2 : delete(this->sock);
124 : 2 : delete(this->sockSSL);
125 : :
126 : 2 : SSL_CTX_free(this->ctx);
127 : 2 : ERR_free_strings();
128 : 2 : }
129 : :
130 : : INIT_IFACE(Class, serverCtor, serverDtor, NULL);
131 : 1 : CREATE_CLASS(Server, NULL, IFACE(Class));
132 : :
133 : : // vim: set ts=4 sw=4:
|