コード例 #1
0
ファイル: server_transfer.c プロジェクト: b-cuts/uftp
/**
 * Sends out a data packet.  All headers should be populated except blsize
 */
int send_data(const struct finfo_t *finfo, unsigned char *packet, int datalen,
              unsigned char *encpacket)
{
    struct uftp_h *header;
    struct fileseg_h *fileseg;
    int payloadlen;
    unsigned char *outpacket;

    header = (struct uftp_h *)packet;
    fileseg = (struct fileseg_h *)(packet + sizeof(struct uftp_h));

    payloadlen = sizeof(struct fileseg_h) + datalen;
    if (keytype != KEY_NONE) {
        if (!encrypt_and_sign(packet, &encpacket, payloadlen, mtu, keytype,
                groupkey, groupsalt, ivlen, hashtype, grouphmackey, hmaclen,
                sigtype, privkey, rsalen)) {
            log0(0, 0, "Error encrypting FILESEG");
            return 0;
        }
        outpacket = encpacket;
        payloadlen = ntohs(((struct uftp_h *)outpacket)->blsize);
    } else {
        outpacket = packet;
        header->blsize = htons(payloadlen);
    }

    if (nb_sendto(sock, outpacket, payloadlen + sizeof(struct uftp_h), 0,
               (struct sockaddr *)&receive_dest,
               sizeof(receive_dest)) == SOCKET_ERROR) {
        sockerror(0, 0, "Error sending FILESEG");
        return 0;
    }

    return 1;
}
コード例 #2
0
ファイル: client_announce.c プロジェクト: PumpkinSpace/uftp
/**
 * Sends a KEYINFO_ACK in response to a KEYINFO
 */
void send_keyinfo_ack(struct group_list_t *group)
{
    unsigned char *buf, *encrypted;
    struct uftp_h *header;
    struct keyinfoack_h *keyinfo_ack;
    unsigned char *verifydata, *verify_hash, *verify_val;
    unsigned int payloadlen, hashlen;
    int verifylen, enclen, len;

    buf = safe_calloc(MAXMTU, 1);

    header = (struct uftp_h *)buf;
    keyinfo_ack = (struct keyinfoack_h *)(buf + sizeof(struct uftp_h));

    set_uftp_header(header, KEYINFO_ACK, group);
    keyinfo_ack->func = KEYINFO_ACK;
    keyinfo_ack->hlen = sizeof(struct keyinfoack_h) / 4;

    verifydata = build_verify_data(group, &verifylen);
    if (!verifydata) {
        glog0(group, "Error getting verify data");
        send_abort(group, "Error getting verify data");
        free(buf);
        return;
    }

    verify_hash = safe_calloc(group->hmaclen, 1);
    verify_val = safe_calloc(VERIFY_LEN + group->hmaclen, 1);
    hash(group->hashtype, verifydata, verifylen, verify_hash, &hashlen);
    PRF(group->hashtype, VERIFY_LEN, group->groupmaster,
            sizeof(group->groupmaster), "client finished",
            verify_hash, hashlen, verify_val, &len);
    memcpy(keyinfo_ack->verify_data, verify_val, VERIFY_LEN);
    free(verifydata);
    free(verify_hash);
    free(verify_val);

    payloadlen = sizeof(struct keyinfoack_h);
    encrypted = NULL;
    if (!encrypt_and_sign(buf, &encrypted, payloadlen, &enclen, group->keytype,
            group->groupkey, group->groupsalt, &group->ivctr, group->ivlen,
            group->hashtype, group->grouphmackey, group->hmaclen,group->sigtype,
            group->keyextype, group->client_privkey,group->client_privkeylen)) {
        glog0(group, "Error encrypting KEYINFO_ACK");
        free(buf);
        return;
    }
    payloadlen = enclen + sizeof(struct uftp_h);

    if (nb_sendto(listener, encrypted, payloadlen, 0,
               (struct sockaddr *)&(group->replyaddr),
               family_len(group->replyaddr)) == SOCKET_ERROR) {
        gsockerror(group, "Error sending KEYINFO_ACK");
    } else {
        glog2(group, "KEYINFO_ACK sent");
    }
    free(encrypted);
    free(buf);
}
コード例 #3
0
ファイル: client_transfer.c プロジェクト: No9/uftp
/**
 * Sends back a CC_ACK message for congestion control feedback
 */
