コード例 #1
0
ファイル: proxy_common.c プロジェクト: fmaker/uftp.deb
/**
 * Clean up a group list entry.  Free malloc'ed structures, drop the
 * multicast group (if no one else is using it) and free the slot.
 */
void group_cleanup(int listidx)
{
    int i;

    for (i = 0; i < MAX_PEND; i++) {
        free(group_list[listidx].pending[i].naklist);
    }

    if ((group_list[listidx].multi.s_addr != 0) &&
            (proxy_type != CLIENT_PROXY) && !other_mcast_users(listidx) &&
            group_list[listidx].multi_join) {
        multicast_leave(listener, group_list[listidx].group_id,
                &group_list[listidx].multi, m_interface, interface_count,
                server_fp, server_fp_count);
    }
    if (group_list[listidx].serverkey) {
        free_RSA_key(group_list[listidx].serverkey);
    }
    for (i = 0; i < group_list[listidx].destcount; i++) {
        if (group_list[listidx].destinfo[i].pubkey) {
            free_RSA_key(group_list[listidx].destinfo[i].pubkey);
        }
    }
    memset(&group_list[listidx], 0, sizeof(group_list[listidx]));
}
コード例 #2
0
ファイル: proxy_common.c プロジェクト: PumpkinSpace/uftp
/**
 * Clean up a group list entry.  Free malloc'ed structures, drop the
 * multicast group (if no one else is using it) and free the slot.
 */
void group_cleanup(struct pr_group_list_t *group)
{
    int i;

    for (i = 0; i < MAX_PEND; i++) {
        free(group->pending[i].naklist);
    }

    if (!addr_blank(&group->privatemcast) && (proxy_type != CLIENT_PROXY) &&
            !other_mcast_users(group) && group->multi_join) {
        multicast_leave(listener, group->group_id, &group->privatemcast,
                m_interface, interface_count, server_fp, server_fp_count);
    }
    if (group->server_pubkey.key) {
        if ((group->keyextype == KEYEX_RSA) ||
                (group->keyextype == KEYEX_ECDH_RSA)) {
            free_RSA_key(group->server_pubkey.rsa);
        } else {
            free_EC_key(group->server_pubkey.ec);
        }
        if ((group->keyextype == KEYEX_ECDH_RSA) ||
                (group->keyextype == KEYEX_ECDH_ECDSA)) {
            free_EC_key(group->server_dhkey.ec);
            free_EC_key(group->proxy_dhkey.ec);
        }
    }
    for (i = 0; i < group->destcount; i++) {
        if (group->destinfo[i].pubkey.key) {
            if ((group->keyextype == KEYEX_RSA) ||
                    (group->keyextype == KEYEX_ECDH_RSA)) {
                free_RSA_key(group->destinfo[i].pubkey.rsa);
            } else {
                free_EC_key(group->destinfo[i].pubkey.ec);
            }
            if ((group->keyextype == KEYEX_ECDH_RSA) ||
                    (group->keyextype == KEYEX_ECDH_ECDSA)) {
                free_EC_key(group->destinfo[i].dhkey.ec);
            }
        }
    }
    memset(group, 0, sizeof(struct pr_group_list_t));
}
コード例 #3
0
ファイル: client_common.c プロジェクト: b-cuts/uftp
/**
 * Clean up a group list entry.  Close the file if open,
 * free malloc'ed structures, drop the multicast group
 * (if no one else is using it) and free the slot.
 */
