summaryrefslogtreecommitdiff
path: root/src/ne_socket.h
blob: 5f6d05de7076c890dfc631bba2009e118b597bb9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
/* 
   socket handling interface
   Copyright (C) 1999-2010, Joe Orton <joe@manyfish.co.uk>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.
   
   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with this library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
   MA 02111-1307, USA

*/

#ifndef NE_SOCKET_H
#define NE_SOCKET_H

#include <sys/types.h>

#ifdef WIN32
#include <stdlib.h> /* for size_t */
#endif

#include "ne_defs.h"
#include "ne_ssl.h" /* for ne_ssl_context */

NE_BEGIN_DECLS

#define NE_SOCK_ERROR (-1)
/* Read/Write timed out */
#define NE_SOCK_TIMEOUT (-2)
/* Socket was closed */
#define NE_SOCK_CLOSED (-3)
/* Connection was reset (e.g. server crashed) */
#define NE_SOCK_RESET (-4)
/* Secure connection was closed without proper SSL shutdown. */
#define NE_SOCK_TRUNC (-5)
/* Reserved value -   (-6) */

/* ne_socket represents a TCP socket. */
typedef struct ne_socket_s ne_socket;

/* ne_sock_addr represents an address object. */
typedef struct ne_sock_addr_s ne_sock_addr;

#ifndef NE_INET_ADDR_DEFINED
typedef struct ne_inet_addr_s ne_inet_addr;
#endif

/* Perform process-global initialization of any libraries in use.
 * Returns non-zero on error. */
int ne_sock_init(void);

/* Perform process-global shutdown of any libraries in use.  This
 * function only has effect when it has been called an equal number of
 * times to ne_sock_init() for the process. */
void ne_sock_exit(void);

#define NE_ADDR_CANON (0x01)
/* Resolve the given hostname. Hex string IPv6 addresses (e.g. `::1')
 * may be enclosed in brackets (e.g. `[::1]').  'flags' should be
 * zero, or if NE_ADDR_CANON is passed, the canonical name for the
 * hostname will be determind. */
ne_sock_addr *ne_addr_resolve(const char *hostname, int flags);

/* Returns zero if name resolution was successful, non-zero on
 * error. */
int ne_addr_result(const ne_sock_addr *addr);

/* Returns the first network address associated with the 'addr'
 * object.  Undefined behaviour if ne_addr_result returns non-zero for
 * 'addr'; otherwise, never returns NULL.  */
const ne_inet_addr *ne_addr_first(ne_sock_addr *addr);

/* Returns the next network address associated with the 'addr' object,
 * or NULL if there are no more. */
const ne_inet_addr *ne_addr_next(ne_sock_addr *addr);

/* NB: the pointers returned by ne_addr_first and ne_addr_next are
 * valid until ne_addr_destroy is called for the corresponding
 * ne_sock_addr object.  They must not be passed to ne_iaddr_free. */

/* If name resolution fails, copies the error string into 'buffer',
 * which is of size 'bufsiz'.  'buffer' is returned. */
char *ne_addr_error(const ne_sock_addr *addr, char *buffer, size_t bufsiz);

/* Returns the canonical name of the host as a NUL-terminated string,
 * if NE_ADDR_CANON was used, and name resolution was successful.
 * Otherwise, returns NULL. */
const char *ne_addr_canonical(const ne_sock_addr *addr);

/* Destroys an address object created by ne_addr_resolve. */
void ne_addr_destroy(ne_sock_addr *addr);

/* Network address type; IPv4 or IPv6 */
typedef enum {
    ne_iaddr_ipv4 = 0,
    ne_iaddr_ipv6
} ne_iaddr_type;

/* Create a network address object from raw byte representation (in
 * network byte order) of given type.  'raw' must be four bytes for an
 * IPv4 address, 16 bytes for an IPv6 address.  May return NULL if
 * address type is not supported. */
ne_inet_addr *ne_iaddr_make(ne_iaddr_type type, const unsigned char *raw);

/* Compare two network address objects i1 and i2; returns zero if they
 * are equivalent or non-zero otherwise.  */
int ne_iaddr_cmp(const ne_inet_addr *i1, const ne_inet_addr *i2);

/* Return the type of the given network address object. */
ne_iaddr_type ne_iaddr_typeof(const ne_inet_addr *ia);

/* Print the string representation of network address 'ia' into the
 * buffer 'buffer', which is of length 'bufsiz'.  Returns 'buffer'. */
