Exemple #1
0
Fichier : net.c Projet : baptr/core
int SendTransaction(int sd, char *buffer, int len, char status)
{
    char work[CF_BUFSIZE];
    int wlen;

    memset(work, 0, sizeof(work));

    if (len == 0)
    {
        wlen = strlen(buffer);
    }
    else
    {
        wlen = len;
    }

    if (wlen > CF_BUFSIZE - CF_INBAND_OFFSET)
    {
        Log(LOG_LEVEL_ERR, "SendTransaction: wlen (%d) > %d - %d", wlen, CF_BUFSIZE, CF_INBAND_OFFSET);
        ProgrammingError("SendTransaction software failure");
    }

    snprintf(work, CF_INBAND_OFFSET, "%c %d", status, wlen);

    memcpy(work + CF_INBAND_OFFSET, buffer, wlen);

    if (SendSocketStream(sd, work, wlen + CF_INBAND_OFFSET, 0) == -1)
    {
        return -1;
    }

    return 0;
}
Exemple #2
0
int SendTransaction(int sd, char *buffer, int len, char status)
{
    char work[CF_BUFSIZE];
    int wlen;

    memset(work, 0, sizeof(work));

    if (len == 0)
    {
        wlen = strlen(buffer);
    }
    else
    {
        wlen = len;
    }

    if (wlen > CF_BUFSIZE - CF_INBAND_OFFSET)
    {
        CfOut(cf_error, "", "SendTransaction: wlen (%d) > %d - %d", wlen, CF_BUFSIZE, CF_INBAND_OFFSET);
        FatalError("SendTransaction software failure");
    }

    snprintf(work, CF_INBAND_OFFSET, "%c %d", status, wlen);

    memcpy(work + CF_INBAND_OFFSET, buffer, wlen);

    CfDebug("Transaction Send[%s][Packed text]\n", work);

    if (SendSocketStream(sd, work, wlen + CF_INBAND_OFFSET, 0) == -1)
    {
        return -1;
    }

    return 0;
}
Exemple #3
0
/**
 * @param len is the number of bytes to send, or 0 if buffer is a
 *        '\0'-terminated string so strlen(buffer) can used.
 */
