コード例 #1
0
int
mongoc_stream_tls_openssl_bio_read (BIO *b, char *buf, int len)
{
   mongoc_stream_tls_t *tls;
   int ret;

   BSON_ASSERT (b);
   BSON_ASSERT (buf);
   ENTRY;

   tls = (mongoc_stream_tls_t *) BIO_get_data (b);

   if (!tls) {
      RETURN (-1);
   }

   errno = 0;
   ret = (int) mongoc_stream_read (
      tls->base_stream, buf, len, 0, tls->timeout_msec);
   BIO_clear_retry_flags (b);

   if ((ret <= 0) && MONGOC_ERRNO_IS_AGAIN (errno)) {
      BIO_set_retry_read (b);
   }

   RETURN (ret);
}
コード例 #2
0
static int
_mongoc_stream_tls_bio_read (BIO  *b,
                             char *buf,
                             int   len)
{
   mongoc_stream_tls_t *tls;
   int ret;

   BSON_ASSERT (b);
   BSON_ASSERT (buf);

   if (!(tls = b->ptr)) {
      return -1;
   }

   errno = 0;
   ret = (int)mongoc_stream_read (tls->base_stream, buf, len, 0,
                                  tls->timeout_msec);
   BIO_clear_retry_flags (b);

   if ((ret < 0) && MONGOC_ERRNO_IS_AGAIN (errno)) {
      BIO_set_retry_read (b);
   }

   return ret;
}
コード例 #3
0
/**
 * mongoc_buffer_append_from_stream:
 * @buffer; A mongoc_buffer_t.
 * @stream: The stream to read from.
 * @size: The number of bytes to read.
 * @timeout_msec: The number of milliseconds to wait or -1 for the default
 * @error: A location for a bson_error_t, or NULL.
 *
 * Reads from stream @size bytes and stores them in @buffer. This can be used
 * in conjunction with reading RPCs from a stream. You read from the stream
 * into this buffer and then scatter the buffer into the RPC.
 *
 * Returns: true if successful; otherwise false and @error is set.
 */
bool
_mongoc_buffer_append_from_stream (mongoc_buffer_t *buffer,
                                   mongoc_stream_t *stream,
                                   size_t size,
                                   int32_t timeout_msec,
                                   bson_error_t *error)
{
   uint8_t *buf;
   ssize_t ret;

   ENTRY;

   BSON_ASSERT (buffer);
   BSON_ASSERT (stream);
   BSON_ASSERT (size);

   BSON_ASSERT (buffer->datalen);
   BSON_ASSERT ((buffer->datalen + size) < INT_MAX);

   if (!SPACE_FOR (buffer, size)) {
      if (buffer->len) {
         memmove (&buffer->data[0], &buffer->data[buffer->off], buffer->len);
      }
      buffer->off = 0;
      if (!SPACE_FOR (buffer, size)) {
         buffer->datalen =
            bson_next_power_of_two (size + buffer->len + buffer->off);
         buffer->data = (uint8_t *) buffer->realloc_func (
            buffer->data, buffer->datalen, NULL);
      }
   }

   buf = &buffer->data[buffer->off + buffer->len];

   BSON_ASSERT ((buffer->off + buffer->len + size) <= buffer->datalen);

   ret = mongoc_stream_read (stream, buf, size, size, timeout_msec);
   if (ret != size) {
      bson_set_error (error,
                      MONGOC_ERROR_STREAM,
                      MONGOC_ERROR_STREAM_SOCKET,
                      "Failed to read %" PRIu64
                      " bytes: socket error or timeout",
                      (uint64_t) size);
      RETURN (false);
   }

   buffer->len += ret;

   RETURN (true);
}
コード例 #4
0
/**
 * mongoc_buffer_append_from_stream:
 * @buffer; A mongoc_buffer_t.
 * @stream: The stream to read from.
 * @size: The number of bytes to read.
 * @timeout_msec: The number of milliseconds to wait or -1 for the default
 * @error: A location for a bson_error_t, or NULL.
 *
 * Reads from stream @size bytes and stores them in @buffer. This can be used
 * in conjunction with reading RPCs from a stream. You read from the stream
 * into this buffer and then scatter the buffer into the RPC.
 *
 * Returns: true if successful; otherwise false and @error is set.
 */
