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 
21 #ifndef __NET_IO_H
22 #define __NET_IO_H
23 
24 #include "c-icap.h"
25 #ifndef _WIN32
26 #include <netinet/in.h>
27 #include <sys/ioctl.h>
28 #include <sys/socket.h>
29 #include <netinet/tcp.h>
30 #include <arpa/inet.h>
31 #include <netdb.h>
32 #include <fcntl.h>
33 #else
34 #include <WinSock2.h>
35 #endif
36 #ifdef USE_OPENSSL
37 #include <openssl/bio.h>
38 #endif
39 
40 #ifdef __cplusplus
41 extern "C"
42 {
43 #endif
44 
45 #ifndef _WIN32
46 #define ci_socket int
47 #define CI_SOCKET_ERROR -1
48 #else
49 #define ci_socket SOCKET
50 #define CI_SOCKET_ERROR INVALID_SOCKET
51 #endif
52 typedef ci_socket ci_socket_t;
53 
54 typedef struct ci_sockaddr {
55 #ifdef USE_IPV6
56     struct sockaddr_storage  sockaddr;
57 #else
58     struct sockaddr_in   sockaddr;
59 #endif
60     int ci_sin_family;/* #define ci_sin_family sockaddr.sin_family */
61     int ci_sin_port;  /* #define ci_sin_port   sockaddr.sin_port   */
62     void *ci_sin_addr;
63     int ci_inaddr_len;
64 }  ci_sockaddr_t;
65 
66 #define CI_MAXHOSTNAMELEN 256
67 
68 #ifdef USE_IPV6
69 
70 typedef union ci_inaddr {
71     struct in_addr ipv4_addr;
72     struct in6_addr ipv6_addr;
73 } ci_in_addr_t;
74 
75 #define ci_inaddr_zero(addr) (memset(&(addr),0,sizeof(ci_in_addr_t)))
76 #define ci_inaddr_copy(dest,src) (memcpy(&(dest),&(src),sizeof(ci_in_addr_t)))
77 #define ci_ipv4_inaddr_hostnetmask(addr)((addr).ipv4_addr.s_addr = htonl(0xFFFFFFFF))
78 #define ci_in6_addr_u32(addr) ((uint32_t *)&((addr).ipv6_addr))
79 #define ci_ipv6_inaddr_hostnetmask(addr)(ci_in6_addr_u32(addr)[0] = htonl(0xFFFFFFFF),\
80                      ci_in6_addr_u32(addr)[1] = htonl(0xFFFFFFFF), \
81                      ci_in6_addr_u32(addr)[2] = htonl(0xFFFFFFFF), \
82                      ci_in6_addr_u32(addr)[3] = htonl(0xFFFFFFFF))
83 
84 #define CI_IPLEN      46
85 
86 #else /*IPV4 only*/
87 
88 typedef struct in_addr ci_in_addr_t;
89 #define ci_inaddr_zero(addr) ((addr).s_addr = 0)
90 #define ci_inaddr_copy(dest,src) ((dest) = (src))
91 #define ci_ipv4_inaddr_hostnetmask(addr)((addr).s_addr = htonl(0xFFFFFFFF))
92 
93 
94 #define CI_IPLEN      16
95 #endif
96 
97 #define wait_for_read       0x1
98 #define wait_for_write      0x2
99 #define wait_for_readwrite  0x3
100 
101 #define ci_wait_for_read       0x1
102 #define ci_wait_for_write      0x2
103 #define ci_wait_for_readwrite  0x3
104 #define ci_wait_should_retry   0x4
105 
106 
107 typedef struct ci_ip {
108     ci_in_addr_t address;
109     ci_in_addr_t netmask;
110     int family;
111 } ci_ip_t;
112 
113 /*Flags for ci_connection_t object*/
114 #define CI_CONNECTION_CONNECTED 0x1
115 
116 typedef struct ci_connection {
117     ci_socket fd;
118     ci_sockaddr_t claddr;
119     ci_sockaddr_t srvaddr;
120 #ifdef USE_OPENSSL
121     BIO* bio;
122 #endif
123     int32_t flags;
124 }  ci_connection_t ;
125 
126 struct ci_port;
127 
128 CI_DECLARE_FUNC(ci_connection_t *) ci_connection_create();
129 CI_DECLARE_FUNC(void) ci_connection_destroy(ci_connection_t *connection);
130 
131 CI_DECLARE_FUNC(void) ci_fill_sockaddr(ci_sockaddr_t *addr);
132 CI_DECLARE_FUNC(void) ci_fill_ip_t(ci_ip_t *ip, ci_sockaddr_t *addr);
133 
134 CI_DECLARE_FUNC(void) ci_copy_sockaddr(ci_sockaddr_t *dest, ci_sockaddr_t *src);
135 CI_DECLARE_FUNC(int) ci_inet_aton(int af,const char *cp, void *inp);
136 CI_DECLARE_FUNC(const char *) ci_inet_ntoa(int af,const void *src, char *dst,int cnt);
137 
138 
139 CI_DECLARE_FUNC(const char *) ci_sockaddr_t_to_ip(ci_sockaddr_t *addr, char *ip,int ip_strlen);
140 #define ci_conn_remote_ip(conn,ip) ci_sockaddr_t_to_ip(&(conn->claddr),ip,CI_IPLEN)
141 #define ci_conn_local_ip(conn,ip)  ci_sockaddr_t_to_ip(&(conn->srvaddr),ip,CI_IPLEN)
142 
143 #ifdef USE_IPV6
144 CI_DECLARE_FUNC(void) ci_sockaddr_set_port(ci_sockaddr_t *addr, int port);
145 #define ci_sockaddr_set_family(addr,family) ((addr).sockaddr.ss_family=family)
146 #else
147 CI_DECLARE_FUNC(void) ci_sockaddr_set_port(ci_sockaddr_t *addr, int port);
148 #define ci_sockaddr_set_family(addr,family) ((addr).sockaddr.sin_family=family/*,(addr).ci_sin_family=family*/)
149 #endif
150 
151 CI_DECLARE_FUNC(const char *) ci_sockaddr_t_to_host(ci_sockaddr_t *addr, char *hname, int maxhostlen);
152 CI_DECLARE_FUNC(int) ci_host_to_sockaddr_t(const char *servername, ci_sockaddr_t * addr, int proto);
153 
154 CI_DECLARE_FUNC(void) ci_copy_connection(ci_connection_t *dest, ci_connection_t *src);
155 CI_DECLARE_FUNC(void) ci_connection_reset(ci_connection_t *conn);
156 
157 CI_DECLARE_FUNC(int) icap_socket_opts(ci_socket fd, int secs_to_linger);
158 CI_DECLARE_FUNC(ci_socket) icap_init_server(struct ci_port *port);
159 CI_DECLARE_FUNC(int) icap_accept_raw_connection(struct ci_port *port, ci_connection_t *conn);
160 
161 
162 CI_DECLARE_FUNC(int) ci_wait_for_data(ci_socket fd,int secs,int what_wait);
163 
164 #define ci_wait_for_incomming_data(fd,timeout) ci_wait_for_data(fd,timeout,wait_for_read)
165 #define ci_wait_for_outgoing_data(fd,timeout) ci_wait_for_data(fd,timeout,wait_for_write)
166 
167 CI_DECLARE_FUNC(int) ci_connection_set_nonblock(ci_connection_t *conn);
168 
169 typedef enum {ci_connection_server_side, ci_connection_client_side} ci_connection_type_t;
170 CI_DECLARE_FUNC(int) ci_connection_init(ci_connection_t *conn, ci_connection_type_t type);
171 
172 CI_DECLARE_FUNC(int) ci_read(ci_socket fd,void *buf,size_t count,int timeout);
173 CI_DECLARE_FUNC(int) ci_write(ci_socket fd, const void *buf,size_t count,int timeout);
174 CI_DECLARE_FUNC(int) ci_read_nonblock(ci_socket fd, void *buf,size_t count);
175 CI_DECLARE_FUNC(int) ci_write_nonblock(ci_socket fd, const void *buf,size_t count);
176 
177 CI_DECLARE_FUNC(int) ci_linger_close(ci_socket fd,int secs_to_linger);
178 CI_DECLARE_FUNC(int) ci_hard_close(ci_socket fd);
179 
180 CI_DECLARE_FUNC(ci_connection_t *) ci_connect_to(const char *servername, int port, int proto, int timeout);
181 CI_DECLARE_FUNC(int) ci_connect_to_nonblock(ci_connection_t *connection, const char *servername, int port, int proto);
182 
183 CI_DECLARE_FUNC(int) ci_connection_wait(ci_connection_t *conn, int secs, int what_wait);
184 CI_DECLARE_FUNC(int) ci_connection_read(ci_connection_t *conn, void *buf, size_t count, int timeout);
185 CI_DECLARE_FUNC(int) ci_connection_write(ci_connection_t *conn, void *buf, size_t count, int timeout);
186 CI_DECLARE_FUNC(int) ci_connection_read_nonblock(ci_connection_t *conn, void *buf, size_t count);
187 CI_DECLARE_FUNC(int) ci_connection_write_nonblock(ci_connection_t *conn, void *buf, size_t count);
188 CI_DECLARE_FUNC(int) ci_connection_linger_close(ci_connection_t *conn, int timeout);
189 CI_DECLARE_FUNC(int) ci_connection_hard_close(ci_connection_t *conn);
190 #ifdef __cplusplus
191 }
192 #endif
193 
194 #endif
195