+static gboolean async_rpc_do_udp(GIOChannel *channel,
+ GIOCondition condition,
+ gpointer data)
+{
+ char buf[65536];
+
+ struct sockaddr_in src;
+ socklen_t addrlen = sizeof(struct sockaddr_in);
+ ssize_t len = recvfrom(g_io_channel_unix_get_fd(channel),
+ buf, sizeof(buf), 0,
+ (struct sockaddr *)&src, &addrlen);
+ if (len < 0) {
+ fprintf(stderr, "UDP read error: %m, shutting down UDP\n");
+ return FALSE;
+ }
+
+ g_assert(len < sizeof(buf));
+
+ RPCConnection *rpc = g_new0(RPCConnection, 1);
+ rpc->channel = channel;
+ rpc->msgbuf = g_string_new_len(buf, len);
+ rpc->send_lock = g_mutex_new();
+ rpc->udp_transport = TRUE;
+ memcpy(&rpc->peer, &src, sizeof(struct sockaddr_in));
+ rpc->sendbuf = g_string_new("");
+
+ /* We have a complete message since this was the last fragment and
+ * there are no more bytes in it. Dispatch the message. */
+ async_rpc_dispatch(rpc);
+
+ return TRUE;
+}
+
+static async_rpc_register_listening_udp(int fd)
+{
+ GIOChannel *channel = g_io_channel_unix_new(fd);
+ g_io_channel_set_encoding(channel, NULL, NULL);
+ GSource *source = g_io_create_watch(channel, G_IO_IN);
+ g_source_set_callback(source, (GSourceFunc)async_rpc_do_udp,
+ NULL, NULL);
+ g_source_attach(source, main_context);
+ g_source_unref(source);
+}
+