void send_cc_ack(struct group_list_t *group)
{
    unsigned char *buf, *encrypted, *outpacket;
    struct uftp_h *header;
    struct cc_ack_h *cc_ack;
    struct tfmcc_ack_info_he *tfmcc;
    int payloadlen, enclen;

    buf = safe_calloc(MAXMTU, 1);

    header = (struct uftp_h *)buf;
    cc_ack = (struct cc_ack_h *)(buf + sizeof(struct uftp_h));
    tfmcc = (struct tfmcc_ack_info_he *)((unsigned char *)cc_ack +
                sizeof(struct cc_ack_h));

    set_uftp_header(header, CC_ACK, group);
    cc_ack->func = CC_ACK;
    cc_ack->hlen =
            (sizeof(struct cc_ack_h) + sizeof(struct tfmcc_ack_info_he)) / 4;
    set_tfmcc_ack_info(group, tfmcc);

    payloadlen = cc_ack->hlen * 4;
    if ((group->phase != PHASE_REGISTERED) && (group->keytype != KEY_NONE)) {
        encrypted = NULL;
        if (!encrypt_and_sign(buf, &encrypted, payloadlen, &enclen,
                group->keytype, group->groupkey, group->groupsalt,&group->ivctr,
                group->ivlen, group->hashtype, group->grouphmackey,
                group->hmaclen, group->sigtype, group->keyextype,
                group->client_privkey, group->client_privkeylen)) {
            glog0(group, "Error encrypting CC_ACK");
            free(buf);
            return;
        }
        outpacket = encrypted;
        payloadlen = enclen;
    } else {
        encrypted = NULL;
        outpacket = buf;
    }
    payloadlen += sizeof(struct uftp_h);

    if (nb_sendto(listener, outpacket, payloadlen, 0,
               (struct sockaddr *)&group->replyaddr,
               family_len(group->replyaddr)) == SOCKET_ERROR) {
        gsockerror(group, "Error sending CC_ACK");
    } else {
        glog2(group, "CC_ACK sent");
    }
    set_timeout(group, 0);
    group->cc_time.tv_sec = 0;
    group->cc_time.tv_usec = 0;
    free(buf);
}
コード例 #4
0
ファイル: server_common.c プロジェクト: fmaker/uftp.deb
/**
 * Sends an ABORT message to one or more clients
 */
void send_abort(const struct finfo_t *finfo, const char *message,
                const struct sockaddr_in *destaddr,
                const struct in_addr *dest, int encrypt)
{
    unsigned char *buf, *encrypted, *outpacket;
    struct uftp_h *header;
    struct abort_h *abort;
    int payloadlen;

    buf = calloc(mtu, 1);
    if (buf == NULL) {
        syserror(0, 0, "calloc failed!");
        exit(1);
    }
    header = (struct uftp_h *)buf;
    abort = (struct abort_h *)(buf + sizeof(struct uftp_h));

    set_uftp_header(header, ABORT, finfo, destaddr);
    abort->func = ABORT;
    if (dest) {
        abort->host = dest->s_addr;
    }
    strncpy(abort->message, message, sizeof(abort->message) - 1);

    payloadlen = sizeof(struct abort_h);
    if (encrypt) {
        encrypted = NULL;
        if (!encrypt_and_sign(buf, &encrypted, payloadlen, mtu, keytype,
                groupkey, groupsalt, ivlen, hashtype, grouphmackey, hmaclen,
                sigtype, privkey, rsalen)) {
            log0(0, 0, "Error encrypting ABORT");
            free(buf);
            return;
        }
        outpacket = encrypted;
        payloadlen = ntohs(((struct uftp_h *)outpacket)->blsize);
    } else {
        encrypted = NULL;
        outpacket = buf;
        header->blsize = htons(payloadlen);
    }

    if (nb_sendto(sock, outpacket, payloadlen + sizeof(struct uftp_h), 0,
               (struct sockaddr *)destaddr,
               sizeof(struct sockaddr_in)) == SOCKET_ERROR) {
        sockerror(0, 0, "Error sending ABORT");
    }
    free(buf); 
    free(encrypted);
} 
コード例 #5
0
ファイル: client_common.c プロジェクト: No9/uftp
/**
 * Sends an ABORT message to a server
 */