void file_cleanup(int listidx, int abort)
{
    if (group_list[listidx].fileinfo.fd >= 0) {
        close(group_list[listidx].fileinfo.fd);
        group_list[listidx].fileinfo.fd = -1;
        if (tempfile) {
            move_to_backup(listidx);
            if (rename(group_list[listidx].fileinfo.temppath,
                       group_list[listidx].fileinfo.filepath) == -1) {
                syserror(group_list[listidx].group_id,
                         group_list[listidx].file_id,
                         "Couldn't rename from %s to %s",
                         group_list[listidx].fileinfo.temppath,
                         group_list[listidx].fileinfo.filepath);
            }
        }
        if (group_list[listidx].fileinfo.tstamp) {
            utim_buf utbuf;
            utbuf.actime = group_list[listidx].fileinfo.tstamp;
            utbuf.modtime = group_list[listidx].fileinfo.tstamp;
            if (utime(group_list[listidx].fileinfo.filepath, &utbuf) == -1) {
                syserror(group_list[listidx].group_id,
                         group_list[listidx].file_id, "utime failed");
            }
        }
    }

    if ((group_list[listidx].version == UFTP_V2_VER) ||
            abort || (group_list[listidx].file_id == 0)) {
        if ((group_list[listidx].multi.s_addr != 0) &&
                !other_mcast_users(listidx) && group_list[listidx].multi_join) {
            if (server_count > 0) {
                multicast_leave(listener, group_list[listidx].group_id,
                        &group_list[listidx].multi, m_interface,
                        interface_count, server_keys, server_count);
                if (has_proxy) {
                    multicast_leave(listener, group_list[listidx].group_id,
                            &group_list[listidx].multi, m_interface,
                            interface_count, &proxy_info, 1);
                }
            } else {
                multicast_leave(listener, group_list[listidx].group_id,
                        &group_list[listidx].multi,
                        m_interface, interface_count, NULL, 0);
            }
        }
        if (group_list[listidx].serverkey) {
            free_RSA_key(group_list[listidx].serverkey);
        }
        if (group_list[listidx].restartinfo &&
                (strcmp(group_list[listidx].restartinfo->name, ""))) {
            // We have unused restart info from the last run.
            // Chalk this up as a loss and delete the data file
            char filepath[MAXPATHNAME];
            snprintf(filepath, sizeof(filepath), "%s%c_group_%08X%c%s", tempdir,
                     PATH_SEP, group_list[listidx].group_id, PATH_SEP,
                     group_list[listidx].restartinfo->name);
            unlink(filepath);
        }
        if (abort) {
            write_restart_file(listidx);
        }

        free(group_list[listidx].fileinfo.naklist);
        free(group_list[listidx].fileinfo.section_done);
        if (group_list[listidx].restartinfo) {
            free(group_list[listidx].restartinfo->naklist);
            free(group_list[listidx].restartinfo->section_done);
            free(group_list[listidx].restartinfo);
        }
        memset(&group_list[listidx], 0, sizeof(group_list[listidx]));
    } else {
        // Don't clear the file_id in case we need to respond to late DONEs
        group_list[listidx].phase = PHASE_MIDGROUP;
        set_timeout(listidx);
        free(group_list[listidx].fileinfo.naklist);
        free(group_list[listidx].fileinfo.section_done);
        group_list[listidx].fileinfo.naklist = NULL;
        group_list[listidx].fileinfo.section_done = NULL;
    }
}
コード例 #4
0
ファイル: client_announce.c プロジェクト: PumpkinSpace/uftp
/**
 * Processes a new incoming ANNOUNCE
 */
