1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
3 * Copyright (C) 2021 Ole André Vadla Ravnås <oleavr@frida.re>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, see
17 * <http://www.gnu.org/licenses/>.
19 * In addition, when the library is used with OpenSSL, a special
20 * exception applies. Refer to the LICENSE_EXCEPTION file for details.
25 #include "lossy-socket.h"
29 GObject parent_instance;
31 GDatagramBased *base_socket;
33 IOPredicateFunc predicate_func;
34 gpointer predicate_data;
40 static void lossy_socket_datagram_based_iface_init (GDatagramBasedInterface *iface);
42 G_DEFINE_TYPE_EXTENDED (LossySocket,
45 G_IMPLEMENT_INTERFACE (G_TYPE_DATAGRAM_BASED,
46 lossy_socket_datagram_based_iface_init))
49 lossy_socket_receive_messages (GDatagramBased *datagram_based,
50 GInputMessage *messages,
54 GCancellable *cancellable,
57 LossySocket *self = LOSSY_SOCKET (datagram_based);
67 ret = g_datagram_based_receive_messages (self->base_socket, messages,
68 num_messages, flags, timeout,
74 d.serial = self->next_rx_serial++;
76 if (self->predicate_func (&d, self->predicate_data) == IO_DROP)
78 messages->bytes_received = 0;
84 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK,
85 "Operation would block");
99 lossy_socket_send_messages (GDatagramBased *datagram_based,
100 GOutputMessage *messages,
104 GCancellable *cancellable,
107 LossySocket *self = LOSSY_SOCKET (datagram_based);
110 d.direction = IO_OUT;
111 d.serial = self->next_tx_serial++;
113 if (self->predicate_func (&d, self->predicate_data) == IO_DROP)
117 for (i = 0; i < num_messages; i++)
119 GOutputMessage *m = &messages[i];
121 for (j = 0; j < m->num_vectors; j++)
122 m->bytes_sent += m->vectors[j].size;
128 return g_datagram_based_send_messages (self->base_socket, messages,
129 num_messages, flags, timeout,
134 lossy_socket_create_source (GDatagramBased *datagram_based,
135 GIOCondition condition,
136 GCancellable *cancellable)
138 LossySocket *self = LOSSY_SOCKET (datagram_based);
140 return g_datagram_based_create_source (self->base_socket, condition,
145 lossy_socket_condition_check (GDatagramBased *datagram_based,
146 GIOCondition condition)
148 LossySocket *self = LOSSY_SOCKET (datagram_based);
150 return g_datagram_based_condition_check (self->base_socket, condition);
154 lossy_socket_condition_wait (GDatagramBased *datagram_based,
155 GIOCondition condition,
157 GCancellable *cancellable,
160 LossySocket *self = LOSSY_SOCKET (datagram_based);
162 return g_datagram_based_condition_wait (self->base_socket, condition, timeout,
167 lossy_socket_init (LossySocket *self)
169 self->next_rx_serial = 1;
170 self->next_tx_serial = 1;
174 lossy_socket_dispose (GObject *object)
176 LossySocket *self = LOSSY_SOCKET (object);
178 g_clear_object (&self->base_socket);
180 G_OBJECT_CLASS (lossy_socket_parent_class)->dispose (object);
184 lossy_socket_class_init (LossySocketClass *klass)
186 GObjectClass *object_class = G_OBJECT_CLASS (klass);
188 object_class->dispose = lossy_socket_dispose;
192 lossy_socket_datagram_based_iface_init (GDatagramBasedInterface *iface)
194 iface->receive_messages = lossy_socket_receive_messages;
195 iface->send_messages = lossy_socket_send_messages;
196 iface->create_source = lossy_socket_create_source;
197 iface->condition_check = lossy_socket_condition_check;
198 iface->condition_wait = lossy_socket_condition_wait;
202 lossy_socket_new (GDatagramBased *base_socket,
203 IOPredicateFunc predicate_func,
204 gpointer predicate_data)
208 s = g_object_new (LOSSY_TYPE_SOCKET, NULL);
209 s->base_socket = g_object_ref (base_socket);
210 s->predicate_func = predicate_func;
211 s->predicate_data = predicate_data;
213 return G_DATAGRAM_BASED (s);