示例#1
0
lwp_sslclient lwp_sslclient_new (SSL_CTX * server_context, lw_stream socket,
                                 lwp_sslclient_on_handshook on_handshook,
                                 void * tag)
{
   lwp_sslclient ctx = calloc (sizeof (*ctx), 1);

   if (!ctx)
      return 0;

   ctx->write_condition = -1;

   #ifdef _lacewing_npn
      *ctx->npn = 0;
   #endif

   ctx->server_context = server_context;
   ctx->ssl = SSL_new (server_context);

   ctx->on_handshook = on_handshook;
   ctx->tag = tag;

   /* TODO : I'm not really happy with the extra layer of buffering
    * that BIO pairs introduce.  Is there a better way to do this?
    */

   BIO_new_bio_pair (&ctx->bio_internal, 0, &ctx->bio_external, 0);
   SSL_set_bio (ctx->ssl, ctx->bio_internal, ctx->bio_internal);

   SSL_set_accept_state (ctx->ssl);

   lwp_stream_init (&ctx->upstream, &def_upstream, 0);
   lwp_stream_init (&ctx->downstream, &def_downstream, 0);

   /* Retain our streams indefinitely, since we'll be in charge of releasing
    * their memory.  This doesn't stop stream_delete from working.
    */
   lwp_retain (&ctx->upstream);
   lwp_retain (&ctx->downstream);

   lw_stream_add_filter_upstream
      (socket, &ctx->upstream, lw_false, lw_false);

   lw_stream_add_filter_downstream
      (socket, &ctx->downstream, lw_false, lw_false);

   pump (ctx);

   assert (! (ctx->flags & lwp_sslclient_flag_dead));

   return ctx;
}
示例#2
0
static lw_bool def_close (lw_stream stream_ctx, lw_bool immediate)
{
   lw_fdstream ctx = (lw_fdstream) stream_ctx;

   lwp_trace ("FDStream::Close for FD %d", ctx->fd);

   lwp_retain (ctx, "fdstream close");

   /* Remove the watch to make sure we don't get any more
    * callbacks from the pump.
    */

   if (ctx->watch)
   {
      lw_pump_remove (lw_stream_pump ((lw_stream) ctx), ctx->watch);
      ctx->watch = 0;
   }

   int fd = ctx->fd;

   ctx->fd = -1;

   if (fd != -1)
   {
      if (ctx->flags & lwp_fdstream_flag_autoclose)
      {
         shutdown (fd, SHUT_RDWR);
         close (fd);
      }
   }

   lwp_release (ctx, "fdstream close");

   return lw_true;
}
示例#3
0
static void read_ready (void * tag)
{
   lw_fdstream ctx = tag;

   if (ctx->flags & lwp_fdstream_flag_reading)
      return;

   ctx->flags |= lwp_fdstream_flag_reading;

   lwp_retain (ctx, "fdstream read_ready");

   /* TODO : Use a buffer on the heap instead? */

   char buffer [lwp_default_buffer_size];

   lw_bool close_stream = lw_false;

   while (ctx->reading_size == -1 || ctx->reading_size > 0)
   {
      if (ctx->fd == -1)
         break;

      size_t to_read = sizeof (buffer);

      if (ctx->reading_size != -1 && to_read > ctx->reading_size)
         to_read = ctx->reading_size;

      int bytes = read (ctx->fd, buffer, to_read);

      if (bytes == 0)
      {
         close_stream = lw_true;
         break;
      }

      if (bytes == -1)
      {
         if (errno == EAGAIN)
            break;

         close_stream = lw_true;
         break;
      }

      if (ctx->reading_size != -1)
      {
         if (bytes > ctx->reading_size)
            ctx->reading_size = 0;
         else
            ctx->reading_size -= bytes;
      }

      lw_stream_data ((lw_stream) ctx, buffer, bytes);

      /* Calling Data or Close may result in destruction of the Stream -
       * see FDStream destructor.
       */

      if (! (ctx->flags & lwp_fdstream_flag_reading))
         break;
   }

   ctx->flags &= ~ lwp_fdstream_flag_reading;

   if (lwp_release (ctx, "fdstream read_ready") || ctx->stream.flags & lwp_stream_flag_dead)
      return;

   if (close_stream)
      lw_stream_close ((lw_stream) ctx, lw_true);
}