static void visit_contact_channel (GObject *source, GAsyncResult *result, gpointer user_data) { ChChannelRequest *chreq = (ChChannelRequest*) user_data; ChVisitor *self = chreq->self; TpContact *contact = chreq->contact; g_free (chreq); const char *ident, *contact_ident; GError *error = NULL; GPtrArray *channels; if (!list_channels_finish (source, result, &channels, &error)) { g_printerr ("error listing channels: %s\n", error->message); return; } contact_ident = tp_contact_get_identifier (contact); // Try to find a matching channel among the already established channels for (unsigned int i = 0; i < channels->len; i++) { TpChannel *channel = g_ptr_array_index (channels, i); ident = tp_channel_get_identifier (channel); if (!strcmp (ident, contact_ident)) { self->visit_channel (self, channel); goto done; } } // Request a new channel request_channel (self, contact); done: g_ptr_array_free (channels, TRUE); ch_visitor_decref (self); }
static void read_udp_peer(evutil_socket_t fd, short events, void *relay) { struct RelayListener *listener = (struct RelayListener *) relay; struct sockaddr_in addr; socklen_t addr_size = sizeof(addr); uint8_t buffer[BUFFER_LIMIT]; int32_t buff_size; if((buff_size = recvfrom( fd, &buffer, BUFFER_LIMIT, 0, (struct sockaddr *) &addr, &addr_size)) == -1) { error_on_udp_peer(fd, events, relay); return; } struct UDPChannel *channel = find_udp_channel_by_peer(&addr); if(!channel) { union Channel *chan = request_channel(listener->proto, listener->port); if(!chan) { debug("udp peer: no channels left!"); return; } chan->udp.peer_fd = fd; memcpy(&chan->udp.peer_addr, &addr, addr_size); chan->udp.pre_buffer = evbuffer_new(); if(buff_size + sizeof(int32_t) <= BUFFER_LIMIT) { evbuffer_add(chan->udp.pre_buffer, &buff_size, sizeof(int32_t)); evbuffer_add(chan->udp.pre_buffer, buffer, buff_size); } return; } if(!channel->channel_fd) { if(evbuffer_get_length(channel->pre_buffer) + buff_size + sizeof(int32_t) <= BUFFER_LIMIT) { evbuffer_add(channel->pre_buffer, &buff_size, sizeof(int32_t)); evbuffer_add(channel->pre_buffer, buffer, buff_size); } return; } if(sendto( channel->channel_fd, buffer, buff_size, 0, (struct sockaddr *) &channel->channel_addr, addr_size) == -1) { error_on_udp_channel(fd, events, relay); return; } channel->base.alive = 2; }