void send_abort(struct group_list_t *group, const char *message)
{
    unsigned char *buf, *encrypted, *outpacket;
    struct uftp_h *header;
    struct abort_h *abort_hdr;
    int payloadlen, enclen;

    buf = safe_calloc(MAXMTU, 1);

    header = (struct uftp_h *)buf;
    abort_hdr = (struct abort_h *)(buf + sizeof(struct uftp_h));

    set_uftp_header(header, ABORT, group);
    abort_hdr->func = ABORT;
    abort_hdr->hlen = sizeof(struct abort_h) / 4;
    abort_hdr->host = 0;
    strncpy(abort_hdr->message, message, sizeof(abort_hdr->message) - 1);

    payloadlen = sizeof(struct abort_h);
    if ((group->phase != PHASE_REGISTERED) &&
            (group->keytype != KEY_NONE)) {
        encrypted = NULL;
        if (!encrypt_and_sign(buf, &encrypted, payloadlen, &enclen,
                group->keytype, group->groupkey, group->groupsalt,&group->ivctr,
                group->ivlen, group->hashtype, group->grouphmackey,
                group->hmaclen, group->sigtype, group->keyextype,
                group->client_privkey, group->client_privkeylen)) {
            glog0(group, "Error encrypting ABORT");
            free(buf);
            return;
        }
        outpacket = encrypted;
        payloadlen = enclen;
    } else {
        encrypted = NULL;
        outpacket = buf;
    }
    payloadlen += sizeof(struct uftp_h);

    if (nb_sendto(listener, outpacket, payloadlen, 0,
               (struct sockaddr *)&group->replyaddr,
               family_len(group->replyaddr)) == SOCKET_ERROR) {
        gsockerror(group, "Error sending ABORT");
    }

    flush_disk_cache(group);
    file_cleanup(group, 1);
    free(buf);
    free(encrypted);
}
コード例 #6
0
ファイル: client_transfer.c プロジェクト: No9/uftp
/**
 * Sends back a COMPLETE message in response to a DONE or FILEINFO
 */
void send_complete(struct group_list_t *group, int set_freespace)
{
    unsigned char *buf, *encrypted, *outpacket;
    struct uftp_h *header;
    struct complete_h *complete;
    struct freespace_info_he *freespace;
    int payloadlen, enclen;
    struct timeval tv;

    gettimeofday(&tv, NULL);
    if ((group->phase == PHASE_COMPLETE) &&
            (cmptimestamp(tv, group->expire_time) >= 0)) {
        glog1(group, "Completion unconfirmed by server");
        move_files(group);
        file_cleanup(group, 0);
        return;
    }
    buf = safe_calloc(MAXMTU, 1);

    header = (struct uftp_h *)buf;
    complete = (struct complete_h *)(buf + sizeof(struct uftp_h));
    freespace = (struct freespace_info_he *)((unsigned char *)complete +
                    sizeof(struct complete_h));

    set_uftp_header(header, COMPLETE, group);
    complete->func = COMPLETE;
    if (set_freespace) {
        complete->hlen = (sizeof(struct complete_h) +
                            sizeof(struct freespace_info_he)) / 4;
    } else {
        complete->hlen = sizeof(struct complete_h) / 4;
    }
    complete->status = group->fileinfo.comp_status;
    complete->file_id = htons(group->file_id);
    if (set_freespace) {
        set_freespace_info(group, freespace);
    }

    payloadlen = complete->hlen * 4;
    if ((group->phase != PHASE_REGISTERED) && (group->keytype != KEY_NONE)) {
        encrypted = NULL;
        if (!encrypt_and_sign(buf, &encrypted, payloadlen, &enclen,
                group->keytype, group->groupkey, group->groupsalt,&group->ivctr,
                group->ivlen, group->hashtype, group->grouphmackey,
                group->hmaclen, group->sigtype, group->keyextype,
                group->client_privkey, group->client_privkeylen)) {
            glog0(group, "Error encrypting COMPLETE");
            free(buf);
            return;
        }
        outpacket = encrypted;
        payloadlen = enclen;
    } else {
        encrypted = NULL;
        outpacket = buf;
    }
    payloadlen += sizeof(struct uftp_h);

    if (nb_sendto(listener, outpacket, payloadlen, 0,
               (struct sockaddr *)&group->replyaddr,
               family_len(group->replyaddr)) == SOCKET_ERROR) {
        gsockerror(group, "Error sending COMPLETE");
    } else {
        glog2(group, "COMPLETE sent");
    }
    set_timeout(group, 0);

    free(buf);
    free(encrypted);
}
コード例 #7
0
ファイル: client_transfer.c プロジェクト: No9/uftp
/**
 * Sends back a STATUS message with the given NAK list
 */
