示例#1
0
dsk_boolean
dsk_ssl_stream_new         (DskSslStreamOptions   *options,
                            DskSslStream         **stream_out,
                            DskOctetSource       **source_out,
                            DskOctetSink         **sink_out,
                            DskError             **error)
{
  DskSslStream *stream;
  DskSslSink *sink;
  DskSslSource *source;

  if (sink_out == NULL || source_out == NULL)
    {
      dsk_set_error (error, "dsk_ssl_stream_new: sink/source");
      return DSK_FALSE;
    }

  sink = dsk_object_new (&dsk_ssl_sink_class);
  source = dsk_object_new (&dsk_ssl_source_class);
  stream = dsk_object_new (&dsk_ssl_stream_class);

  BIO *bio;
  bio = BIO_new (&bio_method__ssl_underlying_stream);
  bio->ptr = stream;
  bio->init = 1;		/// HMM...
  stream->ssl = SSL_new (options->context->ctx);
  stream->context = dsk_object_ref (options->context);
  SSL_set_bio (stream->ssl, bio, bio);
  stream->base_instance.sink = DSK_OCTET_SINK (sink);        /* does not own */
  stream->base_instance.source = DSK_OCTET_SOURCE (source); /* does not own */
  stream->is_client = options->is_client ? 1 : 0;
  stream->handshaking = DSK_TRUE;
  sink->base_instance.stream = dsk_object_ref (stream);
  source->base_instance.stream = dsk_object_ref (stream);

  if (stream->is_client)
    SSL_set_connect_state (stream->ssl);
  else
    SSL_set_accept_state (stream->ssl);

  *sink_out = DSK_OCTET_SINK (sink);
  *source_out = DSK_OCTET_SOURCE (source);

  if (stream_out != NULL)
    *stream_out = stream;
  else
    dsk_object_unref (stream);
  return DSK_TRUE;
}
示例#2
0
static void
begin_connecting (DskClientStream *stream)
{
  if (stream->is_local_socket)
    {
      struct sockaddr_un addr;
      unsigned length = strlen (stream->name);
      if (length > sizeof (addr.sun_path))
        {
          /* name too long */
          /* TODO: catch this in constructor */
          dsk_octet_stream_set_last_error (&stream->base_instance,
                                           "name too long for local socket");

          return;
        }
      addr.sun_family = AF_LOCAL;
      memcpy (addr.sun_path, stream->name,
              length == sizeof (addr.sun_path) ? length : length + 1);
      begin_connecting_sockaddr (stream, sizeof (addr), (struct sockaddr *) &addr);
    }
  else if (stream->is_numeric_name)
    {
      struct sockaddr_storage addr;
      unsigned addr_len;
      DskIpAddress address;

      /* parse name into addr/addr_len */
      if (!dsk_ip_address_parse_numeric (stream->name, &address))
        dsk_die ("dsk_ip_address_parse_numeric failed on %s", stream->name);
      dsk_ip_address_to_sockaddr (&address, stream->port, &addr, &addr_len);
      begin_connecting_sockaddr (stream, addr_len, (struct sockaddr *) &addr);
    }
  else
    {
      /* begin dns lookup */
      stream->is_resolving_name = 1;
      dsk_object_ref (stream);
      dsk_dns_lookup (stream->name,
                      DSK_FALSE,                /* is_ipv6? should be be needed */
                      handle_dns_done, stream);
    }
}
示例#3
0
dsk_boolean
dsk_client_stream_new       (DskClientStreamOptions *options,
                             DskClientStream **stream_out,
                             DskOctetSink    **sink_out,
                             DskOctetSource  **source_out,
                             DskError        **error)
{
  DskClientStream *rv;
  dsk_boolean has_address = !ip_address_is_default (&options->address);

  /* check trivial usage considerations */
  dsk_warn_if_fail (!(options->hostname != NULL && has_address),
                    "ignoring ip-address because symbolic name given");
  if (options->hostname != NULL || has_address)
    {
      if (options->port == 0)
        {
          dsk_set_error (error,
                         "port must be non-zero for client (hostname is '%s')",
                         options->hostname);
          return DSK_FALSE;
        }
      dsk_warn_if_fail (options->path == NULL,
                        "cannot decide between tcp and local client");
    }

  rv = dsk_object_new (&dsk_client_stream_class);
  rv->base_instance.sink = dsk_object_new (&dsk_client_stream_sink_class);
  rv->base_instance.source = dsk_object_new (&dsk_client_stream_source_class);
  rv->base_instance.sink->stream = dsk_object_ref (rv);
  rv->base_instance.source->stream = dsk_object_ref (rv);
  rv->reconnect_time_ms = -1;
  rv->idle_disconnect_time_ms = -1;
  rv->fd = -1;

  if (options->hostname != NULL)
    {
      if (dsk_hostname_looks_numeric (options->hostname))
        rv->is_numeric_name = 1;
      rv->name = dsk_strdup (options->hostname);
      rv->port = options->port;
    }
  else if (has_address)
    {
      rv->is_numeric_name = 1;
      rv->name = dsk_ip_address_to_string (&options->address);
      rv->port = options->port;
    }
  else if (options->path != NULL)
    {
      rv->is_local_socket = 1;
      rv->name = dsk_strdup (options->path);
    }
  rv->idle_disconnect_time_ms = options->idle_disconnect_time;
  rv->reconnect_time_ms = options->reconnect_time;
  begin_connecting (rv);
  if (options->idle_disconnect_time >= 0)
    dsk_client_stream_set_max_idle_time (rv, options->idle_disconnect_time);
  if (options->reconnect_time >= 0)
    dsk_client_stream_set_reconnect_time (rv, options->reconnect_time);
  if (source_out)
    *source_out = rv->base_instance.source;
  else if (rv->base_instance.source)
    dsk_object_unref (rv->base_instance.source);
  if (sink_out)
    *sink_out = rv->base_instance.sink;
  else if (rv->base_instance.sink)
    dsk_object_unref (rv->base_instance.sink);
  if (stream_out)
    *stream_out = rv;
  else
    dsk_object_unref (rv);
  return DSK_TRUE;
}