bool
_mongoc_buffer_append_from_stream (mongoc_buffer_t *buffer,
                                   mongoc_stream_t *stream,
                                   size_t           size,
                                   int32_t          timeout_msec,
                                   bson_error_t    *error)
{
    uint8_t *buf;
    ssize_t ret;

    ENTRY;

    bson_return_val_if_fail (buffer, false);
    bson_return_val_if_fail (stream, false);
    bson_return_val_if_fail (size, false);

    BSON_ASSERT (buffer->datalen);

    if (!SPACE_FOR (buffer, size)) {
        if (buffer->len) {
            memmove(&buffer->data[0], &buffer->data[buffer->off], buffer->len);
        }
        buffer->off = 0;
        if (!SPACE_FOR (buffer, size)) {
            buffer->datalen = bson_next_power_of_two ((uint32_t)size);
            buffer->data = buffer->realloc_func (buffer->data, buffer->datalen, NULL);
        }
    }

    buf = &buffer->data[buffer->off + buffer->len];
    ret = mongoc_stream_read (stream, buf, size, size, timeout_msec);
    if (ret != size) {
        bson_set_error (error,
                        MONGOC_ERROR_STREAM,
                        MONGOC_ERROR_STREAM_SOCKET,
                        "Failed to read %u bytes from socket.",
                        (unsigned)size);
        RETURN (false);
    }

    buffer->len += ret;

    RETURN (true);
}
コード例 #5
0
/**
 * mongoc_buffer_try_append_from_stream:
 * @buffer; A mongoc_buffer_t.
 * @stream: The stream to read from.
 * @size: The number of bytes to read.
 * @timeout_msec: The number of milliseconds to wait or -1 for the default
 * @error: A location for a bson_error_t, or NULL.
 *
 * Reads from stream @size bytes and stores them in @buffer. This can be used
 * in conjunction with reading RPCs from a stream. You read from the stream
 * into this buffer and then scatter the buffer into the RPC.
 *
 * Returns: bytes read if successful; otherwise -1 and @error is set.
 */
ssize_t
_mongoc_buffer_try_append_from_stream (mongoc_buffer_t *buffer,
                                       mongoc_stream_t *stream,
                                       size_t size,
                                       int32_t timeout_msec,
                                       bson_error_t *error)
{
   uint8_t *buf;
   ssize_t ret;

   ENTRY;

   BSON_ASSERT (buffer);
   BSON_ASSERT (stream);
   BSON_ASSERT (size);

   BSON_ASSERT (buffer->datalen);
   BSON_ASSERT ((buffer->datalen + size) < INT_MAX);

   if (!SPACE_FOR (buffer, size)) {
      if (buffer->len) {
         memmove (&buffer->data[0], &buffer->data[buffer->off], buffer->len);
      }
      buffer->off = 0;
      if (!SPACE_FOR (buffer, size)) {
         buffer->datalen =
            bson_next_power_of_two (size + buffer->len + buffer->off);
         buffer->data = (uint8_t *) buffer->realloc_func (
            buffer->data, buffer->datalen, NULL);
      }
   }

   buf = &buffer->data[buffer->off + buffer->len];

   BSON_ASSERT ((buffer->off + buffer->len + size) <= buffer->datalen);

   ret = mongoc_stream_read (stream, buf, size, 0, timeout_msec);

   if (ret > 0) {
      buffer->len += ret;
   }

   RETURN (ret);
}
コード例 #6
0
/** create a gridfs file from a stream
 *
 * The stream is fully consumed in creating the file
 */