void send_status(struct group_list_t *group, unsigned int section,
                 const unsigned char *naks, unsigned int nak_count)
{
    unsigned char *buf, *encrypted, *outpacket;
    struct uftp_h *header;
    struct status_h *status;
    struct tfmcc_ack_info_he *tfmcc;
    unsigned char *sent_naks;
    int payloadlen, enclen;

    buf = safe_calloc(MAXMTU, 1);

    header = (struct uftp_h *)buf;
    status = (struct status_h *)(buf + sizeof(struct uftp_h));
    tfmcc = (struct tfmcc_ack_info_he *)((unsigned char *)status +
                sizeof(struct status_h));

    set_uftp_header(header, STATUS, group);
    status->func = STATUS;
    if (group->cc_type == CC_TFMCC) {
        status->hlen =
              (sizeof(struct status_h) + sizeof(struct tfmcc_ack_info_he)) / 4;
    } else {
        status->hlen = sizeof(struct status_h) / 4;
    }
    status->file_id = htons(group->file_id);
    status->section = htons(section);
    if (section >= group->fileinfo.big_sections) {
        payloadlen = (group->fileinfo.secsize_small / 8) + 1;
    } else {
        payloadlen = (group->fileinfo.secsize_big / 8) + 1;
    }
    if (group->cc_type == CC_TFMCC) {
        set_tfmcc_ack_info(group, tfmcc);
    }
    sent_naks = (unsigned char *)status + (status->hlen * 4);
    memcpy(sent_naks, naks, payloadlen);

    payloadlen += status->hlen * 4;
    if ((group->phase != PHASE_REGISTERED) && (group->keytype != KEY_NONE)) {
        encrypted = NULL;
        if (!encrypt_and_sign(buf, &encrypted, payloadlen, &enclen,
                group->keytype, group->groupkey, group->groupsalt,&group->ivctr,
                group->ivlen, group->hashtype, group->grouphmackey,
                group->hmaclen, group->sigtype, group->keyextype,
                group->client_privkey, group->client_privkeylen)) {
            glog0(group, "Error encrypting STATUS");
            free(buf);
            return;
        }
        outpacket = encrypted;
        payloadlen = enclen;
    } else {
        encrypted = NULL;
        outpacket = buf;
    }
    payloadlen += sizeof(struct uftp_h);

    if (nb_sendto(listener, outpacket, payloadlen, 0,
               (struct sockaddr *)&group->replyaddr,
               family_len(group->replyaddr)) == SOCKET_ERROR) {
        gsockerror(group, "Error sending STATUS");
    } else {
        glog2(group, "Sent %d NAKs for section %d", nak_count, section);
    }

    free(buf);
    free(encrypted);
}
コード例 #8
0
ファイル: client_common.c プロジェクト: b-cuts/uftp
/**
 * Sends an ABORT message to a server
 */
