コード例 #1
0
static gboolean
inf_tcp_connection_addr_info(InfNativeSocket socket,
                             gboolean local,
                             InfIpAddress** address,
                             guint* port,
                             GError** error)
{
  union {
    struct sockaddr in_generic;
    struct sockaddr_in in;
    struct sockaddr_in6 in6;
  } native_addr;
  socklen_t len;
  int res;
  int code;

  len = sizeof(native_addr);

  if(local == TRUE)
    res = getsockname(socket, &native_addr.in_generic, &len);
  else
    res = getpeername(socket, &native_addr.in_generic, &len);

  if(res == -1)
  {
    code = INF_NATIVE_SOCKET_LAST_ERROR;
    inf_native_socket_make_error(code, error);
    return FALSE;
  }

  switch(native_addr.in_generic.sa_family)
  {
  case AF_INET:
    if(address != NULL)
      *address = inf_ip_address_new_raw4(native_addr.in.sin_addr.s_addr);
    if(port != NULL)
      *port = ntohs(native_addr.in.sin_port);
    break;
  case AF_INET6:
    if(address != NULL)
      *address = inf_ip_address_new_raw6(native_addr.in6.sin6_addr.s6_addr);
    if(port != NULL)
      *port = ntohs(native_addr.in6.sin6_port);
    break;
  default:
    g_assert_not_reached();
    break;
  }

  return TRUE;
}
コード例 #2
0
ファイル: server.cpp プロジェクト: aburgm/gobby
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);
		}
	}
}