void handle_announce(union sockaddr_u *src, unsigned char *packet,
                     unsigned packetlen, struct timeval rxtime)
{
    struct uftp_h *header;
    struct announce_h *announce;
    uint32_t *addrlist;
    int addrlen, rval;
    struct group_list_t *group;
    time_t t;
    struct tm *start_time;
    char privname[INET6_ADDRSTRLEN], srcname[INET6_ADDRSTRLEN];
    char srcfqdn[DESTNAME_LEN];

    header = (struct uftp_h *)packet;
    announce = (struct announce_h *)(packet + sizeof(struct uftp_h));
    addrlist = (uint32_t *)((unsigned char *)announce + (announce->hlen * 4));
    addrlen = (packetlen - sizeof(struct uftp_h) - (announce->hlen * 4)) / 4;

    if ((packetlen < sizeof(struct uftp_h) + (announce->hlen * 4U)) ||
            ((announce->hlen * 4U) < sizeof(struct announce_h))) {
        log1(ntohl(header->group_id), header->group_inst, 0, 
                "Rejecting ANNOUNCE from %08X: invalid message size",
                ntohl(header->src_id));
        return;
    }

    if ((addrlen != 0) && (!uid_in_list(addrlist, addrlen))) {
        log1(ntohl(header->group_id), header->group_inst, 0,
                "Name not in host list");
        return;
    }

    if ((group = find_open_slot()) == NULL ) {
        log0(ntohl(header->group_id), header->group_inst, 0,
             "Error: maximum number of incoming files exceeded: %d\n", MAXLIST);
        return;
    }

    t = time(NULL);
    start_time = localtime(&t);
    snprintf(group->start_date, sizeof(group->start_date), "%04d%02d%02d",
            start_time->tm_year + 1900,
            start_time->tm_mon + 1, start_time->tm_mday);
    snprintf(group->start_time, sizeof(group->start_time), "%02d%02d%02d",
            start_time->tm_hour, start_time->tm_min, start_time->tm_sec);

    if (!read_announce(group, packet, src, rxtime, packetlen)) {
        return;
    }

    if ((rval = getnameinfo((struct sockaddr *)src, family_len(*src),
            srcname, sizeof(srcname), NULL, 0, NI_NUMERICHOST)) != 0) {
        glog1(group, "getnameinfo failed: %s", gai_strerror(rval));
    }
    if (!noname) {
        if ((rval = getnameinfo((struct sockaddr *)src, family_len(*src),
                srcfqdn, sizeof(srcfqdn), NULL, 0, 0)) != 0) {
            glog1(group, "getnameinfo failed: %s", gai_strerror(rval));
        }
    } else {
        strncpy(srcfqdn, srcname, sizeof(srcfqdn) - 1);
    }
    if ((rval = getnameinfo((struct sockaddr *)&group->multi,
            family_len(group->multi), privname, sizeof(privname),
            NULL, 0, NI_NUMERICHOST)) != 0) {
        glog1(group, "getnameinfo failed: %s", gai_strerror(rval));
    }

    glog2(group, "Received request from %08X at %s (%s)",
                             ntohl(group->src_id), srcfqdn, srcname);
    glog2(group, "Using private multicast address %s", privname);
    glog3(group, "grtt = %.6f", group->grtt);
    glog3(group, "send time: %d.%06d", group->last_server_ts.tv_sec,
                 group->last_server_ts.tv_usec);
    glog3(group, "receive time: %d.%06d", group->last_server_rx_ts.tv_sec,
                 group->last_server_rx_ts.tv_usec);

    if (status_file) {
        fprintf(status_file,
                "CONNECT;%04d/%02d/%02d-%02d:%02d:%02d;%08X;%08X;%s;%s\n",
                start_time->tm_year + 1900, start_time->tm_mon + 1,
                start_time->tm_mday, start_time->tm_hour,
                start_time->tm_min, start_time->tm_sec,
                ntohl(group->src_id), group->group_id, srcname, srcfqdn);
        fflush(status_file);
    }

    if (group->restart) {
        if (group->sync_mode) {
            glog1(group, "Sync mode and restart mode incompatible");
            send_abort(group, "Sync mode and restart mode incompatible");
            return;
        }
    }

    if (!addr_blank(&group->multi)) {
        if (server_count > 0) {
            if (!is_multicast(&group->multi, 1)) {
                glog1(group, "Invalid source specific multicast address: %s",
                             privname);
                send_abort(group, "Invalid source specific multicast address");
                return;
            }
            if (!other_mcast_users(group)) {
                if (!multicast_join(listener, group->group_id, &group->multi,
                        m_interface, interface_count,
                        server_keys, server_count)) {
                    send_abort(group, "Error joining multicast group");
                    return;
                }
                if (has_proxy) {
                    if (!multicast_join(listener,group->group_id, &group->multi,
                            m_interface, interface_count, &proxy_info, 1)) {
                        send_abort(group, "Error joining multicast group");
                        return;
                    }
                }
            }
        } else {
            if (!is_multicast(&group->multi, 0)) {
                glog1(group, "Invalid multicast address: %s", privname);
                send_abort(group, "Invalid multicast address");
                return;
            }
            if (!other_mcast_users(group)) {
                if (!multicast_join(listener, group->group_id,
                        &group->multi, m_interface, interface_count, NULL, 0)) {
                    send_abort(group, "Error joining multicast group");
                    return;
                }
            }
        }
        group->multi_join = 1;
    }

    send_register(group);
}
コード例 #5
0
ファイル: client_common.c プロジェクト: No9/uftp
/**
 * Clean up a group list entry.  Close the file if open,
 * free malloc'ed structures, drop the multicast group
 * (if no one else is using it) and free the slot.
 */