void send_abort(int listidx, const char *message)
{
    unsigned char *buf, *encrypted, *outpacket;
    struct uftp_h *header;
    struct abort_h *abort;
    struct uftp2_h *v2_header;
    char *v2_message;
    int payloadlen;

    buf = calloc(group_list[listidx].mtu, 1);
    if (buf == NULL) {
        syserror(0, 0, "calloc failed!");
        exit(1);
    }

    if (group_list[listidx].version == UFTP_V2_VER) {
        v2_header = (struct uftp2_h *)buf;
        v2_message = (char *)v2_header + sizeof(struct uftp2_h);

        v2_header->uftp_id = htonl(V2_UFTP_ID);
        v2_header->func = htonl(V2_ABORT);
        v2_header->tx_id = htonl(group_list[listidx].group_id);
        v2_header->blsize = htonl(strlen(message));
        payloadlen = sizeof(struct uftp2_h) + strlen(message);
        strncpy(v2_message, message, V2_BLOCKSIZE - 1);
        encrypted = NULL;
        outpacket = buf;
    } else {
        header = (struct uftp_h *)buf;
        abort = (struct abort_h *)(buf + sizeof(struct uftp_h));

        set_uftp_header(header, ABORT, listidx);
        abort->func = ABORT;
        abort->host = 0;
        strncpy(abort->message, message, sizeof(abort->message) - 1);

        payloadlen = sizeof(struct abort_h);
        if ((group_list[listidx].phase != PHASE_REGISTERED) &&
                (group_list[listidx].keytype != KEY_NONE)) {
            encrypted = NULL;
            if (!encrypt_and_sign(buf, &encrypted, payloadlen,
                    group_list[listidx].mtu, group_list[listidx].keytype,
                    group_list[listidx].groupkey, group_list[listidx].groupsalt,
                    group_list[listidx].ivlen, group_list[listidx].hashtype,
                    group_list[listidx].grouphmackey,
                    group_list[listidx].hmaclen, group_list[listidx].sigtype,
                    group_list[listidx].clientkey,
                    group_list[listidx].client_keylen)) {
                log0(0, 0, "Error encrypting ABORT");
                free(buf);
                return;
            }
            outpacket = encrypted;
            payloadlen = ntohs(((struct uftp_h *)outpacket)->blsize);
        } else {
            encrypted = NULL;
            outpacket = buf;
            header->blsize = htons(payloadlen);
        }
        payloadlen += sizeof(struct uftp_h);
    }

    if (nb_sendto(listener, outpacket, payloadlen, 0,
               (struct sockaddr *)&group_list[listidx].replyaddr,
               sizeof(struct sockaddr_in)) == SOCKET_ERROR) {
        sockerror(group_list[listidx].group_id, group_list[listidx].file_id,
                "Error sending ABORT");
    }

    file_cleanup(listidx, 1);
    free(buf);
    free(encrypted);
}
コード例 #9
0
ファイル: server_common.c プロジェクト: fmaker/uftp.deb
/**
 * For messages that send a list of clients in the body, append all clients
 * in the specified state to the packet, then send the message of the given
 * type when either the body is full or the end of the client list has been
 * reached.  All header fields besides uftp_h.blsize and message.destcount
 * must be populated before calling.
 * Returns 1 on success, 0 on fail.
 */
int send_multiple(const struct finfo_t *finfo, unsigned char *packet,
                  int message, int attempt, uint32_t *addrlist, int state,
                  uint16_t *mes_destcount, int encrypt,
                  const struct sockaddr_in *destaddr, int regconf)
{
    struct uftp_h *header;
    int hsize, payloadlen;
    int maxdest, packetcnt, dests, i;
    unsigned char *mheader, *encpacket, *outpacket;

    header = (struct uftp_h *)packet;
    mheader = packet + sizeof(struct uftp_h);
    hsize = (unsigned char *)addrlist - mheader;
    maxdest = ((encrypt ? encpayloadsize : payloadsize) - hsize) /
              sizeof(struct in_addr);
    packetcnt = 1;
    if (encrypt) {
        encpacket = calloc(mtu + keylen, 1); 
        if (encpacket == NULL) {
            syserror(0, 0, "calloc failed!");
            exit(1);
        }
    } else {
        encpacket = NULL;
    }
    for (i = 0, dests = 0; i < destcount; i++) {
        if (message == REG_CONF) {
            // Only send REG_CONF for a particular client if either it's
            // behind a proxy or we're sending them to everyone.
            // Also, don't send if we already sent one and we haven't
            // gotten another REGISTER
            if ((destlist[i].status == state) &&
                    (!finfo->deststate[i].conf_sent) &&
                    (regconf || (destlist[i].proxyidx != -1))) {
                addrlist[dests++] = destlist[i].addr.s_addr;
                finfo->deststate[i].conf_sent = 1;
            }
        } else if (message == DONE_CONF) {
            // As with REG_CONF, don't send a DONE_CONF for a client
            // if we already sent one and we haven't gotten another COMPLETE
            if ((destlist[i].status == state) &&
                    (!finfo->deststate[i].conf_sent)) {
                addrlist[dests++] = destlist[i].addr.s_addr;
                finfo->deststate[i].conf_sent = 1;
            }
        } else if (destlist[i].status == state) {
            addrlist[dests++] = destlist[i].addr.s_addr;
        }
        if ((dests >= maxdest) || ((i == destcount - 1) && (dests > 0))) {
            payloadlen = hsize + (dests * sizeof(uint32_t));
            *mes_destcount = htons(dests);
            if (encrypt) {
                if (!encrypt_and_sign(packet, &encpacket, payloadlen, mtu,
                        keytype, groupkey, groupsalt, ivlen, hashtype,
                        grouphmackey, hmaclen, sigtype, privkey, rsalen)) {
                    log0(0, 0, "Error encrypting %s", func_name(message));
                    free(encpacket);
                    return 0;
                }
                outpacket = encpacket;
                payloadlen = ntohs(((struct uftp_h *)outpacket)->blsize);
            } else {
                outpacket = packet;
                header->blsize = htons(payloadlen);
            }
            log2(0, 0, "Sending %s %d.%d", func_name(message), 
                       attempt, packetcnt);
            log4(0, 0, "Sending to %08X", ntohl(destaddr->sin_addr.s_addr));
            if (nb_sendto(sock, outpacket, payloadlen + sizeof(struct uftp_h),0,
                       (struct sockaddr *)destaddr,
                       sizeof(*destaddr)) == SOCKET_ERROR) {
                sockerror(0, 0, "Error sending %s", func_name(message));
                sleep(1);
                free(encpacket);
                return 0;
            }
            if (packet_wait) usleep(packet_wait);
            memset(addrlist, 0, maxdest * sizeof(uint32_t));
            dests = 0;
            packetcnt++;
        }
    }
    free(encpacket);
    return 1;
}
コード例 #10
0
ファイル: client_announce.c プロジェクト: PumpkinSpace/uftp
/**
 * Sends a FILEINFO_ACK in response to a FILEINFO
 */