int SendTransaction(const ConnectionInfo *conn_info,
                    const char *buffer, int len, char status)
{
    assert(status == CF_MORE || status == CF_DONE);

    char work[CF_BUFSIZE] = { 0 };
    int ret;

    if (len == 0)
    {
        len = strlen(buffer);
    }

    if (len > CF_BUFSIZE - CF_INBAND_OFFSET)
    {
        Log(LOG_LEVEL_ERR, "SendTransaction: len (%d) > %d - %d",
            len, CF_BUFSIZE, CF_INBAND_OFFSET);
        return -1;
    }

    snprintf(work, CF_INBAND_OFFSET, "%c %d", status, len);

    memcpy(work + CF_INBAND_OFFSET, buffer, len);

    Log(LOG_LEVEL_DEBUG, "SendTransaction header: %s", work);
    LogRaw(LOG_LEVEL_DEBUG, "SendTransaction data: ",
           work + CF_INBAND_OFFSET, len);

    switch(ConnectionInfoProtocolVersion(conn_info))
    {
    case CF_PROTOCOL_CLASSIC:
        ret = SendSocketStream(ConnectionInfoSocket(conn_info), work,
                               len + CF_INBAND_OFFSET);
        break;
    case CF_PROTOCOL_TLS:
        ret = TLSSend(ConnectionInfoSSL(conn_info), work, len + CF_INBAND_OFFSET);
        break;
    default:
        UnexpectedError("SendTransaction: ProtocolVersion %d!",
                        ConnectionInfoProtocolVersion(conn_info));
        ret = -1;
    }

    if (ret == -1)
        return -1;
    else
        return 0;
}
Exemple #4
0
void CfGetFile(ServerFileGetState *args)
{
    int fd;
    off_t n_read, total = 0, sendlen = 0, count = 0;
    char sendbuffer[CF_BUFSIZE + 256], filename[CF_BUFSIZE];
    struct stat sb;
    int blocksize = 2048;

    ConnectionInfo *conn_info = &(args->connect)->conn_info;

    TranslatePath(filename, args->replyfile);

    stat(filename, &sb);

    Log(LOG_LEVEL_DEBUG, "CfGetFile('%s'), size = %" PRIdMAX, filename, (intmax_t) sb.st_size);

/* Now check to see if we have remote permission */

    if (!TransferRights(filename, args, &sb))
    {
        RefuseAccess(args->connect, args->buf_size, "");
        snprintf(sendbuffer, CF_BUFSIZE, "%s", CF_FAILEDSTR);
        if (conn_info->type == CF_PROTOCOL_CLASSIC)
        {
            SendSocketStream(conn_info->sd, sendbuffer, args->buf_size);
        }
        else if (conn_info->type == CF_PROTOCOL_TLS)
        {
            TLSSend(conn_info->ssl, sendbuffer, args->buf_size);
        }
        return;
    }

/* File transfer */

    if ((fd = open(filename, O_RDONLY)) == -1)
    {
        Log(LOG_LEVEL_ERR, "Open error of file '%s'. (open: %s)",
            filename, GetErrorStr());
        snprintf(sendbuffer, CF_BUFSIZE, "%s", CF_FAILEDSTR);
        if (conn_info->type == CF_PROTOCOL_CLASSIC)
        {
            SendSocketStream(conn_info->sd, sendbuffer, args->buf_size);
        }
        else if (conn_info->type == CF_PROTOCOL_TLS)
        {
            TLSSend(conn_info->ssl, sendbuffer, args->buf_size);
        }
    }
    else
    {
        int div = 3;

        if (sb.st_size > 10485760L) /* File larger than 10 MB, checks every 64kB */
        {
            div = 32;
        }

        while (true)
        {
            memset(sendbuffer, 0, CF_BUFSIZE);

            Log(LOG_LEVEL_DEBUG, "Now reading from disk...");

            if ((n_read = read(fd, sendbuffer, blocksize)) == -1)
            {
                Log(LOG_LEVEL_ERR, "Read failed in GetFile. (read: %s)", GetErrorStr());
                break;
            }

            if (n_read == 0)
            {
                break;
            }
            else
            {
                off_t savedlen = sb.st_size;

                /* check the file is not changing at source */

                if (count++ % div == 0)   /* Don't do this too often */
                {
                    if (stat(filename, &sb))
                    {
                        Log(LOG_LEVEL_ERR, "Cannot stat file '%s'. (stat: %s)",
                            filename, GetErrorStr());
                        break;
                    }
                }

                if (sb.st_size != savedlen)
                {
                    snprintf(sendbuffer, CF_BUFSIZE, "%s%s: %s", CF_CHANGEDSTR1, CF_CHANGEDSTR2, filename);

                    if (conn_info->type == CF_PROTOCOL_CLASSIC)
                    {
                        if (SendSocketStream(conn_info->sd, sendbuffer, blocksize) == -1)
                        {
                            Log(LOG_LEVEL_VERBOSE, "Send failed in GetFile. (send: %s)", GetErrorStr());
                        }
                    }
                    else if (conn_info->type == CF_PROTOCOL_TLS)
                    {
                        if (TLSSend(conn_info->ssl, sendbuffer, blocksize) == -1)
                        {
                            Log(LOG_LEVEL_VERBOSE, "Send failed in GetFile. (send: %s)", GetErrorStr());
                        }
                    }

                    Log(LOG_LEVEL_DEBUG, "Aborting transfer after %" PRIdMAX ": file is changing rapidly at source.", (intmax_t)total);
                    break;
                }

                if ((savedlen - total) / blocksize > 0)
                {
                    sendlen = blocksize;
                }
                else if (savedlen != 0)
                {
                    sendlen = (savedlen - total);
                }
            }

            total += n_read;

            if (conn_info->type == CF_PROTOCOL_CLASSIC)
            {
                if (SendSocketStream(conn_info->sd, sendbuffer, sendlen) == -1)
                {
                    Log(LOG_LEVEL_VERBOSE, "Send failed in GetFile. (send: %s)", GetErrorStr());
                    break;
                }
            }
            else if (conn_info->type == CF_PROTOCOL_TLS)
            {
                if (TLSSend(conn_info->ssl, sendbuffer, sendlen) == -1)
                {
                    Log(LOG_LEVEL_VERBOSE, "Send failed in GetFile. (send: %s)", GetErrorStr());
                    break;
                }
            }
        }

        close(fd);
    }
}
Exemple #5
0
/**
 * @param len is the number of bytes to send, or 0 if buffer is a
 *        '\0'-terminated string so strlen(buffer) can used.
 * @return -1 in case of error or connection closed
 *         (also currently returns 0 for success but don't count on it)
 * @NOTE #buffer can't be of zero length, our protocol
 *       does not allow empty transactions! The reason is that
 *       ReceiveTransaction() can't differentiate between that
 *       and connection closed.
 * @NOTE (len <= CF_BUFSIZE - CF_INBAND_OFFSET)
 */
int SendTransaction(const ConnectionInfo *conn_info,
                    const char *buffer, int len, char status)
{
    assert(status == CF_MORE || status == CF_DONE);

    char work[CF_BUFSIZE] = { 0 };
    int ret;

    if (len == 0)
    {
        len = strlen(buffer);
    }

    /* Not allowed to send zero-payload packets, because
       (ReceiveTransaction() == 0) currently means connection closed. */
    assert(len > 0);

    if (len > CF_BUFSIZE - CF_INBAND_OFFSET)
    {
        Log(LOG_LEVEL_ERR, "SendTransaction: len (%d) > %d - %d",
            len, CF_BUFSIZE, CF_INBAND_OFFSET);
        return -1;
    }

    snprintf(work, CF_INBAND_OFFSET, "%c %d", status, len);

    memcpy(work + CF_INBAND_OFFSET, buffer, len);

    Log(LOG_LEVEL_DEBUG, "SendTransaction header: %s", work);
    LogRaw(LOG_LEVEL_DEBUG, "SendTransaction data: ",
           work + CF_INBAND_OFFSET, len);

    switch(conn_info->protocol)
    {

    case CF_PROTOCOL_CLASSIC:
        ret = SendSocketStream(conn_info->sd, work,
                               len + CF_INBAND_OFFSET);
        break;

    case CF_PROTOCOL_TLS:
        ret = TLSSend(conn_info->ssl, work, len + CF_INBAND_OFFSET);
        if (ret <= 0)
        {
            ret = -1;
        }
        break;

    default:
        UnexpectedError("SendTransaction: ProtocolVersion %d!",
                        conn_info->protocol);
        ret = -1;
    }

    if (ret == -1)
    {
        return -1;                                              /* error */
    }
    else
    {
        /* SSL_MODE_AUTO_RETRY guarantees no partial writes. */
        assert(ret == len + CF_INBAND_OFFSET);

        return 0;
    }
}