Пример #1
0
/**
 * Do all socket creation and initialization
 */
void create_sockets()
{
    struct sockaddr_in sin;
    int fdflag, i;

    memset(&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = htonl(INADDR_ANY);
    sin.sin_port = htons(port);
    if ((listener = socket(AF_INET,SOCK_DGRAM,0)) == INVALID_SOCKET) {
        sockerror(0, 0, "Error creating socket for listener");
        exit(1);
    }
    if (bind(listener, (struct sockaddr *)&sin, sizeof(sin)) == SOCKET_ERROR) {
        sockerror(0, 0, "Error binding socket for listener");
        exit(1);
    }
#ifndef BLOCKING
#ifdef WINDOWS
    fdflag = 1;
    if (ioctlsocket(listener, FIONBIO, &fdflag) == SOCKET_ERROR) {
        sockerror(0, 0, "Error setting non-blocking option");
        closesocket(listener);
        exit(1);
    }
#else
    if ((fdflag = fcntl(listener, F_GETFL)) == SOCKET_ERROR) {
        sockerror(0, 0, "Error getting socket descriptor flags");
        closesocket(listener);
        exit(1);
    }
    fdflag |= O_NONBLOCK;
    if (fcntl(listener, F_SETFL, fdflag) == SOCKET_ERROR) {
        sockerror(0, 0, "Error setting non-blocking option");
        closesocket(listener);
        exit(1);
    }
#endif
#endif  // BLOCKING
    if (setsockopt(listener, IPPROTO_IP, IP_TOS, (char *)&dscp,
                   sizeof(dscp)) == SOCKET_ERROR) {
        sockerror(0, 0, "Error setting dscp");
        closesocket(listener);
        exit(1);
    }
#ifdef IP_MTU_DISCOVER
    {
        int mtuflag = IP_PMTUDISC_DONT;
        if (setsockopt(listener, IPPROTO_IP, IP_MTU_DISCOVER, (char *)&mtuflag,
                       sizeof(mtuflag)) == SOCKET_ERROR) {
            sockerror(0, 0, "Error disabling MTU discovery");
            closesocket(listener);
            exit(1);
        }
    }
#endif
    if (buffer) {
        if (setsockopt(listener, SOL_SOCKET, SO_RCVBUF,
                       (char *)&buffer, sizeof(buffer)) == SOCKET_ERROR) {
            sockerror(0, 0, "Error setting receive buffer size");
            exit(1);
        }
    } else {
        buffer = DEF_RCVBUF;
        if (setsockopt(listener, SOL_SOCKET, SO_RCVBUF,
                       (char *)&buffer, sizeof(buffer)) == SOCKET_ERROR) {
            buffer = DEF_BSD_RCVBUF;
            if (setsockopt(listener, SOL_SOCKET, SO_RCVBUF,
                           (char *)&buffer, sizeof(buffer)) == SOCKET_ERROR) {
                sockerror(0, 0, "Error setting receive buffer size");
                exit(1);
            }
        }
    }
    for (i = 0; i < pub_multi_count; i++) {
        if (server_count > 0) {
            log(0, 0, "joining ssm for server IPs");
            if (!multicast_join(listener, 0, &pub_multi[i], m_interface,
                                interface_count, server_keys, server_count)) {
                exit(1);
            }
            if (has_proxy) {
                log(0, 0, "joining ssm for proxy IPs");
                if (!multicast_join(listener, 0, &pub_multi[i], m_interface,
                                    interface_count, &proxy_info, 1)) {
                    exit(1);
                }
            }
        } else {
            if (!multicast_join(listener, 0, &pub_multi[i], m_interface,
                                interface_count, NULL, 0)) {
                exit(1);
            }
        }
    }
}
Пример #2
0
/**
 * Do all socket creation and initialization
 */
void create_sockets()
{
    struct sockaddr_in sin;
    int fdflag, found_if, i;

    memset(&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = htonl(INADDR_ANY);
    sin.sin_port = htons(port);
    if ((listener = socket(AF_INET,SOCK_DGRAM,0)) == INVALID_SOCKET) {
        sockerror(0, 0, "Error creating socket for listener");
        exit(1);
    }
    if (bind(listener, (struct sockaddr *)&sin, sizeof(sin)) == SOCKET_ERROR) {
        sockerror(0, 0, "Error binding socket for listener");
        exit(1);
    }
#ifndef BLOCKING
#ifdef WINDOWS
    fdflag = 1;
    if (ioctlsocket(listener, FIONBIO, &fdflag) == SOCKET_ERROR) {
        sockerror(0, 0, "Error setting non-blocking option");
        closesocket(listener);
        exit(1);
    }
#else
    if ((fdflag = fcntl(listener, F_GETFL)) == SOCKET_ERROR) {
        sockerror(0, 0, "Error getting socket descriptor flags");
        closesocket(listener);
        exit(1);
    }
    fdflag |= O_NONBLOCK;
    if (fcntl(listener, F_SETFL, fdflag) == SOCKET_ERROR) {
        sockerror(0, 0, "Error setting non-blocking option");
        closesocket(listener);
        exit(1);
    }
#endif
#endif  // BLOCKING
    if (setsockopt(listener, IPPROTO_IP, IP_TOS, (char *)&dscp,
                   sizeof(dscp)) == SOCKET_ERROR) {
        sockerror(0, 0, "Error setting dscp");
        closesocket(listener);
        exit(1);
    }
    if (buffer) {
        if (setsockopt(listener, SOL_SOCKET, SO_RCVBUF,
                       (char *)&buffer, sizeof(buffer)) == SOCKET_ERROR) {
            sockerror(0, 0, "Error setting receive buffer size");
            exit(1);
        }
        if (setsockopt(listener, SOL_SOCKET, SO_SNDBUF,
                       (char *)&buffer, sizeof(buffer)) == SOCKET_ERROR) {
            sockerror(0, 0, "Error setting send buffer size");
            exit(1);
        }
    } else {
        buffer = DEF_RCVBUF;
        if (setsockopt(listener, SOL_SOCKET, SO_RCVBUF,
                       (char *)&buffer, sizeof(buffer)) == SOCKET_ERROR) {
            buffer = DEF_BSD_RCVBUF;
            if (setsockopt(listener, SOL_SOCKET, SO_RCVBUF,
                           (char *)&buffer, sizeof(buffer)) == SOCKET_ERROR) {
                sockerror(0, 0, "Error setting receive buffer size");
                exit(1);
            }
        }
        buffer = DEF_RCVBUF;
        if (setsockopt(listener, SOL_SOCKET, SO_SNDBUF,
                       (char *)&buffer, sizeof(buffer)) == SOCKET_ERROR) {
            buffer = DEF_BSD_RCVBUF;
            if (setsockopt(listener, SOL_SOCKET, SO_SNDBUF,
                           (char *)&buffer, sizeof(buffer)) == SOCKET_ERROR) {
                sockerror(0, 0, "Error setting send buffer size");
                exit(1);
            }
        }
    }
    if (setsockopt(listener, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,
                   sizeof(ttl)) == SOCKET_ERROR) {
        sockerror(0, 0, "Error setting ttl");
        closesocket(listener);
        exit(1);
    }
    if (out_addr.s_addr == INADDR_NONE) {
        for (i = 0, found_if = 0; (i < ifl_len) && !found_if; i++) {
            if (!ifl[i].isloopback) {
                found_if = 1;
                out_addr.s_addr = ifl[i].addr.s_addr;
            }
        }
        if (!found_if) {
            if (ifl_len > 0) {
                out_addr.s_addr = ifl[0].addr.s_addr;
            } else {
                fprintf(stderr, "ERROR: no network interfaces found!\n");
                exit(1);
            }
        }
    }
    if (setsockopt(listener, IPPROTO_IP, IP_MULTICAST_IF, (char *)&out_addr,
                   sizeof(out_addr)) == SOCKET_ERROR) {
        sockerror(0, 0, "Error setting outgoing interface");
        closesocket(listener);
        exit(1);
    }

    for (i = 0; i < pub_multi_count; i++) {
        if (!multicast_join(listener, 0, &pub_multi[i], m_interface,
                            interface_count, server_fp, server_fp_count)) {
            exit(1);
        }
    }
}
Пример #3
0
/**
 * 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);
}
Пример #4
0
/**
 * Do all socket creation and initialization
 */
void create_sockets(void)
{
    struct addrinfo ai_hints, *ai_rval;
    int family, rval, fdflag, i;
#if (defined IPV6_RECVTCLASS || defined IP_RECVTCLASS || defined IP_RECVTOS) &&\
        !(defined WINDOWS && _WIN32_WINNT < _WIN32_WINNT_LONGHORN)
    int tosflag;
#endif

    family = AF_INET;
    for (i = 0; i < pub_multi_count; i++) {
        if (pub_multi[i].ss.ss_family == AF_INET6) {
            family = AF_INET6;
            break;
        }
    }

    if ((listener = socket(family, SOCK_DGRAM, 0)) == INVALID_SOCKET) {
        sockerror(0, 0, 0, "Error creating socket for listener");
        exit(ERR_SOCKET);
    }
#if (defined WINDOWS && _WIN32_WINNT >= _WIN32_WINNT_LONGHORN) ||\
        (!defined WINDOWS && !defined NO_DUAL)
    if (family == AF_INET6) {
        int v6flag = 0;
        if (setsockopt(listener, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&v6flag,
                        sizeof(v6flag)) == SOCKET_ERROR) {
            sockerror(0, 0, 0, "Error setting v6only");
            closesocket(listener);
            exit(ERR_SOCKET);
        }
    }
#endif
    memset(&ai_hints, 0, sizeof(ai_hints));
    ai_hints.ai_family = family;
    ai_hints.ai_socktype = SOCK_DGRAM;
    ai_hints.ai_protocol = 0;
    ai_hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV;
    if ((rval = getaddrinfo(NULL, portname, &ai_hints, &ai_rval)) != 0) {
        log0(0, 0, 0, "Error getting bind address: %s", gai_strerror(rval));
        exit(ERR_SOCKET);
    }
    if (bind(listener, ai_rval->ai_addr, ai_rval->ai_addrlen) == SOCKET_ERROR) {
        sockerror(0, 0, 0, "Error binding socket for listener");
        closesocket(listener);
        exit(ERR_SOCKET);
    }
    freeaddrinfo(ai_rval);
#ifdef WINDOWS
    fdflag = 1;
    if (ioctlsocket(listener, FIONBIO, &fdflag) == SOCKET_ERROR) {
        sockerror(0, 0, 0, "Error setting non-blocking option");
        closesocket(listener);
        exit(ERR_SOCKET);
    }
#else
    if ((fdflag = fcntl(listener, F_GETFL)) == SOCKET_ERROR) {
        sockerror(0, 0, 0, "Error getting socket descriptor flags");
        closesocket(listener);
        exit(ERR_SOCKET);
    }
    fdflag |= O_NONBLOCK;
    if (fcntl(listener, F_SETFL, fdflag) == SOCKET_ERROR) {
        sockerror(0, 0, 0, "Error setting non-blocking option");
        closesocket(listener);
        exit(ERR_SOCKET);
    }
#endif
    if (family == AF_INET6) {
#if defined IPV6_TCLASS && !defined WINDOWS
        if (setsockopt(listener, IPPROTO_IPV6, IPV6_TCLASS, (char *)&dscp,
                       sizeof(dscp)) == SOCKET_ERROR) {
            sockerror(0, 0, 0, "Error setting dscp");
            closesocket(listener);
            exit(ERR_SOCKET);
        }
#endif
#ifdef IPV6_RECVTCLASS
#if !(defined WINDOWS && _WIN32_WINNT < _WIN32_WINNT_LONGHORN)
        tosflag = 1;
        if (setsockopt(listener, IPPROTO_IPV6, IPV6_RECVTCLASS,
                       (char *)&tosflag, sizeof(tosflag)) == SOCKET_ERROR) {
            sockerror(0, 0, 0, "Error setting recv tos");
            closesocket(listener);
            exit(ERR_SOCKET);
       }
#endif
#endif
#ifdef IPV6_MTU_DISCOVER
        {
            int mtuflag = IP_PMTUDISC_DONT;
            if (setsockopt(listener, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
                           (char *)&mtuflag, sizeof(mtuflag)) == SOCKET_ERROR) {
                sockerror(0, 0, 0, "Error disabling MTU discovery");
                closesocket(listener);
                exit(ERR_SOCKET);
            }
        }
#endif
    }
#if (defined WINDOWS && _WIN32_WINNT < _WIN32_WINNT_LONGHORN) ||\
        (defined NO_DUAL)
    if (family == AF_INET) {
#endif
        if (setsockopt(listener, IPPROTO_IP, IP_TOS, (char *)&dscp,
                       sizeof(dscp)) == SOCKET_ERROR) {
            sockerror(0, 0, 0, "Error setting dscp");
            closesocket(listener);
            exit(ERR_SOCKET);
        }
#ifdef IP_RECVTCLASS
#if !(defined WINDOWS && _WIN32_WINNT < _WIN32_WINNT_LONGHORN)
        tosflag = 1;
        if (setsockopt(listener, IPPROTO_IP, IP_RECVTCLASS, (char *)&tosflag,
                       sizeof(tosflag)) == SOCKET_ERROR) {
            sockerror(0, 0, 0, "Error setting recv tos");
            closesocket(listener);
            exit(ERR_SOCKET);
        }
#endif
#elif defined IP_RECVTOS
        tosflag = 1;
        if (setsockopt(listener, IPPROTO_IP, IP_RECVTOS, (char *)&tosflag,
                       sizeof(tosflag)) == SOCKET_ERROR) {
            sockerror(0, 0, 0, "Error setting recv tos");
            closesocket(listener);
            exit(ERR_SOCKET);
        }
#endif
#ifdef IP_MTU_DISCOVER
        {
            int mtuflag = IP_PMTUDISC_DONT;
            if (setsockopt(listener, IPPROTO_IP, IP_MTU_DISCOVER,
                    (char *)&mtuflag, sizeof(mtuflag)) == SOCKET_ERROR) {
                sockerror(0, 0, 0, "Error disabling MTU discovery");
                closesocket(listener);
                exit(ERR_SOCKET);
            }
        }
#endif
#if (defined WINDOWS && _WIN32_WINNT < _WIN32_WINNT_LONGHORN) ||\
        (defined NO_DUAL)
    }
#endif
    if (rcvbuf) {
        if (setsockopt(listener, SOL_SOCKET, SO_RCVBUF,
                       (char *)&rcvbuf, sizeof(rcvbuf)) == SOCKET_ERROR) {
            sockerror(0, 0, 0, "Error setting receive buffer size");
            exit(ERR_SOCKET);
        }
    } else {
        rcvbuf = DEF_RCVBUF;
        if (setsockopt(listener, SOL_SOCKET, SO_RCVBUF,
                       (char *)&rcvbuf, sizeof(rcvbuf)) == SOCKET_ERROR) {
            rcvbuf = DEF_BSD_RCVBUF;
            if (setsockopt(listener, SOL_SOCKET, SO_RCVBUF,
                           (char *)&rcvbuf, sizeof(rcvbuf)) == SOCKET_ERROR) {
                sockerror(0, 0, 0, "Error setting receive buffer size");
                exit(ERR_SOCKET);
            }
        }
    }
    for (i = 0; i < pub_multi_count; i++) {
        if (server_count > 0) {
            log3(0, 0, 0, "joining ssm for server IPs");
            if (!multicast_join(listener, 0, &pub_multi[i], m_interface,
                                interface_count, server_keys, server_count)) {
                exit(ERR_SOCKET);
            }
            if (has_proxy) {
                log3(0, 0, 0, "joining ssm for proxy IPs");
                if (!multicast_join(listener, 0, &pub_multi[i], m_interface,
                                    interface_count, &proxy_info, 1)) {
                    exit(ERR_SOCKET);
                }
            }
        } else {
            if (!multicast_join(listener, 0, &pub_multi[i], m_interface,
                                interface_count, NULL, 0)) {
                exit(ERR_SOCKET);
            }
        }
    }
}