1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3
* Authors: Jeffrey Stedfast <fejj@ximian.com>
5
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of version 2 of the GNU Lesser General Public
9
* License as published by the Free Software Foundation.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* General Public License for more details.
16
* You should have received a copy of the GNU Lesser General Public
17
* License along with this program; if not, write to the
18
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19
* Boston, MA 02110-1301, USA.
23
#if !defined (__CAMEL_H_INSIDE__) && !defined (CAMEL_COMPILATION)
24
#error "Only <camel/camel.h> can be included directly."
27
#ifndef CAMEL_TCP_STREAM_H
28
#define CAMEL_TCP_STREAM_H
31
#include <sys/types.h>
32
#include <sys/socket.h>
33
#include <netinet/in.h>
34
#include <netinet/tcp.h>
36
typedef struct linger CamelLinger;
49
#include <camel/camel-stream.h>
51
/* Standard GObject macros */
52
#define CAMEL_TYPE_TCP_STREAM \
53
(camel_tcp_stream_get_type ())
54
#define CAMEL_TCP_STREAM(obj) \
55
(G_TYPE_CHECK_INSTANCE_CAST \
56
((obj), CAMEL_TYPE_TCP_STREAM, CamelTcpStream))
57
#define CAMEL_TCP_STREAM_CLASS(cls) \
58
(G_TYPE_CHECK_CLASS_CAST \
59
((cls), CAMEL_TYPE_TCP_STREAM, CamelTcpStreamClass))
60
#define CAMEL_IS_TCP_STREAM(obj) \
61
(G_TYPE_CHECK_INSTANCE_TYPE \
62
((obj), CAMEL_TYPE_TCP_STREAM))
63
#define CAMEL_IS_TCP_STREAM_CLASS(cls) \
64
(G_TYPE_CHECK_CLASS_TYPE \
65
((cls), CAMEL_TYPE_TCP_STREAM))
66
#define CAMEL_TCP_STREAM_GET_CLASS(obj) \
67
(G_TYPE_INSTANCE_GET_CLASS \
68
((obj), CAMEL_TYPE_TCP_STREAM, CamelTcpStreamClass))
72
typedef struct _CamelTcpStream CamelTcpStream;
73
typedef struct _CamelTcpStreamClass CamelTcpStreamClass;
74
typedef struct _CamelTcpStreamPrivate CamelTcpStreamPrivate;
77
CAMEL_SOCKOPT_NONBLOCKING, /* nonblocking io */
78
CAMEL_SOCKOPT_LINGER, /* linger on close if data present */
79
CAMEL_SOCKOPT_REUSEADDR, /* allow local address reuse */
80
CAMEL_SOCKOPT_KEEPALIVE, /* keep connections alive */
81
CAMEL_SOCKOPT_RECVBUFFERSIZE, /* receive buffer size */
82
CAMEL_SOCKOPT_SENDBUFFERSIZE, /* send buffer size */
84
CAMEL_SOCKOPT_IPTIMETOLIVE, /* time to live */
85
CAMEL_SOCKOPT_IPTYPEOFSERVICE, /* type of service and precedence */
87
CAMEL_SOCKOPT_ADDMEMBER, /* add an IP group membership */
88
CAMEL_SOCKOPT_DROPMEMBER, /* drop an IP group membership */
89
CAMEL_SOCKOPT_MCASTINTERFACE, /* multicast interface address */
90
CAMEL_SOCKOPT_MCASTTIMETOLIVE, /* multicast timetolive */
91
CAMEL_SOCKOPT_MCASTLOOPBACK, /* multicast loopback */
93
CAMEL_SOCKOPT_NODELAY, /* don't delay send to coalesce packets */
94
CAMEL_SOCKOPT_MAXSEGMENT, /* maximum segment size */
95
CAMEL_SOCKOPT_BROADCAST, /* enable broadcast */
99
typedef struct _CamelSockOptData {
102
guint ip_ttl; /* IP time to live */
103
guint mcast_ttl; /* IP multicast time to live */
104
guint tos; /* IP type of service and precedence */
105
gboolean non_blocking; /* Non-blocking (network) I/O */
106
gboolean reuse_addr; /* Allow local address reuse */
107
gboolean keep_alive; /* Keep connections alive */
108
gboolean mcast_loopback; /* IP multicast loopback */
109
gboolean no_delay; /* Don't delay send to coalesce packets */
110
gboolean broadcast; /* Enable broadcast */
111
gsize max_segment; /* Maximum segment size */
112
gsize recv_buffer_size; /* Receive buffer size */
113
gsize send_buffer_size; /* Send buffer size */
114
CamelLinger linger; /* Time to linger on close if data present */
118
struct _CamelTcpStream {
121
CamelTcpStreamPrivate *priv;
124
struct _CamelTcpStreamClass {
125
CamelStreamClass parent_class;
127
gint (*connect) (CamelTcpStream *stream,
129
const gchar *service,
131
GCancellable *cancellable,
133
gint (*getsockopt) (CamelTcpStream *stream,
134
CamelSockOptData *data);
135
gint (*setsockopt) (CamelTcpStream *stream,
136
const CamelSockOptData *data);
138
(*get_local_address) (CamelTcpStream *stream,
141
(*get_remote_address) (CamelTcpStream *stream,
144
PRFileDesc * (*get_file_desc) (CamelTcpStream *stream);
147
GType camel_tcp_stream_get_type (void);
148
gint camel_tcp_stream_connect (CamelTcpStream *stream,
150
const gchar *service,
152
GCancellable *cancellable,
154
gint camel_tcp_stream_getsockopt (CamelTcpStream *stream,
155
CamelSockOptData *data);
156
gint camel_tcp_stream_setsockopt (CamelTcpStream *stream,
157
const CamelSockOptData *data);
158
PRFileDesc * camel_tcp_stream_get_file_desc (CamelTcpStream *stream);
160
/* Note about SOCKS proxies:
162
* As of 2010/Jun/02, Camel supports SOCKS4 proxies, but not SOCKS4a nor SOCKS5.
163
* This comment leaves the implementation of those proxy types as an exercise
164
* for the reader, with some hints:
166
* The way SOCKS proxies work right now is that clients of Camel call
167
* camel_session_set_socks_proxy(). Later, users of TCP streams like
168
* the POP/IMAP providers will look at the CamelSession's proxy, and
169
* set it on the CamelTcpStream subclasses that they instantiate.
171
* Both SOCKS4a and SOCKS5 let you resolve hostnames on the proxy; while
172
* SOCKS5 also has extra features like passing a username/password to the
173
* proxy. However, Camel's current API does not let us implement those
176
* You use a CamelTCPStream by essentially doing this:
178
* struct addrinfo *ai;
179
* CamelTcpStream *stream;
182
* stream = camel_tcp_stream_{raw/ssl}_new (session, ...);
183
* camel_tcp_stream_set_socks_proxy (stream, ...);
185
* ai = camel_getaddrinfo (host, port, ...);
186
* result = camel_tcp_stream_connect (stream, ai);
188
* Since you pass a struct addrinfo directly to camel_tcp_stream_connect(), this means
189
* that the stream expects your hostname to be resolved already. However, SOCKS4a/SOCKS5
190
* proxies would rather resolve the hostname themselves.
192
* The solution would be to make camel_tcp_stream_connect() a higher-level API, more or
195
* gint camel_tcp_stream_connect (stream, host, port);
197
* Internally it would do camel_getaddrinfo() for the case without SOCKS proxies,
198
* and otherwise have the proxy itself resolve the host.
200
* Fortunately, it seems that the only callers of CamelTcpStream are *inside* Camel;
201
* Evolution doesn't use this API directly. So all the changes required to
202
* support SOCKS4a/SOCKS5 proxies should be well-contained within Camel,
203
* with no extra changes required in Evolution.
205
void camel_tcp_stream_set_socks_proxy (CamelTcpStream *stream,
206
const gchar *socks_host,
208
void camel_tcp_stream_peek_socks_proxy
209
(CamelTcpStream *stream,
210
const gchar **socks_host_ret,
211
gint *socks_port_ret);
214
camel_tcp_stream_get_local_address
215
(CamelTcpStream *stream,
218
camel_tcp_stream_get_remote_address
219
(CamelTcpStream *stream,
228
#endif /* CAMEL_TCP_STREAM_H */