mongoc_gridfs_file_t *
mongoc_gridfs_create_file_from_stream (mongoc_gridfs_t          *gridfs,
                                       mongoc_stream_t          *stream,
                                       mongoc_gridfs_file_opt_t *opt)
{
   mongoc_gridfs_file_t *file;
   ssize_t r;
   uint8_t buf[MONGOC_GRIDFS_STREAM_CHUNK];
   mongoc_iovec_t iov;
   int timeout;

   ENTRY;

   BSON_ASSERT (gridfs);
   BSON_ASSERT (stream);

   iov.iov_base = (void *)buf;
   iov.iov_len = 0;

   file = _mongoc_gridfs_file_new (gridfs, opt);
   timeout = gridfs->client->cluster.sockettimeoutms;

   for (;; ) {
      r = mongoc_stream_read (stream, iov.iov_base, MONGOC_GRIDFS_STREAM_CHUNK,
                              0, timeout);

      if (r > 0) {
         iov.iov_len = r;
         mongoc_gridfs_file_writev (file, &iov, 1, timeout);
      } else if (r == 0) {
         break;
      } else {
         mongoc_gridfs_file_destroy (file);
         RETURN (NULL);
      }
   }

   mongoc_stream_failed (stream);

   mongoc_gridfs_file_seek (file, 0, SEEK_SET);

   RETURN (file);
}
コード例 #7
0
OSStatus
mongoc_secure_transport_read (SSLConnectionRef connection,
                              void             *data,
                              size_t           *data_length)
{
   mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *)connection;
   ssize_t length;
   ENTRY;

   errno = 0;
   /* 4 arguments is *min_bytes* -- This is not a negotiation.
    * Secure Transport wants all or nothing. We must continue reading until
    * we get this amount, or timeout */
   length = mongoc_stream_read (tls->base_stream, data, *data_length, *data_length,
                                tls->timeout_msec);

   if (length > 0) {
      *data_length = length;
      RETURN(noErr);
   }

   if (length == 0) {
      RETURN(errSSLClosedGraceful);
   }

   switch (errno) {
   case ENOENT:
      RETURN(errSSLClosedGraceful);
      break;
   case ECONNRESET:
      RETURN(errSSLClosedAbort);
      break;
   case EAGAIN:
      RETURN(errSSLWouldBlock);
      break;
   default:
      RETURN(-36); /* ioErr */
      break;
   }
}
コード例 #8
0
/** create a gridfs file from a stream
 *
 * The stream is fully consumed in creating the file
 */
mongoc_gridfs_file_t *
mongoc_gridfs_create_file_from_stream (mongoc_gridfs_t          *gridfs,
                                       mongoc_stream_t          *stream,
                                       mongoc_gridfs_file_opt_t *opt)
{
   mongoc_gridfs_file_t *file;
   ssize_t r;
   bson_uint8_t buf[MONGOC_GRIDFS_STREAM_CHUNK];
   struct iovec iov = { buf, 0 };

   ENTRY;

   BSON_ASSERT (gridfs);
   BSON_ASSERT (stream);

   file = _mongoc_gridfs_file_new (gridfs, opt);

   for (;; ) {
      r = mongoc_stream_read (stream, iov.iov_base, MONGOC_GRIDFS_STREAM_CHUNK,
                              0, 0);

      if (r > 0) {
         iov.iov_len = r;
         mongoc_gridfs_file_writev (file, &iov, 1, 0);
      } else if (r == 0) {
         break;
      } else {
         mongoc_gridfs_file_destroy (file);
         RETURN (NULL);
      }
   }

   mongoc_stream_destroy (stream);

   mongoc_gridfs_file_seek (file, 0, SEEK_SET);

   RETURN (file);
}
コード例 #9
0
ファイル: mongoc-buffer.c プロジェクト: jqk6/mongo-c-driver
/**
 * _mongoc_buffer_fill:
 * @buffer: A mongoc_buffer_t.
 * @stream: A stream to read from.
 * @min_bytes: The minumum number of bytes to read.
 * @error: A location for a bson_error_t or NULL.
 *
 * Attempts to fill the entire buffer, or at least @min_bytes.
 *
 * Returns: The number of buffered bytes, or -1 on failure.
 */
