static void infd_xmpp_server_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec) { InfdXmppServer* xmpp; InfdXmppServerPrivate* priv; xmpp = INFD_XMPP_SERVER(object); priv = INFD_XMPP_SERVER_PRIVATE(xmpp); switch(prop_id) { case PROP_TCP: infd_xmpp_server_set_tcp( xmpp, INFD_TCP_SERVER(g_value_get_object(value)) ); break; case PROP_LOCAL_HOSTNAME: g_free(priv->local_hostname); priv->local_hostname = g_value_dup_string(value); if(priv->local_hostname == NULL) priv->local_hostname = g_strdup(g_get_host_name()); break; case PROP_CREDENTIALS: if(priv->tls_creds != NULL) inf_certificate_credentials_unref(priv->tls_creds); priv->tls_creds = g_value_dup_boxed(value); break; case PROP_SASL_CONTEXT: if(priv->sasl_own_context != NULL) { inf_sasl_context_unref(priv->sasl_own_context); priv->sasl_own_context = NULL; } if(priv->sasl_context != NULL) inf_sasl_context_unref(priv->sasl_context); priv->sasl_context = g_value_dup_boxed(value); infd_xmpp_server_setup_own_sasl_context(xmpp); break; case PROP_SASL_MECHANISMS: g_free(priv->sasl_mechanisms); priv->sasl_mechanisms = g_value_dup_string(value); break; case PROP_SECURITY_POLICY: infd_xmpp_server_set_security_policy(xmpp, g_value_get_enum(value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } }
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); } } }