void file_cleanup(struct group_list_t *group, int abort_session)
{
    if (group->fileinfo.fd >= 0) {
        glog2(group, "starting file close");
        close(group->fileinfo.fd);
        glog2(group, "done file close");
        group->fileinfo.fd = -1;
        if (abort_session && !strcmp(tempdir, "")) {
            if (tempfile) {
                unlink(group->fileinfo.temppath);
            } else {
                unlink(group->fileinfo.filepath);
            }
        } else {
            if (tempfile) {
                move_to_backup(group);
                if (rename(group->fileinfo.temppath,
                           group->fileinfo.filepath) == -1) {
                    gsyserror(group, "Couldn't rename from %s to %s",
                             group->fileinfo.temppath,group->fileinfo.filepath);
                }
            }
            if (group->fileinfo.tstamp) {
                utim_buf utbuf;
                utbuf.actime = group->fileinfo.tstamp;
                utbuf.modtime = group->fileinfo.tstamp;
                if (utime(group->fileinfo.filepath, &utbuf) == -1) {
                    gsyserror(group, "utime failed");
                }
            }
        }
    }

    if (abort_session || (group->file_id == 0)) {
        if (!addr_blank(&group->multi) && !other_mcast_users(group) &&
                group->multi_join) {
            if (server_count > 0) {
                multicast_leave(listener, group->group_id, &group->multi,
                        m_interface, interface_count, server_keys,server_count);
                if (has_proxy) {
                    multicast_leave(listener, group->group_id, &group->multi,
                            m_interface, interface_count, &proxy_info, 1);
                }
            } else {
                multicast_leave(listener, group->group_id, &group->multi,
                        m_interface, interface_count, NULL, 0);
            }
        }
        if (group->server_pubkey.key) {
            if (group->keyextype == KEYEX_ECDH_ECDSA) {
                free_EC_key(group->server_pubkey.ec);
            } else {
                free_RSA_key(group->server_pubkey.rsa);
            }
        }
        if (group->server_dhkey.key) {
            free_EC_key(group->server_dhkey.ec);
            free_EC_key(group->client_dhkey.ec);
        }
        if (group->restartinfo &&
                (strcmp(group->restartinfo->name, ""))) {
            // We have unused restart info from the last run.
            // Chalk this up as a loss and delete the data file
            char filepath[MAXPATHNAME];
            snprintf(filepath, sizeof(filepath), "%s%c_group_%08X%c%s", tempdir,
                     PATH_SEP, group->group_id, PATH_SEP,
                     group->restartinfo->name);
            unlink(filepath);
        }
        if (abort_session) {
            write_restart_file(group);
        }

        free(group->loss_history);
        free(group->fileinfo.naklist);
        free(group->fileinfo.section_done);
        free(group->fileinfo.cache);
        free(group->fileinfo.cache_status);
        if (group->restartinfo) {
            free(group->restartinfo->naklist);
            free(group->restartinfo->section_done);
            free(group->restartinfo);
        }
        memset(group, 0, sizeof(struct group_list_t));
    } else {
        // Don't clear the file_id in case we need to respond to late DONEs
        if (!strcmp(tempdir, "")) {
            run_postreceive(group, group->fileinfo.filepath);
        }
        group->phase = PHASE_MIDGROUP;
        set_timeout(group, 0);
        free(group->fileinfo.naklist);
        free(group->fileinfo.section_done);
        free(group->fileinfo.cache);
        free(group->fileinfo.cache_status);
        group->fileinfo.naklist = NULL;
        group->fileinfo.section_done = NULL;
        group->fileinfo.cache = NULL;
        group->fileinfo.cache_status = NULL;
    }
}