ssize_t
_mongoc_buffer_fill (mongoc_buffer_t *buffer,
                     mongoc_stream_t *stream,
                     size_t           min_bytes,
                     int32_t          timeout_msec,
                     bson_error_t    *error)
{
   ssize_t ret;
   size_t avail_bytes;

   ENTRY;

   bson_return_val_if_fail(buffer, false);
   bson_return_val_if_fail(stream, false);
   bson_return_val_if_fail(min_bytes >= 0, false);

   BSON_ASSERT (buffer->data);
   BSON_ASSERT (buffer->datalen);

   if (min_bytes <= buffer->len) {
      RETURN (buffer->len);
   }

   min_bytes -= buffer->len;

   if (buffer->len) {
      memmove (&buffer->data[0], &buffer->data[buffer->off], buffer->len);
   }

   buffer->off = 0;

   if (!SPACE_FOR (buffer, min_bytes)) {
      buffer->datalen = bson_next_power_of_two (buffer->len + min_bytes);
      buffer->data = buffer->realloc_func (buffer->data, buffer->datalen,
                                           buffer->realloc_data);
   }

   avail_bytes = buffer->datalen - buffer->len;

   ret = mongoc_stream_read (stream,
                             &buffer->data[buffer->off + buffer->len],
                             avail_bytes, min_bytes, timeout_msec);

   if (ret == -1) {
      bson_set_error (error,
                      MONGOC_ERROR_STREAM,
                      MONGOC_ERROR_STREAM_SOCKET,
                      "Failed to buffer %u bytes within %d milliseconds.",
                      (unsigned)min_bytes, (int)timeout_msec);
      RETURN (-1);
   }

   buffer->len += ret;

   if (buffer->len < min_bytes) {
      bson_set_error (error,
                      MONGOC_ERROR_STREAM,
                      MONGOC_ERROR_STREAM_SOCKET,
                      "Could only buffer %u of %u bytes in %d milliseconds.",
                      (unsigned)buffer->len,
                      (unsigned)min_bytes,
                      (int)timeout_msec);
      RETURN (-1);
   }

   RETURN (buffer->len);
}
コード例 #10
0
static void
validate (const char *name) /* IN */
{
   mongoc_stream_t *stream;
   mongoc_rpc_t rpc;
#ifdef _WIN32
   struct _stat st;
#else
   struct stat st;
#endif
   uint8_t *buf;
   int32_t len;
   int ret;

   stream = mongoc_stream_file_new_for_path (name, O_RDONLY, 0);
   if (!stream) {
      perror ("failed to open file");
      exit (EXIT_FAILURE);
   }

#ifdef _WIN32
   ret = _stat (name, &st);
#else
   ret = stat (name, &st);
#endif
   if (ret != 0) {
      perror ("failed to stat() file.");
      exit (EXIT_FAILURE);
   }

   if ((st.st_size > (100 * 1024 * 1024)) || (st.st_size < 16)) {
      fprintf (stderr, "%s: unreasonable message size\n", name);
      exit (EXIT_FAILURE);
   }

   buf = malloc (st.st_size);
   if (buf == NULL) {
      fprintf (stderr, "%s: Failed to malloc %d bytes.\n",
               name, (int)st.st_size);
      exit (EXIT_FAILURE);
   }

   if (st.st_size != mongoc_stream_read (stream, buf, st.st_size, st.st_size, -1)) {
      fprintf (stderr, "%s: Failed to read %d bytes into buffer.\n",
               name, (int)st.st_size);
      exit (EXIT_FAILURE);
   }

   memcpy (&len, buf, 4);
   len = BSON_UINT32_FROM_LE (len);
   if (len != st.st_size) {
      fprintf (stderr, "%s is invalid. Invalid Length.\n", name);
      exit (EXIT_FAILURE);
   }

   if (!_mongoc_rpc_scatter (&rpc, buf, st.st_size)) {
      fprintf (stderr, "%s is invalid. Invalid Format.\n", name);
      exit (EXIT_FAILURE);
   }

   fprintf (stdout, "%s is valid.\n", name);

   bson_free (buf);
}