1 /*
2 * Copyright (C) 2004-2008 Christos Tsantilas
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301 USA.
18 */
19
20 #include "common.h"
21 #include "c-icap.h"
22 //#include "cfg_param.h"
23 #include "port.h"
24 #include <assert.h>
25 #include <errno.h>
26 #include <netinet/tcp.h>
27 #include <arpa/inet.h>
28 #include <netdb.h>
29 #include <sys/time.h>
30 #if defined(USE_POLL)
31 #include <poll.h>
32 #else
33 #include <sys/select.h>
34 #endif
35 #include "debug.h"
36 #include "net_io.h"
37
38
ci_sockaddr_t_to_host(ci_sockaddr_t * addr,char * hname,int maxhostlen)39 const char *ci_sockaddr_t_to_host(ci_sockaddr_t * addr, char *hname,
40 int maxhostlen)
41 {
42 getnameinfo((const struct sockaddr *)&(addr->sockaddr),
43 addr->ci_sin_family == AF_INET6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in), hname, maxhostlen - 1,
44 NULL, 0, 0);
45 return (const char *) hname;
46 }
47
48
49 #ifdef USE_IPV6
icap_init_server_ipv6(ci_port_t * port)50 int icap_init_server_ipv6(ci_port_t *port)
51 {
52 struct sockaddr_in6 addr;
53
54 port->fd = socket(AF_INET6, SOCK_STREAM, 0);
55 if (port->fd == -1) {
56 ci_debug_printf(1, "Error opening ipv6 socket ....\n");
57 return CI_SOCKET_ERROR;
58 }
59
60 icap_socket_opts(port->fd, port->secs_to_linger);
61
62 memset(&addr, 0, sizeof(addr));
63 addr.sin6_family = AF_INET6;
64 addr.sin6_port = htons(port->port);
65 if (port->address == NULL) // ListenAddress is not set in configuration file. Bind to all interfaces
66 addr.sin6_addr = in6addr_any;
67 else {
68 if (inet_pton(AF_INET6, port->address, (void *) &addr.sin6_addr) != 1) {
69 ci_debug_printf(1, "Error converting ipv6 address to the network byte order \n");
70 close(port->fd);
71 port->fd = -1;
72 return CI_SOCKET_ERROR;
73 }
74 }
75
76
77
78 if (bind(port->fd, (struct sockaddr *) &addr, sizeof(addr))) {
79 ci_debug_printf(1, "Error bind at ipv6 address \n");;
80 close(port->fd);
81 port->fd = -1;
82 return CI_SOCKET_ERROR;
83 }
84 if (listen(port->fd, 512)) {
85 ci_debug_printf(1, "Error listening to ipv6 address.....\n");
86 close(port->fd);
87 port->fd = -1;
88 return CI_SOCKET_ERROR;
89 }
90 port->protocol_family = AF_INET6;
91 return port->fd;
92
93 }
94
95 #endif
96
icap_init_server(ci_port_t * port)97 int icap_init_server(ci_port_t *port)
98 {
99 struct sockaddr_in addr;
100
101 #ifdef USE_IPV6
102 if (icap_init_server_ipv6(port) != CI_SOCKET_ERROR)
103 return port->fd;
104 ci_debug_printf(1,
105 "WARNING! Error binding to an ipv6 address. Trying ipv4...\n");
106 #endif
107
108 port->fd = socket(AF_INET, SOCK_STREAM, 0);
109 if (port->fd == -1) {
110 ci_debug_printf(1, "Error opening socket ....\n");
111 return CI_SOCKET_ERROR;
112 }
113
114 icap_socket_opts(port->fd, port->secs_to_linger);
115
116 memset(&addr, 0, sizeof(addr));
117 addr.sin_family = AF_INET;
118 addr.sin_port = htons(port->port);
119 if (port->address == NULL) // ListenAddress is not set in configuration file
120 addr.sin_addr.s_addr = INADDR_ANY;
121 else if (inet_pton(AF_INET, port->address, (void *) &addr.sin_addr.s_addr) != 1) {
122 ci_debug_printf(1, "Error converting ipv4 address to the network byte order \n");
123 close(port->fd);
124 port->fd = -1;
125 return CI_SOCKET_ERROR;
126 }
127
128 if (bind(port->fd, (struct sockaddr *) &addr, sizeof(addr))) {
129 ci_debug_printf(1, "Error binding \n");;
130 close(port->fd);
131 port->fd = -1;
132 return CI_SOCKET_ERROR;
133 }
134 if (listen(port->fd, 512)) {
135 ci_debug_printf(1, "Error listening .....\n");
136 close(port->fd);
137 port->fd = -1;
138 return CI_SOCKET_ERROR;
139 }
140 port->protocol_family = AF_INET;
141 return port->fd;
142 }
143
144
145
icap_socket_opts(ci_socket fd,int secs_to_linger)146 int icap_socket_opts(ci_socket fd, int secs_to_linger)
147 {
148 struct linger li;
149 int value;
150 /* if (fcntl(fd, F_SETFD, 1) == -1) {
151 ci_debug_printf(1,"can't set close-on-exec on server socket!");
152 }
153 */
154
155 value = 1;
156 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value)) == -1) {
157 ci_debug_printf(1, "setsockopt: unable to set SO_REUSEADDR\n");
158 }
159
160 value = 1;
161 if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &value, sizeof(value)) == -1) {
162 ci_debug_printf(1, "setsockopt: unable to set TCP_NODELAY\n");
163 }
164
165 li.l_onoff = 1;
166 li.l_linger = secs_to_linger; /*MAX_SECS_TO_LINGER; */
167
168 if (setsockopt(fd, SOL_SOCKET, SO_LINGER,
169 (char *) &li, sizeof(struct linger)) < 0) {
170 ci_debug_printf(1, "setsockopt: unable to set SO_LINGER \n");
171 }
172 return 1;
173 }
174
175 /*1 is success, 0 should retried, -1 error can be ignored, -2 fatal error */
icap_accept_raw_connection(ci_port_t * port,ci_connection_t * conn)176 int icap_accept_raw_connection(ci_port_t *port, ci_connection_t *conn)
177 {
178 socklen_t claddrlen;
179
180 errno = 0;
181 claddrlen = sizeof(conn->claddr.sockaddr);
182 if (((conn->fd =
183 accept(port->fd,
184 (struct sockaddr *) &(conn->claddr.sockaddr),
185 &claddrlen)) < 0)) {
186 switch (errno) {
187 case EINTR:
188 return 0;
189 case ECONNABORTED:
190 ci_debug_printf(2, "Accepting connection aborted\n");
191 return -1;
192 default:
193 ci_debug_printf(1, "Accept failed: errno=%d\n", errno);
194 return -2;
195 }
196 }
197
198 if (!ci_connection_init(conn, ci_connection_server_side)) {
199 ci_debug_printf(1, "Initializing connection failed, errno:%d\n", errno);
200 close(conn->fd);
201 conn->fd = -1;
202 return -2;
203 }
204
205 return 1;
206 }
207
ci_connection_init(ci_connection_t * conn,ci_connection_type_t type)208 int ci_connection_init(ci_connection_t *conn, ci_connection_type_t type)
209 {
210 socklen_t claddrlen;
211 struct sockaddr *addr;
212 assert(type == ci_connection_server_side || type == ci_connection_client_side);
213 if (type == ci_connection_server_side) {
214 claddrlen = sizeof(conn->srvaddr.sockaddr);
215 addr = (struct sockaddr *) &(conn->srvaddr.sockaddr);
216 } else {
217 claddrlen = sizeof(conn->claddr.sockaddr);
218 addr = (struct sockaddr *) &(conn->claddr.sockaddr);
219 }
220
221 if (getsockname(conn->fd, addr, &claddrlen)) {
222 /* caller should handle the error */
223 return 0;
224 }
225 ci_fill_sockaddr(&(conn->claddr));
226 ci_fill_sockaddr(&(conn->srvaddr));
227
228 fcntl(conn->fd, F_SETFL, O_NONBLOCK); //Setting newfd descriptor to nonblocking state....
229 return 1;
230 }
231
ci_connection_set_nonblock(ci_connection_t * conn)232 int ci_connection_set_nonblock(ci_connection_t *conn)
233 {
234 fcntl(conn->fd, F_SETFL, O_NONBLOCK); //Setting newfd descriptor to nonblocking state....
235 return 1;
236 }
237
238 /*
239 int ci_wait_for_data(ci_socket fd,int secs,int what_wait){
240 fd_set fds, *rfds,*wfds;
241 struct timeval tv;
242 int ret;
243
244 if(secs>=0){
245 tv.tv_sec=secs;
246 tv.tv_usec=0;
247 }
248
249 FD_ZERO(&fds);
250 FD_SET(fd,&fds);
251
252 if(what_wait == wait_for_read){
253 rfds=&fds;
254 wfds=NULL;
255 }
256 else{
257 wfds = &fds;
258 rfds = NULL;
259 }
260 if((ret = select(fd+1, rfds, wfds, NULL,(secs >=0 ? &tv:NULL))) > 0)
261 return 1;
262
263 if(ret < 0){
264 ci_debug_printf(1,"Fatal error while waiting for new data....\n");
265 }
266 return 0;
267 }
268
269 */
270
271 #if defined(USE_POLL)
ci_wait_for_data(int fd,int secs,int what_wait)272 int ci_wait_for_data(int fd, int secs, int what_wait)
273 {
274 int ret = 0;
275 struct pollfd fds[1];
276 secs *= 1000; // Should be in milliseconds
277
278 fds[0].fd = fd;
279 fds[0].events = (what_wait & ci_wait_for_read ? POLLIN : 0) | (what_wait & ci_wait_for_write ? POLLOUT : 0);
280
281 errno = 0;
282 if ((ret = poll(fds, 1, secs)) > 0) {
283 if (fds[0].revents & (POLLERR | POLLHUP)) {
284 ci_debug_printf(3, "ci_wait_for_data error: the connection is terminated\n");
285 return -1;
286 }
287
288 if (fds[0].revents & (POLLNVAL)) {
289 ci_debug_printf(1, "ci_wait_for_data error: poll on closed socket?\n");
290 return -1;
291 }
292 ret = 0;
293 if (fds[0].revents & POLLIN)
294 ret = ci_wait_for_read;
295 if (fds[0].revents & POLLOUT)
296 ret = ret | ci_wait_for_write;
297 return ret;
298 }
299
300 if (ret < 0) {
301 if (errno == EINTR) {
302 return ci_wait_should_retry;
303 } else {
304 ci_debug_printf(5, "Fatal error while waiting for new data (errno=%d....\n", errno);
305 return -1;
306 }
307 }
308 return 0;
309 }
310
311 #else
ci_wait_for_data(int fd,int secs,int what_wait)312 int ci_wait_for_data(int fd, int secs, int what_wait)
313 {
314 fd_set rfds, wfds, *preadfds, *pwritefds;
315 struct timeval tv;
316 int ret = 0;
317
318 if (secs >= 0) {
319 tv.tv_sec = secs;
320 tv.tv_usec = 0;
321 }
322
323 preadfds = NULL;
324 pwritefds = NULL;
325
326 if (what_wait & wait_for_read) {
327 FD_ZERO(&rfds);
328 FD_SET(fd, &rfds);
329 preadfds = &rfds;
330 }
331
332 if (what_wait & wait_for_write) {
333 FD_ZERO(&wfds);
334 FD_SET(fd, &wfds);
335 pwritefds = &wfds;
336 }
337
338 errno = 0;
339 if ((ret =
340 select(fd + 1, preadfds, pwritefds, NULL,
341 (secs >= 0 ? &tv : NULL))) > 0) {
342 ret = 0;
343 if (preadfds && FD_ISSET(fd, preadfds))
344 ret = wait_for_read;
345 if (pwritefds && FD_ISSET(fd, pwritefds))
346 ret = ret | wait_for_write;
347 return ret;
348 }
349
350 if (ret < 0) {
351 if (errno == EINTR) {
352 return ci_wait_should_retry;
353 } else {
354 ci_debug_printf(5, "Fatal error while waiting for new data (errno=%d....\n", errno);
355 return -1;
356 }
357 }
358 return 0;
359 }
360 #endif
361
362
ci_read(int fd,void * buf,size_t count,int timeout)363 int ci_read(int fd, void *buf, size_t count, int timeout)
364 {
365 int bytes = 0;
366 do {
367 bytes = read(fd, buf, count);
368 } while (bytes == -1 && errno == EINTR);
369
370 if (bytes == -1 && errno == EAGAIN) {
371 int ret;
372 do {
373 ret = ci_wait_for_data(fd, timeout, wait_for_read);
374 } while (ret & ci_wait_should_retry);
375
376 if (ret <= 0) /*timeout or connection closed*/
377 return -1;
378
379 do {
380 bytes = read(fd, buf, count);
381 } while (bytes == -1 && errno == EINTR);
382 }
383 if (bytes == 0) {
384 return -1;
385 }
386 return bytes;
387 }
388
389
ci_write(int fd,const void * buf,size_t count,int timeout)390 int ci_write(int fd, const void *buf, size_t count, int timeout)
391 {
392 int bytes = 0;
393 int remains = count;
394 char *b = (char *) buf;
395
396 while (remains > 0) { //write until count bytes written
397 do {
398 bytes = write(fd, b, remains);
399 } while (bytes == -1 && errno == EINTR);
400
401 if (bytes == -1 && errno == EAGAIN) {
402 int ret;
403 do {
404 ret = ci_wait_for_data(fd, timeout, wait_for_write);
405 } while (ret & ci_wait_should_retry);
406
407 if (ret <= 0) /*timeout or connection closed*/
408 return -1;
409
410 do {
411 bytes = write(fd, b, remains);
412 } while (bytes == -1 && errno == EINTR);
413
414 }
415 if (bytes < 0)
416 return bytes;
417 b = b + bytes; //points to remaining bytes......
418 remains = remains - bytes;
419 } //Ok......
420 return count;
421 }
422
423
ci_read_nonblock(int fd,void * buf,size_t count)424 int ci_read_nonblock(int fd, void *buf, size_t count)
425 {
426 int bytes = 0;
427 do {
428 bytes = read(fd, buf, count);
429 } while (bytes == -1 && errno == EINTR);
430
431 if (bytes < 0 && errno == EAGAIN)
432 return 0;
433
434 if (bytes == 0) /*EOF received?*/
435 return -1;
436
437 return bytes;
438 }
439
440
441
ci_write_nonblock(int fd,const void * buf,size_t count)442 int ci_write_nonblock(int fd, const void *buf, size_t count)
443 {
444 int bytes = 0;
445 do {
446 bytes = write(fd, buf, count);
447 } while (bytes == -1 && errno == EINTR);
448
449 if (bytes < 0 && errno == EAGAIN)
450 return 0;
451
452 if (bytes == 0) /*connection is closed?*/
453 return -1;
454
455 return bytes;
456 }
457
458
459
ci_linger_close(int fd,int timeout)460 int ci_linger_close(int fd, int timeout)
461 {
462 char buf[10];
463 int ret;
464 ci_debug_printf(8, "Waiting to close connection\n");
465
466 if (shutdown(fd, SHUT_WR) != 0) {
467 close(fd);
468 return 1;
469 }
470
471 while (ci_wait_for_data(fd, timeout, wait_for_read)
472 && (ret = ci_read_nonblock(fd, buf, 10)) > 0)
473 ci_debug_printf(10, "OK I linger %d bytes.....\n", ret);
474
475 close(fd);
476 ci_debug_printf(8, "Connection closed ...\n");
477 return 1;
478 }
479
480
ci_hard_close(int fd)481 int ci_hard_close(int fd)
482 {
483 close(fd);
484 return 1;
485 }
486
487
488 /*
489 int readline(int fd,char *buf){
490 int i = 0, readed = 0;
491 char c,oc=0;
492 while((readed = icap_read(fd, &c, 1)) > 0 && c != '\n' && i < BUFSIZE ){
493 if(c=='\r'){
494 icap_read(fd, &c, 1);
495 if(c == '\n')
496 break;
497 buf[i++] = '\r';
498 buf[i++] = c;
499 }
500 else
501 buf[i++] = c;
502 }
503 buf[i] = '\0';
504 if(i == BUFSIZE){
505 ci_debug_printf("Readline error. Skip until eol ......\n");
506 while(icap_read(fd, &c, 1) > 0 && c!='\n');
507 }
508 return i;
509 }
510 */
511