4 #include <sys/select.h>
12 #include "agent-signals-marshal.h"
18 /* (ICE-13 §4.1.1) For RTP-based media streams, the RTP itself has a component
19 * ID of 1, and RTCP a component ID of 2. If an agent is using RTCP it MUST
20 * obtain a candidate for it. If an agent is using both RTP and RTCP, it
21 * would end up with 2*K host candidates if an agent has K interfaces.
31 typedef struct _Component Component
;
36 /* the local candidate that last received a valid connectivity check */
37 NiceCandidate
*active_candidate
;
38 /* the remote address that the last connectivity check came from */
39 NiceAddress peer_addr
;
41 NiceComponentState state
;
42 GSList
*local_candidates
;
43 GSList
*remote_candidates
;
54 component
= g_slice_new0 (Component
);
61 component_free (Component
*cmp
)
65 for (i
= cmp
->local_candidates
; i
; i
= i
->next
)
67 NiceCandidate
*candidate
= i
->data
;
69 nice_candidate_free (candidate
);
72 for (i
= cmp
->remote_candidates
; i
; i
= i
->next
)
74 NiceCandidate
*candidate
= i
->data
;
76 nice_candidate_free (candidate
);
79 g_slist_free (cmp
->local_candidates
);
80 g_slist_free (cmp
->remote_candidates
);
81 g_slice_free (Component
, cmp
);
88 typedef struct _Stream Stream
;
93 /* XXX: streams can have multiple components */
103 stream
= g_slice_new0 (Stream
);
104 stream
->component
= component_new (COMPONENT_TYPE_RTP
);
110 stream_free (Stream
*stream
)
112 component_free (stream
->component
);
113 g_slice_free (Stream
, stream
);
117 /*** candidate_pair ***/
120 typedef struct _CandidatePair CandidatePair
;
122 struct _CandidatePair
125 NiceCandidate remote
;
129 /* ICE-13 §5.7 (p24) */
133 CHECK_STATE_IN_PROGRESS
,
134 CHECK_STATE_SUCCEEDED
,
142 CHECK_LIST_STATE_RUNNING
,
143 CHECK_LIST_STATE_COMPLETED
,
150 candidate_pair_priority (
151 guint64 offerer_prio
,
152 guint64 answerer_prio
)
155 0x100000000LL
* MIN (offerer_prio
, answerer_prio
) +
156 2 * MAX (offerer_prio
, answerer_prio
) +
157 (offerer_prio
> answerer_prio
? 1 : 0));
165 G_DEFINE_TYPE (NiceAgent
, nice_agent
, G_TYPE_OBJECT
);
170 PROP_SOCKET_FACTORY
= 1,
176 SIGNAL_COMPONENT_STATE_CHANGED
,
181 static guint signals
[N_SIGNALS
];
185 find_stream (NiceAgent
*agent
, guint stream_id
)
189 for (i
= agent
->streams
; i
; i
= i
->next
)
193 if (s
->id
== stream_id
)
207 Component
**component
)
211 if (component_id
!= 1)
214 s
= find_stream (agent
, stream_id
);
223 *component
= s
->component
;
230 nice_agent_dispose (GObject
*object
);
233 nice_agent_get_property (
240 nice_agent_set_property (
248 nice_agent_class_init (NiceAgentClass
*klass
)
250 GObjectClass
*gobject_class
= G_OBJECT_CLASS (klass
);
252 gobject_class
->get_property
= nice_agent_get_property
;
253 gobject_class
->set_property
= nice_agent_set_property
;
254 gobject_class
->dispose
= nice_agent_dispose
;
256 /* install properties */
258 g_object_class_install_property (gobject_class
, PROP_SOCKET_FACTORY
,
259 g_param_spec_pointer (
261 "UDP socket factory",
262 "The socket factory used to create new UDP sockets",
263 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT_ONLY
));
265 /* install signals */
267 signals
[SIGNAL_COMPONENT_STATE_CHANGED
] =
269 "component-state-changed",
270 G_OBJECT_CLASS_TYPE (klass
),
271 G_SIGNAL_RUN_LAST
| G_SIGNAL_DETAILED
,
275 agent_marshal_VOID__UINT_UINT_UINT
,
278 G_TYPE_UINT
, G_TYPE_UINT
, G_TYPE_UINT
,
284 nice_agent_init (NiceAgent
*agent
)
286 agent
->next_candidate_id
= 1;
287 agent
->next_stream_id
= 1;
293 * @factory: a NiceUDPSocketFactory used for allocating sockets
295 * Create a new NiceAgent.
297 * Returns: the new agent
300 nice_agent_new (NiceUDPSocketFactory
*factory
)
302 return g_object_new (NICE_TYPE_AGENT
,
303 "socket-factory", factory
,
309 nice_agent_get_property (
315 NiceAgent
*agent
= NICE_AGENT (object
);
319 case PROP_SOCKET_FACTORY
:
320 g_value_set_pointer (value
, agent
->socket_factory
);
324 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
330 nice_agent_set_property (
336 NiceAgent
*agent
= NICE_AGENT (object
);
340 case PROP_SOCKET_FACTORY
:
341 agent
->socket_factory
= g_value_get_pointer (value
);
345 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
351 nice_agent_add_local_host_candidate (
355 NiceAddress
*address
)
358 NiceCandidate
*candidate
;
359 Component
*component
;
361 if (!find_component (agent
, stream_id
, component_id
, NULL
, &component
))
364 candidate
= nice_candidate_new (NICE_CANDIDATE_TYPE_HOST
);
365 candidate
->id
= agent
->next_candidate_id
++;
366 candidate
->stream_id
= stream_id
;
367 candidate
->component_id
= component_id
;
368 candidate
->addr
= *address
;
369 candidate
->base_addr
= *address
;
370 component
->local_candidates
= g_slist_append (component
->local_candidates
,
373 /* generate username/password */
374 rng
= nice_rng_new ();
375 nice_rng_generate_bytes_print (rng
, 8, candidate
->username
);
376 nice_rng_generate_bytes_print (rng
, 8, candidate
->password
);
379 /* allocate socket */
380 /* XXX: handle error */
381 if (!nice_udp_socket_factory_make (agent
->socket_factory
,
382 &(candidate
->sock
), address
))
383 g_assert_not_reached ();
385 candidate
->addr
= candidate
->sock
.addr
;
386 candidate
->base_addr
= candidate
->sock
.addr
;
391 * nice_agent_add_stream:
392 * @agent: a NiceAgent
393 * @handle_recv: a function called when the stream recieves data
394 * @handle_recv_data: data passed as last parameter to @handle_recv
396 * Add a data stream to @agent.
398 * Returns: the ID of the new stream
401 nice_agent_add_stream (
408 g_assert (n_components
== 1);
409 stream
= stream_new ();
410 stream
->id
= agent
->next_stream_id
++;
411 agent
->streams
= g_slist_append (agent
->streams
, stream
);
413 /* generate a local host candidate for each local address */
415 for (i
= agent
->local_addresses
; i
; i
= i
->next
)
417 NiceAddress
*addr
= i
->data
;
419 nice_agent_add_local_host_candidate (agent
, stream
->id
,
420 stream
->component
->id
, addr
);
422 /* XXX: need to check for redundant candidates? */
423 /* later: send STUN requests to obtain server-reflexive candidates */
431 * nice_agent_remove_stream:
432 * @agent: a NiceAgent
433 * @stream_id: the ID of the stream to remove
436 nice_agent_remove_stream (
440 /* note that streams/candidates can be in use by other threads */
444 stream
= find_stream (agent
, stream_id
);
451 stream_free (stream
);
452 agent
->streams
= g_slist_remove (agent
->streams
, stream
);
457 * nice_agent_add_local_address:
458 * @agent: A NiceAgent
459 * @addr: the address of a local IP interface
461 * Inform the agent of the presence of an address that a local network
462 * interface is bound to.
465 nice_agent_add_local_address (NiceAgent
*agent
, NiceAddress
*addr
)
469 dup
= nice_address_dup (addr
);
471 agent
->local_addresses
= g_slist_append (agent
->local_addresses
, dup
);
473 /* XXX: Should we generate local candidates for existing streams at this
474 * point, or require that local addresses are set before media streams are
480 * nice_agent_add_remote_candidate
481 * @agent: a NiceAgent
482 * @stream_id: the ID of the stream the candidate is for
483 * @component_id: the ID of the component the candidate is for
484 * @type: the type of the new candidate
485 * @addr: the new candidate's IP address
486 * @port: the new candidate's port
487 * @username: the new candidate's username
488 * @password: the new candidate's password
490 * Add a candidate our peer has informed us about to the agent's list.
493 nice_agent_add_remote_candidate (
497 NiceCandidateType type
,
499 const gchar
*username
,
500 const gchar
*password
)
502 NiceCandidate
*candidate
;
503 Component
*component
;
505 if (!find_component (agent
, stream_id
, component_id
, NULL
, &component
))
508 candidate
= nice_candidate_new (type
);
509 candidate
->stream_id
= stream_id
;
510 candidate
->component_id
= component_id
;
511 /* XXX: do remote candidates need IDs? */
513 candidate
->addr
= *addr
;
514 strncpy (candidate
->username
, username
, sizeof (candidate
->username
));
515 strncpy (candidate
->password
, password
, sizeof (candidate
->password
));
517 component
->remote_candidates
= g_slist_append (component
->remote_candidates
,
520 /* later: for each component, generate a new check with the new candidate */
525 static NiceCandidate
*
526 _local_candidate_lookup (NiceAgent
*agent
, guint candidate_id
)
530 for (i
= agent
->local_candidates
; i
; i
= i
->next
)
532 NiceCandidate
*c
= i
->data
;
534 if (c
->id
== candidate_id
)
543 static NiceCandidate
*
544 find_candidate_by_fd (Component
*component
, guint fd
)
548 for (i
= component
->local_candidates
; i
; i
= i
->next
)
550 NiceCandidate
*c
= i
->data
;
552 if (c
->sock
.fileno
== fd
)
561 _handle_stun_binding_request (
564 Component
*component
,
565 NiceCandidate
*local
,
570 StunAttribute
**attr
;
571 gchar
*username
= NULL
;
572 NiceCandidate
*remote
= NULL
;
574 /* msg should have either:
577 * username = local candidate username + remote candidate username
579 * username = local candidate username + ":" + remote candidate username
580 * password = local candidate pwd
581 * priority = priority to use if a new candidate is generated
585 * - "local"/"remote" are from the perspective of the receiving side
586 * - the remote candidate username is not necessarily unique; Jingle seems
587 * to always generate a unique username/password for each candidate, but
588 * ICE makes no guarantees
590 * There are three cases we need to deal with:
592 * - valid username with a known address
594 * - valid username with an unknown address
596 * --> later: create new remote candidate
602 for (attr
= msg
->attributes
; *attr
; attr
++)
603 if ((*attr
)->type
== STUN_ATTRIBUTE_USERNAME
)
605 username
= (*attr
)->username
;
609 if (username
== NULL
)
610 /* no username attribute found */
613 /* validate username */
614 /* XXX: Should first try and find a remote candidate with a matching
615 * transport address, and fall back to matching on username only after that.
616 * That way, we know to always generate a new remote candidate if the
617 * transport address didn't match.
620 for (i
= component
->remote_candidates
; i
; i
= i
->next
)
627 g_debug ("uname check: %s :: %s -- %s", username
, local
->username
,
631 if (!g_str_has_prefix (username
, local
->username
))
634 len
= strlen (local
->username
);
636 if (0 != strcmp (username
+ len
, remote
->username
))
640 /* usernames match; check address */
642 if (rtmp
->addr
.addr_ipv4
== ntohs (from
.sin_addr
.s_addr
) &&
643 rtmp
->port
== ntohl (from
.sin_port
))
645 /* this is a candidate we know about, just send a reply */
646 /* is candidate pair active now? */
655 /* username is not valid */
664 ip
= nice_address_to_string (&remote
->addr
);
665 g_debug ("s%d:%d: got valid connectivity check for candidate %d (%s:%d)",
666 stream
->id
, component
->id
, remote
->id
, ip
, remote
->addr
.port
);
671 /* update candidate/peer affinity */
672 /* Note that @from might be different to @remote->addr; for ICE, this
673 * (always?) creates a new peer-reflexive remote candidate (§7.2).
675 /* XXX: test case where @from != @remote->addr. */
677 component
->active_candidate
= local
;
678 component
->peer_addr
= from
;
680 /* send STUN response */
683 StunMessage
*response
;
687 response
= stun_message_new (STUN_MESSAGE_BINDING_RESPONSE
,
688 msg
->transaction_id
, 2);
689 response
->attributes
[0] = stun_attribute_mapped_address_new (
690 from
.addr_ipv4
, from
.port
);
691 response
->attributes
[1] = stun_attribute_username_new (username
);
692 len
= stun_message_pack (response
, &packed
);
693 nice_udp_socket_send (&local
->sock
, &from
, len
, packed
);
696 stun_message_free (response
);
699 /* send reciprocal ("triggered") connectivity check */
700 /* XXX: possibly we shouldn't do this if we're being an ICE Lite agent */
709 extra
= stun_message_new (STUN_MESSAGE_BINDING_REQUEST
,
712 username
= g_strconcat (remote
->username
, local
->username
, NULL
);
713 extra
->attributes
[0] = stun_attribute_username_new (username
);
716 rng
= nice_rng_new ();
717 nice_rng_generate_bytes (rng
, 16, extra
->transaction_id
);
720 len
= stun_message_pack (extra
, &packed
);
721 nice_udp_socket_send (&local
->sock
, &from
, len
, packed
);
724 stun_message_free (extra
);
727 /* emit component-state-changed(connected) */
728 /* XXX: probably better do this when we get the binding response */
731 if (component
->state
!= NICE_COMPONENT_STATE_CONNECTED
)
733 component
->state
= NICE_COMPONENT_STATE_CONNECTED
;
734 g_signal_emit (agent
, signals
[SIGNAL_COMPONENT_STATE_CHANGED
], 0,
735 stream
->id
, component
->id
, component
->state
);
747 ip
= nice_address_to_string (&remote
->addr
);
749 "s%d:%d: got invalid connectivity check for candidate %d (%s:%d)",
750 stream
->id
, component
->id
, remote
->id
, ip
, remote
->addr
.port
);
755 /* XXX: add ERROR-CODE parameter */
758 StunMessage
*response
;
762 response
= stun_message_new (STUN_MESSAGE_BINDING_ERROR_RESPONSE
,
763 msg
->transaction_id
, 0);
764 len
= stun_message_pack (response
, &packed
);
765 nice_udp_socket_send (&local
->sock
, &from
, len
, packed
);
768 stun_message_free (response
);
771 /* XXX: we could be clever and keep around STUN packets that we couldn't
772 * validate, then re-examine them when we get new remote candidates -- would
773 * this fix some timing problems (i.e. TCP being slower than UDP)
775 /* XXX: if the peer is the controlling agent, it may include a USE-CANDIDATE
776 * attribute in the binding request
785 Component
*component
,
786 NiceCandidate
*local
,
792 case STUN_MESSAGE_BINDING_REQUEST
:
793 _handle_stun_binding_request (agent
, stream
, component
, local
, from
,
796 case STUN_MESSAGE_BINDING_RESPONSE
:
797 /* XXX: check it matches a request we sent */
800 /* a message type we don't know how to handle */
801 /* XXX: send error response */
811 Component
*component
,
812 NiceCandidate
*candidate
,
819 len
= nice_udp_socket_recv (&(candidate
->sock
), &from
,
825 g_assert (len
< buf_len
);
827 /* XXX: verify sender; maybe:
829 * if (candidate->other != NULL)
831 * if (from != candidate->other.addr)
832 * // ignore packet from unexpected sender
837 * // go through remote candidates, looking for one matching packet from
838 * // address; if found, assign it to candidate->other and call handler,
839 * // otherwise ignore it
842 * Perhaps remote socket affinity is superfluous and all we need is the
844 * Perhaps we should also check whether this candidate is supposed to be
848 /* The top two bits of an RTP message are the version number; the current
849 * version number is 2. The top two bits of a STUN message are always 0.
852 if ((buf
[0] & 0xc0) == 0x80)
857 else if ((buf
[0] & 0xc0) == 0)
859 /* looks like a STUN message (connectivity check) */
860 /* connectivity checks are described in ICE-13 §7. */
863 msg
= stun_message_unpack (len
, buf
);
867 _handle_stun (agent
, stream
, component
, candidate
, from
, msg
);
868 stun_message_free (msg
);
872 /* anything else is ignored */
879 * @agent: a NiceAgent
880 * @stream_id: the ID of the stream to recieve data from
881 * @component_id: the ID of the component to receive data from
882 * @buf_len: the size of @buf
883 * @buf: the buffer to read data into
885 * Recieve data on a particular component.
887 * Returns: the amount of data read into @buf
903 Component
*component
;
905 if (!find_component (agent
, stream_id
, component_id
, &stream
, &component
))
910 for (i
= component
->local_candidates
; i
; i
= i
->next
)
912 NiceCandidate
*candidate
= i
->data
;
914 FD_SET (candidate
->sock
.fileno
, &fds
);
915 max_fd
= MAX (candidate
->sock
.fileno
, max_fd
);
918 /* Loop on candidate sockets until we find one that has non-STUN data
924 num_readable
= select (max_fd
+ 1, &fds
, NULL
, NULL
, NULL
);
925 g_assert (num_readable
>= 0);
927 if (num_readable
> 0)
931 for (j
= 0; j
<= max_fd
; j
++)
932 if (FD_ISSET (j
, &fds
))
934 NiceCandidate
*candidate
;
936 candidate
= find_candidate_by_fd (component
, j
);
937 g_assert (candidate
);
938 len
= _nice_agent_recv (agent
, stream
, component
, candidate
,
947 g_assert_not_reached ();
952 nice_agent_recv_sock (
960 NiceCandidate
*candidate
;
962 Component
*component
;
964 if (!find_component (agent
, stream_id
, component_id
, &stream
, &component
))
967 candidate
= find_candidate_by_fd (component
, sock
);
968 g_assert (candidate
);
970 return _nice_agent_recv (agent
, stream
, stream
->component
,
971 candidate
, buf_len
, buf
);
976 * nice_agent_poll_read:
977 * @agent: A NiceAgent
978 * @other_fds: A GSList of other file descriptors to poll
980 * Polls the agent's sockets until at least one of them is readable, and
981 * additionally if @other_fds is not NULL, polls those for readability too.
982 * @other_fds should contain the file descriptors directly, i.e. using
985 * Returns: A list of file descriptors from @other_fds that are readable
988 nice_agent_poll_read (
991 NiceAgentRecvFunc func
,
1003 for (i
= agent
->streams
; i
; i
= i
->next
)
1006 Stream
*stream
= i
->data
;
1007 Component
*component
= stream
->component
;
1009 for (j
= component
->local_candidates
; j
; j
= j
->next
)
1011 NiceCandidate
*candidate
= j
->data
;
1013 FD_SET (candidate
->sock
.fileno
, &fds
);
1014 max_fd
= MAX (candidate
->sock
.fileno
, max_fd
);
1018 for (i
= other_fds
; i
; i
= i
->next
)
1022 fileno
= GPOINTER_TO_UINT (i
->data
);
1023 FD_SET (fileno
, &fds
);
1024 max_fd
= MAX (fileno
, max_fd
);
1027 num_readable
= select (max_fd
+ 1, &fds
, NULL
, NULL
, NULL
);
1029 if (num_readable
< 1)
1030 /* none readable, or error */
1033 for (j
= 0; j
<= max_fd
; j
++)
1034 if (FD_ISSET (j
, &fds
))
1036 if (g_slist_find (other_fds
, GUINT_TO_POINTER (j
)))
1037 ret
= g_slist_append (ret
, GUINT_TO_POINTER (j
));
1040 NiceCandidate
*candidate
= NULL
;
1045 for (i
= agent
->streams
; i
; i
= i
->next
)
1047 Stream
*s
= i
->data
;
1048 Component
*c
= s
->component
;
1050 candidate
= find_candidate_by_fd (c
, j
);
1052 if (candidate
!= NULL
)
1056 if (candidate
== NULL
)
1059 stream
= find_stream (agent
, candidate
->stream_id
);
1064 len
= _nice_agent_recv (agent
, stream
, stream
->component
,
1065 candidate
, 1024, buf
);
1067 if (len
&& func
!= NULL
)
1068 func (agent
, stream
->id
, candidate
->component_id
, len
, buf
,
1086 Component
*component
;
1088 stream
= find_stream (agent
, stream_id
);
1089 component
= stream
->component
;
1091 if (component
->active_candidate
!= NULL
)
1093 NiceUDPSocket
*sock
;
1097 g_debug ("s%d:%d: sending %d bytes to %08x:%d", stream_id
, component_id
,
1098 len
, component
->peer_addr
->addr_ipv4
, component
->peer_addr
->port
);
1101 sock
= &component
->active_candidate
->sock
;
1102 addr
= &component
->peer_addr
;
1103 nice_udp_socket_send (sock
, addr
, len
, buf
);
1109 * Set the STUN server from which to obtain server-reflexive candidates.
1113 nice_agent_set_stun_server (
1122 * nice_agent_get_local_candidates:
1123 * @agent: A NiceAgent
1125 * The caller owns the returned GSList but not the candidates contained within
1128 * Returns: a GSList of local candidates belonging to @agent
1131 nice_agent_get_local_candidates (
1135 { Component
*component
;
1137 if (!find_component (agent
, stream_id
, component_id
, NULL
, &component
))
1140 return g_slist_copy (component
->local_candidates
);
1145 * nice_agent_get_remote_candidates:
1146 * @agent: A NiceAgent
1148 * The caller owns the returned GSList but not the candidates contained within
1151 * Returns: a GSList of remote candidates belonging to @agent
1154 nice_agent_get_remote_candidates (
1159 Component
*component
;
1161 if (!find_component (agent
, stream_id
, component_id
, NULL
, &component
))
1164 return g_slist_copy (component
->remote_candidates
);
1169 nice_agent_dispose (GObject
*object
)
1172 NiceAgent
*agent
= NICE_AGENT (object
);
1174 for (i
= agent
->local_addresses
; i
; i
= i
->next
)
1176 NiceAddress
*a
= i
->data
;
1178 nice_address_free (a
);
1181 g_slist_free (agent
->local_addresses
);
1182 agent
->local_addresses
= NULL
;
1184 for (i
= agent
->streams
; i
; i
= i
->next
)
1186 Stream
*s
= i
->data
;
1191 g_slist_free (agent
->streams
);
1192 agent
->streams
= NULL
;
1194 if (G_OBJECT_CLASS (nice_agent_parent_class
)->dispose
)
1195 G_OBJECT_CLASS (nice_agent_parent_class
)->dispose (object
);
1199 typedef struct _IOCtx IOCtx
;
1205 Component
*component
;
1206 NiceCandidate
*candidate
;
1214 Component
*component
,
1215 NiceCandidate
*candidate
)
1219 ctx
= g_slice_new0 (IOCtx
);
1221 ctx
->stream
= stream
;
1222 ctx
->component
= component
;
1223 ctx
->candidate
= candidate
;
1229 io_ctx_free (IOCtx
*ctx
)
1231 g_slice_free (IOCtx
, ctx
);
1236 nice_agent_g_source_cb (
1239 GIOCondition condition
,
1242 /* return value is whether to keep the source */
1245 NiceAgent
*agent
= ctx
->agent
;
1246 Stream
*stream
= ctx
->stream
;
1247 Component
*component
= ctx
->component
;
1248 NiceCandidate
*candidate
= ctx
->candidate
;
1252 len
= _nice_agent_recv (agent
, stream
, component
, candidate
, 1024,
1256 agent
->read_func (agent
, candidate
->stream_id
, candidate
->component_id
,
1257 len
, buf
, agent
->read_func_data
);
1264 nice_agent_main_context_attach (
1267 NiceAgentRecvFunc func
,
1272 if (agent
->main_context_set
)
1275 /* attach candidates */
1277 for (i
= agent
->streams
; i
; i
= i
->next
)
1280 Stream
*stream
= i
->data
;
1281 Component
*component
= stream
->component
;
1283 for (j
= component
->local_candidates
; j
; j
= j
->next
)
1285 NiceCandidate
*candidate
= j
->data
;
1290 io
= g_io_channel_unix_new (candidate
->sock
.fileno
);
1291 source
= g_io_create_watch (io
, G_IO_IN
);
1292 ctx
= io_ctx_new (agent
, stream
, component
, candidate
);
1293 g_source_set_callback (source
, (GSourceFunc
) nice_agent_g_source_cb
,
1294 ctx
, (GDestroyNotify
) io_ctx_free
);
1295 g_source_attach (source
, NULL
);
1296 candidate
->source
= source
;
1300 agent
->main_context
= ctx
;
1301 agent
->main_context_set
= TRUE
;
1302 agent
->read_func
= func
;
1303 agent
->read_func_data
= data
;