char *ne_iaddr_print(const ne_inet_addr *ia, char *buffer, size_t bufsiz);

/* Dump the raw byte representation (in network byte order) of address
 * 'ia' into the buffer 'buffer', which must be of a suitable length
 * (4 bytes for an IPv4 address, 16 bytes for an IPv6 address).
 * Returns 'buffer'. */
unsigned char *ne_iaddr_raw(const ne_inet_addr *ia, unsigned char *buffer);

/* Perform the reverse name lookup on network address 'ia', placing
 * the returned name in the 'buf' buffer (of length 'bufsiz') if
 * successful.  Returns zero on success, or non-zero on error. */
int ne_iaddr_reverse(const ne_inet_addr *ia, char *buf, size_t bufsiz);

/* Convert network address string 'addr' (for example, "127.0.0.1")
 * into a network address object.  Returns NULL on parse error.  If
 * non-NULL, return value must be freed using ne_iaddr_free. */
ne_inet_addr *ne_iaddr_parse(const char *addr, ne_iaddr_type type);

/* Destroy a network address object created using ne_iaddr_make or
 * ne_iaddr_parse. */
void ne_iaddr_free(ne_inet_addr *addr);

/* Create a socket object; returns NULL on error. */
ne_socket *ne_sock_create(void);

/* Specify an address to which the local end of the socket will be
 * bound during a subsequent ne_sock_connect() call.  If the address
 * passed to ne_sock_connect() is of a different type (family) to
 * 'addr', 'addr' is ignored.  Either 'addr' may be NULL, to use the
 * given port with unspecified address, or 'port' may be 0, to use the
 * given address with an unspecified port.
 *
 * (Note: This function is not equivalent to a BSD socket bind(), it
 * only takes effect during the _connect() call). */
void ne_sock_prebind(ne_socket *sock, const ne_inet_addr *addr,
                     unsigned int port);

/* Connect the socket to server at address 'addr' on port 'port'.
 * Returns zero on success, NE_SOCK_TIMEOUT if a timeout occurs when a
 * non-zero connect timeout is configured (and is supported), or
 * NE_SOCK_ERROR on failure.  */
int ne_sock_connect(ne_socket *sock, const ne_inet_addr *addr, 
                    unsigned int port);

/* Read up to 'count' bytes from socket into 'buffer'.  Returns:
 *   NE_SOCK_* on error,
 *   >0 length of data read into buffer (may be less than 'count')
 */
ssize_t ne_sock_read(ne_socket *sock, char *buffer, size_t count);

/* Read up to 'count' bytes into 'buffer', leaving the data available
 * in the socket buffer to be returned by a subsequent call to
 * ne_sock_read or ne_sock_peek. Returns:
 *   NE_SOCK_* on error,
 *   >0 length of data read into buffer.
 */
ssize_t ne_sock_peek(ne_socket *sock, char *buffer, size_t count);

/* Block for up to 'n' seconds until data becomes available for reading
 * from the socket. Returns:
 *  NE_SOCK_* on error,
 *  NE_SOCK_TIMEOUT if no data arrives in 'n' seconds,
 *  0 if data arrived on the socket.
 */
int ne_sock_block(ne_socket *sock, int n);

/* Write 'count' bytes of 'data' to the socket.  Guarantees to either
 * write all the bytes or to fail.  Returns 0 on success, or NE_SOCK_*
 * on error. */
int ne_sock_fullwrite(ne_socket *sock, const char *data, size_t count); 

/* I/O vector. */
struct ne_iovec {
    void *base;
    size_t len;
};

/* Writes 'count' blocks described by 'vector' to the socket.
 * Guarantees to either write all the bytes or to fail.  Count must be
 * greater than zero and smaller than the system-defined maximum
 * vector limit.  Returns 0 on success, or NE_SOCK_* on error. */
int ne_sock_fullwritev(ne_socket *sock, const struct ne_iovec *vector,
                       int count); 

/* Read an LF-terminated line into 'buffer', and NUL-terminate it.
 * At most 'len' bytes are read (including the NUL terminator).
 * Returns:
 * NE_SOCK_* on error,
 * >0 number of bytes read (including NUL terminator)
 */
ssize_t ne_sock_readline(ne_socket *sock, char *buffer, size_t len);

/* Read exactly 'len' bytes into buffer, or fail; returns 0 on
 * success, NE_SOCK_* on error. */
