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