void send_fileinfo_ack(struct group_list_t *group, int restart)
{
    unsigned char *buf, *encrypted, *outpacket;
    struct uftp_h *header;
    struct fileinfoack_h *fileinfo_ack;
    struct timeval now, send_time;
    unsigned int payloadlen;
    int enclen;

    buf = safe_calloc(MAXMTU, 1);

    header = (struct uftp_h *)buf;
    fileinfo_ack = (struct fileinfoack_h *)(buf + sizeof(struct uftp_h));

    payloadlen = sizeof(struct fileinfoack_h);
    set_uftp_header(header, FILEINFO_ACK, group);
    fileinfo_ack->func = FILEINFO_ACK;
    fileinfo_ack->hlen = sizeof(struct fileinfoack_h) / 4;
    fileinfo_ack->file_id = htons(group->file_id);
    if (restart) {
        fileinfo_ack->flags |= FLAG_PARTIAL;
    }
    gettimeofday(&now, NULL);
    if (cmptimestamp(now, group->last_server_rx_ts) <= 0) {
        send_time = group->last_server_ts;
    } else {
        send_time = add_timeval(group->last_server_ts,
                diff_timeval(now, group->last_server_rx_ts));
    }
    fileinfo_ack->tstamp_sec = htonl((uint32_t)send_time.tv_sec);
    fileinfo_ack->tstamp_usec = htonl((uint32_t)send_time.tv_usec);
    if (group->keytype != KEY_NONE) {
        encrypted = NULL;
        if (!encrypt_and_sign(buf, &encrypted, payloadlen, &enclen,
                group->keytype, group->groupkey, group->groupsalt,&group->ivctr,
                group->ivlen, group->hashtype, group->grouphmackey,
                group->hmaclen, group->sigtype, group->keyextype,
                group->client_privkey, group->client_privkeylen)) {
            glog0(group, "Error encrypting FILEINFO_ACK");
            free(buf);
            return;
        }
        outpacket = encrypted;
        payloadlen = enclen;
    } else {
        encrypted = NULL;
        outpacket = buf;
    }
    payloadlen += sizeof(struct uftp_h);

    if (nb_sendto(listener, outpacket, payloadlen, 0,
               (struct sockaddr *)&(group->replyaddr),
               family_len(group->replyaddr)) == SOCKET_ERROR) {
        gsockerror(group, "Error sending FILEINFO_ACK");
    } else {
        glog2(group, "FILEINFO_ACK sent");
    }
    glog3(group, "send time: %d.%06d", send_time.tv_sec, send_time.tv_usec);
    free(encrypted);
    free(buf);
}