ssize_t ne_sock_fullread(ne_socket *sock, char *buffer, size_t len);

/* Accepts a connection from listening socket 'fd' and places the
 * socket in 'sock'.  Returns zero on success or -1 on failure. */
int ne_sock_accept(ne_socket *sock, int fd);

/* Returns the file descriptor used for socket 'sock'. */
int ne_sock_fd(const ne_socket *sock);

/* Return address of peer, or NULL on error.  The returned address
 * must be destroyed by caller using ne_iaddr_free. */
ne_inet_addr *ne_sock_peer(ne_socket *sock, unsigned int *port);

/* Close the socket and destroy the socket object.  If SSL is in use
 * for the socket, a closure alert is sent to initiate a clean
 * shutdown, but this function does not wait for the peer's response.
 * Returns zero on success, or non-zero on failure. */
int ne_sock_close(ne_socket *sock);

/* Return current error string for socket. */
const char *ne_sock_error(const ne_socket *sock);

/* Set the error string for the socket; takes printf-like format
 * string. */
void ne_sock_set_error(ne_socket *sock, const char *format, ...)
    ne_attribute((format (printf, 2, 3)));

/* Set read timeout for socket, in seconds; must be a non-zero
 * positive integer. */
void ne_sock_read_timeout(ne_socket *sock, int timeout);

/* Set connect timeout for socket, in seconds; must be a positive
 * integer.  If a timeout of 'zero' is used then then no explicit
 * timeout handling will be used for ne_sock_connect(), and the
 * connect call will only timeout as dictated by the TCP stack. */
void ne_sock_connect_timeout(ne_socket *sock, int timeout);

/* Negotiate an SSL connection on socket as an SSL server, using given
 * SSL context. */
int ne_sock_accept_ssl(ne_socket *sock, ne_ssl_context *ctx);

/* Negotiate an SSL connection on socket as an SSL client, using given
 * SSL context.  The 'userdata' parameter is associated with the
 * underlying SSL library's socket structure for use in callbacks.
 * Returns zero on success, or non-zero on error. */
int ne_sock_connect_ssl(ne_socket *sock, ne_ssl_context *ctx,
                        void *userdata);

/* Retrieve the session ID of the current SSL session.  If 'buf' is
 * non-NULL, on success, copies at most *buflen bytes to 'buf' and
 * sets *buflen to the exact number of bytes copied.  If 'buf' is
 * NULL, on success, sets *buflen to the length of the session ID.
 * Returns zero on success, non-zero on error. */
int ne_sock_sessid(ne_socket *sock, unsigned char *buf, size_t *buflen);

/* Return human-readable name of SSL/TLS cipher used for connection,
 * or NULL if none.  The format of this string is not intended to be
 * fixed or parseable, but is informational only.  Return value is
 * NUL-terminated malloc-allocated string if not NULL, which must be
 * freed by the caller. */
char *ne_sock_cipher(ne_socket *sock);

/* SOCKS proxy protocol version: */
enum ne_sock_sversion {
    NE_SOCK_SOCKSV4 = 0,
    NE_SOCK_SOCKSV4A,
    NE_SOCK_SOCKSV5
};

/* Given a socket 'sock' which is connected to a SOCKS proxy, initiate
 * a connection to a destination server using that proxy, specified
 * either by network address or hostname, at given port 'port'.
 *
 * If 'vers' is NE_SOCKS_V4, addr must be an IPv4 address; hostname
 * and password are ignored; username must be non-NULL.
 *
 * If 'vers' is NE_SOCKS_V4A, hostname must be non-NULL; addr is
 * ignored; password is ignored; username must be non-NULL.
 *
 * If 'vers' is NE_SOCKS_V5, addr may be NULL, in which case hostname
 * must be non-NULL.  addr if non-NULL may be an IPv4 or IPv6 address;
 * username may be NULL, in which case password is ignored.  If
 * username is non-NULL password must also be non-NULL.
 *
 * Returns 0 on success, or NE_SOCK_* on failure - in which case, the
 * socket error string is set.  On failure, the socket must be closed
 * by the caller.
 */
int ne_sock_proxy(ne_socket *sock, enum ne_sock_sversion vers,
                  const ne_inet_addr *addr, const char *hostname, 
                  unsigned int port,
                  const char *username, const char *password);

NE_END_DECLS

#endif /* NE_SOCKET_H */