static void notify_status_cb(InfTcpConnection* connection, const gchar* property, gpointer user_data) { InfTcpConnectionStatus status; InfIpAddress* addr; guint port; gchar* addr_str; g_object_get( G_OBJECT(connection), "status", &status, "remote-address", &addr, "remote-port", &port, NULL ); addr_str = inf_ip_address_to_string(addr); inf_ip_address_free(addr); switch(status) { case INF_TCP_CONNECTION_CONNECTING: printf("Connecting to %s:%u\n", addr_str, port); break; case INF_TCP_CONNECTION_CONNECTED: printf("Connected to %s:%u\n", addr_str, port); g_object_get( G_OBJECT(connection), "local-address", &addr, "local-port", &port, NULL ); g_free(addr_str); addr_str = inf_ip_address_to_string(addr); inf_ip_address_free(addr); printf("Connected from %s:%u\n", addr_str, port); inf_tcp_connection_send(connection, "Hello, World!\n", 14); break; case INF_TCP_CONNECTION_CLOSED: printf("Connection to %s:%u closed\n", addr_str, port); if(inf_standalone_io_loop_running(INF_STANDALONE_IO(user_data))) inf_standalone_io_loop_quit(INF_STANDALONE_IO(user_data)); break; default: g_assert_not_reached(); break; } g_free(addr_str); }
/* Creates a new TCP connection from an accepted socket. This is only used * by InfdTcpServer and should not be considered regular API. Do not call * this function. Language bindings should not wrap it. */ InfTcpConnection* _inf_tcp_connection_accepted(InfIo* io, InfNativeSocket socket, InfIpAddress* address, guint port, const InfKeepalive* keepalive, GError** error) { InfTcpConnection* connection; InfTcpConnectionPrivate* priv; int errcode; g_return_val_if_fail(INF_IS_IO(io), NULL); g_return_val_if_fail(socket != INVALID_SOCKET, NULL); g_return_val_if_fail(address != NULL, NULL); g_return_val_if_fail(keepalive != NULL, NULL); if(inf_tcp_connection_configure_socket(socket, keepalive, error) != TRUE) return NULL; g_return_val_if_fail(address != NULL, NULL); g_return_val_if_fail(port != 0, NULL); connection = inf_tcp_connection_new(io, address, port); inf_ip_address_free(address); priv = INF_TCP_CONNECTION_PRIVATE(connection); priv->socket = socket; priv->keepalive = *keepalive; inf_tcp_connection_connected(connection); return connection; }
static void inf_tcp_connection_connected(InfTcpConnection* connection) { InfTcpConnectionPrivate* priv; priv = INF_TCP_CONNECTION_PRIVATE(connection); priv->status = INF_TCP_CONNECTION_CONNECTED; priv->front_pos = 0; priv->back_pos = 0; priv->events = INF_IO_INCOMING | INF_IO_ERROR; if(priv->watch == NULL) { priv->watch = inf_io_add_watch( priv->io, &priv->socket, priv->events, inf_tcp_connection_io, connection, NULL ); } else { inf_io_update_watch(priv->io, priv->watch, priv->events); } g_object_freeze_notify(G_OBJECT(connection)); /* Update adresses from resolver */ if(priv->resolver != NULL) { if(priv->remote_address != NULL) inf_ip_address_free(priv->remote_address); priv->remote_address = inf_ip_address_copy( inf_name_resolver_get_address(priv->resolver, priv->resolver_index) ); priv->remote_port = inf_name_resolver_get_port(priv->resolver, priv->resolver_index); g_object_notify(G_OBJECT(connection), "remote-address"); g_object_notify(G_OBJECT(connection), "remote-port"); priv->resolver_index = 0; } g_object_notify(G_OBJECT(connection), "status"); g_object_notify(G_OBJECT(connection), "local-address"); g_object_notify(G_OBJECT(connection), "local-port"); g_object_thaw_notify(G_OBJECT(connection)); }
static void conn_received_cb(InfTcpConnection* connection, gconstpointer data, guint len, gpointer user_data) { InfIpAddress* addr; gchar* str; g_object_get(G_OBJECT(connection), "remote-address", &addr, NULL); str = inf_ip_address_to_string(addr); inf_ip_address_free(addr); printf("Data from %s: %.*s\n", str, (int)len, (const char*)data); g_free(str); }
static void conn_error_cb(InfTcpConnection* connection, GError* error, gpointer user_data) { InfIpAddress* addr; gchar* str; g_object_get(G_OBJECT(connection), "remote-address", &addr, NULL); str = inf_ip_address_to_string(addr); inf_ip_address_free(addr); printf("Error from %s: %s\n", str, error->message); g_free(str); g_object_unref(G_OBJECT(connection)); }
static void infd_xmpp_server_new_connection_cb(InfdTcpServer* tcp_server, InfTcpConnection* tcp_connection, gpointer user_data) { InfdXmppServer* xmpp_server; InfdXmppServerPrivate* priv; InfXmppConnection* xmpp_connection; InfIpAddress* addr; gchar* addr_str; xmpp_server = INFD_XMPP_SERVER(user_data); priv = INFD_XMPP_SERVER_PRIVATE(xmpp_server); /* TODO: We could perform a reverse DNS lookup to find the client hostname * here. */ g_object_get(G_OBJECT(tcp_connection), "remote-address", &addr, NULL); addr_str = inf_ip_address_to_string(addr); inf_ip_address_free(addr); xmpp_connection = inf_xmpp_connection_new( tcp_connection, INF_XMPP_CONNECTION_SERVER, priv->local_hostname, addr_str, priv->security_policy, priv->tls_creds, priv->sasl_context, priv->sasl_own_context != NULL ? "ANONYMOUS" : priv->sasl_mechanisms ); g_free(addr_str); /* We could, alternatively, keep the connection around until authentication * has completed and emit the new_connection signal after that, to guarantee * that the connection is open when new_connection is emitted. */ infd_xml_server_new_connection( INFD_XML_SERVER(xmpp_server), INF_XML_CONNECTION(xmpp_connection) ); g_object_unref(G_OBJECT(xmpp_connection)); }
static void inf_tcp_connection_finalize(GObject* object) { InfTcpConnection* connection; InfTcpConnectionPrivate* priv; connection = INF_TCP_CONNECTION(object); priv = INF_TCP_CONNECTION_PRIVATE(connection); if(priv->remote_address != NULL) inf_ip_address_free(priv->remote_address); if(priv->socket != INVALID_SOCKET) closesocket(priv->socket); g_free(priv->queue); G_OBJECT_CLASS(inf_tcp_connection_parent_class)->finalize(object); }
static void new_connection_cb(InfdTcpServer* server, InfTcpConnection* connection, gpointer user_data) { InfIpAddress* addr; gchar* str; g_object_get(G_OBJECT(connection), "remote-address", &addr, NULL); str = inf_ip_address_to_string(addr); inf_ip_address_free(addr); printf("Connection from %s\n", str); g_free(str); g_signal_connect( G_OBJECT(connection), "received", G_CALLBACK(conn_received_cb), NULL ); g_signal_connect( G_OBJECT(connection), "error", G_CALLBACK(conn_error_cb), NULL ); g_signal_connect( G_OBJECT(connection), "notify::status", G_CALLBACK(conn_notify_status_cb), NULL ); g_object_ref(G_OBJECT(connection)); }
static void notify_status_cb(InfdTcpServer* server, GParamSpec* pspec, gpointer user_data) { InfdTcpServerStatus status; InfIpAddress* addr; guint port; gchar* addr_str; g_object_get( G_OBJECT(server), "status", &status, "local-address", &addr, "local-port", &port, NULL ); addr_str = inf_ip_address_to_string(addr); inf_ip_address_free(addr); switch(status) { case INFD_TCP_SERVER_CLOSED: printf("Server closed\n"); break; case INFD_TCP_SERVER_OPEN: printf("Server listening on %s:%u\n", addr_str, port); break; default: g_assert_not_reached(); break; } g_free(addr_str); }
static void conn_notify_status_cb(InfTcpConnection* connection, GParamSpec* spec, gpointer user_data) { InfIpAddress* addr; InfTcpConnectionStatus status; gchar* str; g_object_get( G_OBJECT(connection), "remote-address", &addr, "status", &status, NULL ); str = inf_ip_address_to_string(addr); inf_ip_address_free(addr); if(status == INF_TCP_CONNECTION_CLOSED) printf("Connection close from %s\n", str); g_free(str); }
static void bookmark_added (GeditCollaborationWindowHelper *helper, GeditCollaborationBookmark *bookmark) { GResolver *resolver = g_resolver_get_default (); GList *addresses; InfTcpConnection *tcp; InfIpAddress *ipaddress; InfXmppConnection *connection; gchar *ipaddr; NameInfo *info; GeditCollaborationUser *user; /* TODO: make this asynchronous and be smarter about it */ addresses = g_resolver_lookup_by_name (resolver, gedit_collaboration_bookmark_get_host (bookmark), NULL, NULL); if (!addresses) { return; } ipaddr = g_inet_address_to_string ((GInetAddress *)addresses->data); g_resolver_free_addresses (addresses); ipaddress = inf_ip_address_new_from_string (ipaddr); g_free (ipaddr); tcp = inf_tcp_connection_new (helper->priv->io, ipaddress, (guint)gedit_collaboration_bookmark_get_port (bookmark)); user = gedit_collaboration_bookmark_get_user (bookmark); connection = inf_xmpp_connection_new (tcp, INF_XMPP_CONNECTION_CLIENT, NULL, gedit_collaboration_bookmark_get_host (bookmark), INF_XMPP_CONNECTION_SECURITY_BOTH_PREFER_TLS, helper->priv->certificate_credentials, gedit_collaboration_user_get_sasl_context (user), "ANONYMOUS PLAIN"); g_signal_connect (user, "request-password", G_CALLBACK (user_request_password), helper); inf_gtk_browser_store_add_connection (helper->priv->browser_store, INF_XML_CONNECTION (connection), gedit_collaboration_bookmark_get_name (bookmark)); g_object_set_data (G_OBJECT (connection), BOOKMARK_DATA_KEY, bookmark); inf_ip_address_free (ipaddress); g_object_unref (tcp); info = g_slice_new (NameInfo); info->helper = helper; info->connection = INF_XML_CONNECTION (connection); g_signal_connect_data (bookmark, "notify::name", G_CALLBACK (on_bookmark_name_changed), info, (GClosureNotify)name_info_free, 0); }
static void inf_tcp_connection_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec) { InfTcpConnection* connection; InfTcpConnectionPrivate* priv; #ifndef G_OS_WIN32 const gchar* device_string; unsigned int new_index; #endif GError* error; connection = INF_TCP_CONNECTION(object); priv = INF_TCP_CONNECTION_PRIVATE(connection); switch(prop_id) { case PROP_IO: g_assert(priv->status == INF_TCP_CONNECTION_CLOSED); if(priv->io != NULL) g_object_unref(G_OBJECT(priv->io)); priv->io = INF_IO(g_value_dup_object(value)); break; case PROP_RESOLVER: g_assert(priv->status == INF_TCP_CONNECTION_CLOSED); inf_tcp_connection_set_resolver( connection, INF_NAME_RESOLVER(g_value_get_object(value)) ); break; case PROP_KEEPALIVE: error = NULL; inf_tcp_connection_set_keepalive( connection, (InfKeepalive*)g_value_get_boxed(value), &error ); if(error != NULL) { g_warning("Failed to set keepalive settings: %s\n", error->message); g_error_free(error); } break; case PROP_REMOTE_ADDRESS: g_assert(priv->status == INF_TCP_CONNECTION_CLOSED); if(priv->remote_address != NULL) inf_ip_address_free(priv->remote_address); priv->remote_address = (InfIpAddress*)g_value_dup_boxed(value); break; case PROP_REMOTE_PORT: g_assert(priv->status == INF_TCP_CONNECTION_CLOSED); priv->remote_port = g_value_get_uint(value); break; case PROP_DEVICE_INDEX: g_assert(priv->status == INF_TCP_CONNECTION_CLOSED); /* TODO: Verify that such a device exists */ priv->device_index = g_value_get_uint(value); g_object_notify(G_OBJECT(object), "device-name"); break; case PROP_DEVICE_NAME: #ifdef G_OS_WIN32 /* TODO: We can probably implement this using GetInterfaceInfo() */ g_warning("The device-name property is not implemented on Win32"); #else g_assert(priv->status == INF_TCP_CONNECTION_CLOSED); device_string = g_value_get_string(value); if(device_string == NULL) priv->device_index = 0; new_index = if_nametoindex(device_string); if(new_index == 0) { g_warning(_("Interface `%s' does not exist"), device_string); } else { priv->device_index = new_index; g_object_notify(G_OBJECT(object), "device-index"); } #endif break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } }
int main(int argc, char* argv[]) { InfIpAddress* addr; InfStandaloneIo* io; InfTcpConnection* connection; GError* error; g_type_init(); addr = inf_ip_address_new_loopback4(); io = inf_standalone_io_new(); error = NULL; connection = g_object_new( INF_TYPE_TCP_CONNECTION, "io", io, "remote-address", addr, "remote-port", 5223, NULL ); inf_ip_address_free(addr); g_signal_connect( G_OBJECT(connection), "received", G_CALLBACK(received_cb), io ); g_signal_connect( G_OBJECT(connection), "sent", G_CALLBACK(sent_cb), io ); g_signal_connect( G_OBJECT(connection), "error", G_CALLBACK(error_cb), io ); g_signal_connect( G_OBJECT(connection), "notify::status", G_CALLBACK(notify_status_cb), io ); if(inf_tcp_connection_open(connection, &error) == FALSE) { fprintf(stderr, "Could not open connection: %s\n", error->message); g_error_free(error); } else { inf_standalone_io_loop(io); } g_object_unref(G_OBJECT(io)); g_object_unref(G_OBJECT(connection)); return 0; }
static void inf_test_mass_join_connect(InfTestMassJoin* massjoin, const char* hostname, guint port, const char* document, const char* username) { InfIpAddress* addr; InfTcpConnection* tcp; InfXmppConnection* xmpp; InfTestMassJoiner* joiner; InfXmlConnection* xml; GError* error; addr = inf_ip_address_new_from_string(hostname); tcp = inf_tcp_connection_new(massjoin->io, addr, port); xmpp = inf_xmpp_connection_new( tcp, INF_XMPP_CONNECTION_CLIENT, g_get_host_name(), hostname, INF_XMPP_CONNECTION_SECURITY_BOTH_PREFER_TLS, NULL, NULL, NULL ); joiner = g_slice_new(InfTestMassJoiner); joiner->communication_manager = inf_communication_manager_new(); joiner->browser = infc_browser_new( massjoin->io, joiner->communication_manager, INF_XML_CONNECTION(xmpp) ); joiner->session = NULL; joiner->document = g_strdup(document); joiner->username = g_strdup(username); g_object_unref(xmpp); g_object_unref(tcp); inf_ip_address_free(addr); massjoin->joiners = g_slist_prepend(massjoin->joiners, joiner); infc_browser_add_plugin(joiner->browser, &INF_TEST_MASS_JOIN_TEXT_PLUGIN); g_signal_connect( G_OBJECT(joiner->browser), "notify::status", G_CALLBACK(inf_test_mass_join_browser_notify_status_cb), massjoin ); error = NULL; xml = infc_browser_get_connection(joiner->browser); if(inf_xml_connection_open(xml, &error) == FALSE) { fprintf( stderr, "Joiner %s: Failed to connect to %s: %s\n", joiner->username, hostname, error->message ); g_error_free(error); massjoin->joiners = g_slist_remove(massjoin->joiners, joiner); if(massjoin->joiners == NULL) inf_standalone_io_loop_quit(INF_STANDALONE_IO(massjoin->io)); } }
static InfXmppConnection* inf_test_certificate_validate_setup_client(InfIo* io, const gchar* ca_file, const gchar* remote_hostname, GError** error) { InfIpAddress* addr; InfTcpConnection* conn; InfXmppConnection* xmpp; InfCertificateCredentials* creds; GPtrArray* cas; int res; guint i; creds = inf_certificate_credentials_new(); if(ca_file != NULL) { cas = inf_cert_util_read_certificate(ca_file, NULL, error); if(cas == NULL) { inf_certificate_credentials_unref(creds); return NULL; } res = gnutls_certificate_set_x509_trust( inf_certificate_credentials_get(creds), (gnutls_x509_crt_t*)cas->pdata, cas->len ); for(i = 0; i < cas->len; ++i) gnutls_x509_crt_deinit(cas->pdata[i]); g_ptr_array_free(cas, TRUE); } addr = inf_ip_address_new_loopback4(); conn = inf_tcp_connection_new(io, addr, 6524); inf_ip_address_free(addr); xmpp = inf_xmpp_connection_new( conn, INF_XMPP_CONNECTION_CLIENT, g_get_host_name(), remote_hostname, INF_XMPP_CONNECTION_SECURITY_ONLY_TLS, creds, NULL, NULL ); inf_certificate_credentials_unref(creds); if(inf_tcp_connection_open(conn, error) == FALSE) { g_object_unref(conn); g_object_unref(xmpp); return NULL; } g_object_unref(conn); return xmpp; }
int main(int argc, char* argv[]) { InfTestBrowser test; InfIpAddress* address; InfCommunicationManager* manager; InfTcpConnection* tcp_conn; GError* error; gnutls_global_init(); g_type_init(); test.io = inf_standalone_io_new(); #ifndef G_OS_WIN32 test.input_fd = STDIN_FILENO; #endif address = inf_ip_address_new_loopback4(); error = NULL; tcp_conn = inf_tcp_connection_new_and_open(INF_IO(test.io), address, inf_protocol_get_default_port(), &error); inf_ip_address_free(address); if(tcp_conn == NULL) { fprintf(stderr, "Could not open TCP connection: %s\n", error->message); g_error_free(error); } else { test.conn = inf_xmpp_connection_new( tcp_conn, INF_XMPP_CONNECTION_CLIENT, NULL, "localhost", INF_XMPP_CONNECTION_SECURITY_BOTH_PREFER_TLS, NULL, NULL, NULL ); g_object_unref(G_OBJECT(tcp_conn)); manager = inf_communication_manager_new(); test.browser = INF_BROWSER( infc_browser_new( INF_IO(test.io), manager, INF_XML_CONNECTION(test.conn) ) ); g_signal_connect_after( G_OBJECT(test.browser), "notify::status", G_CALLBACK(inf_test_browser_notify_status_cb), &test ); g_signal_connect( G_OBJECT(test.browser), "error", G_CALLBACK(inf_test_browser_error_cb), &test ); inf_standalone_io_loop(test.io); g_object_unref(G_OBJECT(manager)); g_object_unref(G_OBJECT(test.browser)); /* TODO: Wait until the XMPP connection is in status closed */ g_object_unref(G_OBJECT(test.conn)); } g_object_unref(G_OBJECT(test.io)); return 0; }
static void notify_status_cb(InfTcpConnection* connection, GParamSpec* pspec, gpointer user_data) { InfTcpConnectionStatus status; InfIpAddress* addr; guint port; InfNameResolver* resolver; gchar* addr_str_tmp; gchar* addr_str; g_object_get( G_OBJECT(connection), "status", &status, "remote-address", &addr, "remote-port", &port, "resolver", &resolver, NULL ); if(addr != NULL) { addr_str_tmp = inf_ip_address_to_string(addr); addr_str = g_strdup_printf("%s:%u", addr_str_tmp, port); g_free(addr_str_tmp); } else { g_object_get(G_OBJECT(resolver), "hostname", &addr_str, NULL); } if(addr != NULL) inf_ip_address_free(addr); if(resolver != NULL) g_object_unref(resolver); switch(status) { case INF_TCP_CONNECTION_CONNECTING: printf("Connecting to %s\n", addr_str); break; case INF_TCP_CONNECTION_CONNECTED: printf("Connected to %s\n", addr_str); g_object_get( G_OBJECT(connection), "local-address", &addr, "local-port", &port, NULL ); g_free(addr_str); addr_str = inf_ip_address_to_string(addr); inf_ip_address_free(addr); printf("Connected from %s:%u\n", addr_str, port); inf_tcp_connection_send(connection, "Hello, World!\n", 14); break; case INF_TCP_CONNECTION_CLOSED: printf("Connection to %s closed\n", addr_str); if(inf_standalone_io_loop_running(INF_STANDALONE_IO(user_data))) inf_standalone_io_loop_quit(INF_STANDALONE_IO(user_data)); break; default: g_assert_not_reached(); break; } g_free(addr_str); }
void Gobby::Server::open(unsigned int port, InfXmppConnectionSecurityPolicy security_policy, InfCertificateCredentials* creds, InfSaslContext* context, const char* sasl_mechanisms) { // If we can open one of tcp4 or tcp6 that's a success. InfdTcpServer* tcp4; InfdTcpServer* tcp6; // If the server is already open and we do not need to change the // port, then just change the credentials and SASL context without // doing anything else. if(is_open() && get_port() == port) { set_credentials(security_policy, creds); set_sasl_context(context, sasl_mechanisms); return; } static const guint8 ANY6_ADDR[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; InfIpAddress* any6 = inf_ip_address_new_raw6(ANY6_ADDR); tcp4 = INFD_TCP_SERVER(g_object_new( INFD_TYPE_TCP_SERVER, "io", m_io, "local-address", NULL, "local-port", port, NULL)); tcp6 = INFD_TCP_SERVER(g_object_new( INFD_TYPE_TCP_SERVER, "io", m_io, "local-address", any6, "local-port", port, NULL)); inf_ip_address_free(any6); if(!infd_tcp_server_open(tcp6, NULL)) { g_object_unref(tcp6); tcp6 = NULL; GError* error = NULL; if(!infd_tcp_server_open(tcp4, &error)) { g_object_unref(tcp4); const std::string message = error->message; g_error_free(error); throw std::runtime_error(message); } } else { if(!infd_tcp_server_open(tcp4, NULL)) { g_object_unref(tcp4); tcp4 = NULL; } } // We have the new server open, from this point on there is nothing // that can go wrong anymore. Therefore, close the old server and // take over the new one. if(is_open()) close(); InfXmppConnectionSecurityPolicy policy = INF_XMPP_CONNECTION_SECURITY_ONLY_UNSECURED; if(creds != NULL) policy = security_policy; if(tcp4) { m_xmpp4 = infd_xmpp_server_new( tcp4, security_policy, creds, context, sasl_mechanisms); g_object_unref(tcp4); } if(tcp6) { m_xmpp6 = infd_xmpp_server_new( tcp6, security_policy, creds, context, sasl_mechanisms); g_object_unref(tcp6); } if(m_pool) { if(m_xmpp4 != NULL) { infd_server_pool_add_server( m_pool, INFD_XML_SERVER(m_xmpp4)); infd_server_pool_add_local_publisher( m_pool, m_xmpp4, m_publisher); } if(m_xmpp6 != NULL) { infd_server_pool_add_server( m_pool, INFD_XML_SERVER(m_xmpp6)); infd_server_pool_add_local_publisher( m_pool, m_xmpp6, m_publisher); } } }