2 * This file is part of the Nice GLib ICE library.
4 * (C) 2010 Collabora Ltd.
5 * Contact: Youness Alaoui
8 * The contents of this file are subject to the Mozilla Public License Version
9 * 1.1 (the "License"); you may not use this file except in compliance with
10 * the License. You may obtain a copy of the License at
11 * http://www.mozilla.org/MPL/
13 * Software distributed under the License is distributed on an "AS IS" basis,
14 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
15 * for the specific language governing rights and limitations under the
18 * The Original Code is the Nice GLib ICE library.
20 * The Initial Developers of the Original Code are Collabora Ltd and Nokia
21 * Corporation. All Rights Reserved.
24 * Youness Alaoui, Collabora Ltd.
26 * Alternatively, the contents of this file may be used under the terms of the
27 * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
28 * case the provisions of LGPL are applicable instead of those above. If you
29 * wish to allow use of your version of this file only under the terms of the
30 * LGPL and not to allow others to use your version of this file under the
31 * MPL, indicate your decision by deleting the provisions above and replace
32 * them with the notice and other provisions required by the LGPL. If you do
33 * not delete the provisions above, a recipient may use your version of this
34 * file under either the MPL or the LGPL.
42 * @short_description: Pseudo TCP implementation
43 * @include: pseudotcp.h
46 * The #PseudoTcpSocket is an object implementing a Pseudo Tcp Socket for use
48 * The socket will implement a subset of the TCP stack to allow for a reliable
49 * transport over non-reliable sockets (such as UDP).
51 * See the file tests/test-pseudotcp.c in the source package for an example
52 * of how to use the object.
59 #include <glib-object.h>
62 # include <winsock2.h>
63 # define ECONNABORTED WSAECONNABORTED
64 # define ENOTCONN WSAENOTCONN
65 # define EWOULDBLOCK WSAEWOULDBLOCK
66 # define ECONNRESET WSAECONNRESET
74 * The #PseudoTcpSocket is the GObject implementing the Pseudo TCP Socket
78 typedef struct _PseudoTcpSocket PseudoTcpSocket
;
80 typedef struct _PseudoTcpSocketClass PseudoTcpSocketClass
;
82 GType
pseudo_tcp_socket_get_type (void);
85 #define PSEUDO_TCP_SOCKET_TYPE \
86 (pseudo_tcp_socket_get_type ())
87 #define PSEUDO_TCP_SOCKET(obj) \
88 (G_TYPE_CHECK_INSTANCE_CAST((obj), PSEUDO_TCP_SOCKET_TYPE, \
90 #define PSEUDO_TCP_SOCKET_CLASS(klass) \
91 (G_TYPE_CHECK_CLASS_CAST((klass), PSEUDO_TCP_SOCKET_TYPE, \
92 PseudoTcpSocketClass))
93 #define IS_PSEUDO_TCP_SOCKET(obj) \
94 (G_TYPE_CHECK_INSTANCE_TYPE((obj), PSEUDO_TCP_SOCKET_TYPE))
95 #define IS_PSEUDO_TCP_SOCKET_CLASS(klass) \
96 (G_TYPE_CHECK_CLASS_TYPE((klass), PSEUDO_TCP_SOCKET_TYPE))
97 #define PSEUDOTCP_SOCKET_GET_CLASS(obj) \
98 (G_TYPE_INSTANCE_GET_CLASS ((obj), PSEUDO_TCP_SOCKET_TYPE, \
99 PseudoTcpSocketClass))
101 struct _PseudoTcpSocketClass
{
102 GObjectClass parent_class
;
105 typedef struct _PseudoTcpSocketPrivate PseudoTcpSocketPrivate
;
107 struct _PseudoTcpSocket
{
109 PseudoTcpSocketPrivate
*priv
;
113 * PseudoTcpDebugLevel:
114 * @PSEUDO_TCP_DEBUG_NONE: Disable debug messages
115 * @PSEUDO_TCP_DEBUG_NORMAL: Enable basic debug messages
116 * @PSEUDO_TCP_DEBUG_VERBOSE: Enable verbose debug messages
118 * Valid values of debug levels to be set.
123 PSEUDO_TCP_DEBUG_NONE
= 0,
124 PSEUDO_TCP_DEBUG_NORMAL
,
125 PSEUDO_TCP_DEBUG_VERBOSE
,
126 } PseudoTcpDebugLevel
;
130 * @TCP_LISTEN: The socket's initial state. The socket isn't connected and is
131 * listening for an incoming connection
132 * @TCP_SYN_SENT: The socket has sent a connection request (SYN) packet and is
133 * waiting for an answer
134 * @TCP_SYN_RECEIVED: The socket has received a connection request (SYN) packet.
135 * @TCP_ESTABLISHED: The socket is connected
136 * @TCP_CLOSED: The socket has been closed
138 * An enum representing the state of the #PseudoTcpSocket.
139 * <para> See also: #PseudoTcpSocket:state </para>
152 * PseudoTcpWriteResult:
153 * @WR_SUCCESS: The write operation was successful
154 * @WR_TOO_LARGE: The socket type requires that message be sent atomically
155 * and the size of the message to be sent made this impossible.
156 * @WR_FAIL: There was an error sending the message
158 * An enum representing the result value of the write operation requested by
159 * the #PseudoTcpSocket.
160 * <para> See also: %PseudoTcpCallbacks:WritePacket </para>
168 } PseudoTcpWriteResult
;
171 * PseudoTcpCallbacks:
172 * @user_data: A user defined pointer to be passed to the callbacks
173 * @PseudoTcpOpened: The #PseudoTcpSocket is now connected
174 * @PseudoTcpReadable: The socket is readable
175 * @PseudoTcpWritable: The socket is writable
176 * @PseudoTcpClosed: The socket was closed
177 * @WritePacket: This callback is called when the socket needs to send data.
179 * A structure containing callbacks functions that will be called by the
180 * #PseudoTcpSocket when some events happen.
181 * <para> See also: #PseudoTcpWriteResult </para>
187 void (*PseudoTcpOpened
) (PseudoTcpSocket
*tcp
, gpointer data
);
188 void (*PseudoTcpReadable
) (PseudoTcpSocket
*tcp
, gpointer data
);
189 void (*PseudoTcpWritable
) (PseudoTcpSocket
*tcp
, gpointer data
);
190 void (*PseudoTcpClosed
) (PseudoTcpSocket
*tcp
, guint32 error
, gpointer data
);
191 PseudoTcpWriteResult (*WritePacket
) (PseudoTcpSocket
*tcp
,
192 const gchar
* buffer
, guint32 len
, gpointer data
);
193 } PseudoTcpCallbacks
;
196 * pseudo_tcp_socket_new:
197 * @conversation: The conversation id for the socket.
198 * @callbacks: A pointer to the #PseudoTcpCallbacks structure for getting
199 * notified of the #PseudoTcpSocket events.
201 * Creates a new #PseudoTcpSocket for the specified conversation
205 The @callbacks must be non-NULL, in order to get notified of packets the
206 socket needs to send.
209 If the @callbacks structure was dynamicly allocated, it can be freed
210 after the call @pseudo_tcp_socket_new
214 * Returns: The new #PseudoTcpSocket object, %NULL on error
218 PseudoTcpSocket
*pseudo_tcp_socket_new (guint32 conversation
,
219 PseudoTcpCallbacks
*callbacks
);
223 * pseudo_tcp_socket_connect:
224 * @self: The #PseudoTcpSocket object.
226 * Connects the #PseudoTcpSocket to the peer with the same conversation id.
227 * The connection will only be successful after the
228 * %PseudoTcpCallbacks:PseudoTcpOpened callback is called
230 * Returns: %TRUE on success, %FALSE on failure (not in %TCP_LISTEN state)
231 * <para> See also: pseudo_tcp_socket_get_error() </para>
235 gboolean
pseudo_tcp_socket_connect(PseudoTcpSocket
*self
);
239 * pseudo_tcp_socket_recv:
240 * @self: The #PseudoTcpSocket object.
241 * @buffer: The buffer to fill with received data
242 * @len: The length of @buffer
244 * Receive data from the socket.
248 Only call this on the %PseudoTcpCallbacks:PseudoTcpReadable callback.
251 This function should be called in a loop. If this function does not
252 return -1 with EWOULDBLOCK as the error, the
253 %PseudoTcpCallbacks:PseudoTcpReadable callback will not be called again.
257 * Returns: The number of bytes received or -1 in case of error
258 * <para> See also: pseudo_tcp_socket_get_error() </para>
262 gint
pseudo_tcp_socket_recv(PseudoTcpSocket
*self
, char * buffer
, size_t len
);
266 * pseudo_tcp_socket_send:
267 * @self: The #PseudoTcpSocket object.
268 * @buffer: The buffer with data to send
269 * @len: The length of @buffer
271 * Send data on the socket.
275 If this function return -1 with EWOULDBLOCK as the error, or if the return
276 value is lower than @len, then the %PseudoTcpCallbacks:PseudoTcpWritable
277 callback will be called when the socket will become writable.
281 * Returns: The number of bytes sent or -1 in case of error
282 * <para> See also: pseudo_tcp_socket_get_error() </para>
286 gint
pseudo_tcp_socket_send(PseudoTcpSocket
*self
, const char * buffer
,
291 * pseudo_tcp_socket_close:
292 * @self: The #PseudoTcpSocket object.
293 * @force: %TRUE to close the socket forcefully, %FALSE to close it gracefully
295 * Close the socket. IF @force is set to %FALSE, the socket will finish sending
296 * pending data before closing.
300 The %PseudoTcpCallbacks:PseudoTcpClosed callback will not be called once
301 the socket gets closed. It is only used for aborted connection.
302 Instead, the socket gets closed when the pseudo_tcp_socket_get_next_clock()
303 function returns FALSE.
307 * <para> See also: pseudo_tcp_socket_get_next_clock() </para>
311 void pseudo_tcp_socket_close(PseudoTcpSocket
*self
, gboolean force
);
315 * pseudo_tcp_socket_get_error:
316 * @self: The #PseudoTcpSocket object.
318 * Return the last encountered error.
322 The return value can be :
324 EINVAL (for pseudo_tcp_socket_connect()).
327 EWOULDBLOCK or ENOTCONN (for pseudo_tcp_socket_recv() and
328 pseudo_tcp_socket_send()).
333 * Returns: The error code
334 * <para> See also: pseudo_tcp_socket_connect() </para>
335 * <para> See also: pseudo_tcp_socket_recv() </para>
336 * <para> See also: pseudo_tcp_socket_send() </para>
340 int pseudo_tcp_socket_get_error(PseudoTcpSocket
*self
);
344 * pseudo_tcp_socket_get_next_clock:
345 * @self: The #PseudoTcpSocket object.
346 * @timeout: A pointer to be filled with the new timeout.
348 * Call this to determine the timeout needed before the next time call
349 * to pseudo_tcp_socket_notify_clock() should be made.
351 * Returns: %TRUE if @timeout was filled, %FALSE if the socket is closed and
352 * ready to be destroyed.
354 * <para> See also: pseudo_tcp_socket_notify_clock() </para>
358 gboolean
pseudo_tcp_socket_get_next_clock(PseudoTcpSocket
*self
, long *timeout
);
362 * pseudo_tcp_socket_notify_clock:
363 * @self: The #PseudoTcpSocket object.
365 * Start the processing of receiving data, pending data or syn/acks.
366 * Call this based on timeout value returned by
367 * pseudo_tcp_socket_get_next_clock().
368 * It's ok to call this too frequently.
370 * <para> See also: pseudo_tcp_socket_get_next_clock() </para>
374 void pseudo_tcp_socket_notify_clock(PseudoTcpSocket
*self
);
378 * pseudo_tcp_socket_notify_mtu:
379 * @self: The #PseudoTcpSocket object.
380 * @mtu: The new MTU of the socket
382 * Set the MTU of the socket
386 void pseudo_tcp_socket_notify_mtu(PseudoTcpSocket
*self
, guint16 mtu
);
390 * pseudo_tcp_socket_notify_packet:
391 * @self: The #PseudoTcpSocket object.
392 * @buffer: The buffer containing the received data
393 * @len: The length of @buffer
395 * Notify the #PseudoTcpSocket when a new packet arrives
397 * Returns: %TRUE if the packet was processed successfully, %FALSE otherwise
401 gboolean
pseudo_tcp_socket_notify_packet(PseudoTcpSocket
*self
,
402 const gchar
* buffer
, guint32 len
);
406 * pseudo_tcp_set_debug_level:
407 * @level: The level of debug to set
409 * Sets the debug level to enable/disable normal/verbose debug messages.
413 void pseudo_tcp_set_debug_level (PseudoTcpDebugLevel level
);
417 #endif /* _PSEUDOTCP_H */