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