⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 srvnet.c

📁 distcc编译器的源代码.好像是readhat公司开发的.
💻 C
字号:
/* -*- c-file-style: "java"; indent-tabs-mode: nil; fill-column: 78 -*- *  * distcc -- A simple distributed compiler system * * Copyright (C) 2002, 2003, 2004 by Martin Pool <mbp@samba.org> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * General Public License for more details. *  * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */                /* "Happy is the man who finds wisdom, and the man who                 * gets understanding; for the gain from it is better                 * than gain from silver and its profit better than                 * gold." -- Proverbs 3:13 *//** * @file * * Server-side networking. **/#include "config.h"#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <fcntl.h>#include <errno.h>#include <netdb.h>#include <sys/stat.h>#include <sys/types.h>#include <sys/wait.h>#include <sys/param.h>#include <sys/socket.h>#include <netinet/in.h>#include <netinet/tcp.h>#ifdef HAVE_ARPA_NAMESER_H#  include <arpa/nameser.h>#endif#include <arpa/inet.h>#ifdef HAVE_RESOLV_H#  include <resolv.h>#endif#include "types.h"#include "exitcode.h"#include "distcc.h"#include "trace.h"#include "util.h"#include "srvnet.h"#include "access.h"#include "netutil.h"#include "dopt.h"/* * Listen on a predetermined address (often the passive address).  The way in * which we get the address depends on the resolver API in use. **/static int dcc_listen_by_addr(int fd,                              struct sockaddr *sa,                              size_t salen){    int one = 1;    char *sa_buf = NULL;    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one));    dcc_sockaddr_to_string(sa, salen, &sa_buf);    /* now we've got a socket - we need to bind it */    if (bind(fd, sa, salen) == -1) {	rs_log_error("bind of %s failed: %s", sa_buf ? sa_buf : "UNKNOWN",                     strerror(errno));        free(sa_buf);	close(fd);	return EXIT_BIND_FAILED;    }    rs_log_info("listening on %s", sa_buf ? sa_buf : "UNKNOWN");    free(sa_buf);    if (listen(fd, 10)) {        rs_log_error("listen failed: %s", strerror(errno));        close(fd);        return EXIT_BIND_FAILED;    }    return 0;}#if defined(ENABLE_RFC2553)/* This version uses getaddrinfo.  It will probably use IPv6 if that's * supported by your configuration, kernel, and library. */int dcc_socket_listen(int port, int *fd_out, const char *listen_addr){    char portname[20];    struct addrinfo hints;    struct addrinfo *res, *ai;    int error;    int ret;    /* getaddrinfo() ought to check for this, but some versions do not.     * (Debian Bug#192876.) */    if (port < 1 || port > 65535) {        rs_log_error("port number out of range: %d", port);        return EXIT_BAD_ARGUMENTS;    }    /* getaddrinfo wants a string for the service name */    snprintf(portname, sizeof portname, "%d", port);    /* Set-up hints structure.  */    memset(&hints, 0, sizeof(hints));    hints.ai_socktype = SOCK_STREAM;    if (listen_addr == NULL)        hints.ai_flags = AI_PASSIVE; /* bind all */    error = getaddrinfo(listen_addr, portname, &hints, &res);        if (error) {        rs_log_error("getaddrinfo failed for host %s service %s: %s",                     listen_addr ? listen_addr : "(passive)",                     portname, gai_strerror(error));        return EXIT_BIND_FAILED;    }    /* The first sockaddr returned will typically be an IPv6 socket.  Some     * kernels might not support that. */    for (ai = res; ai; ai=ai->ai_next) {        int af = ai->ai_addr->sa_family;        if ((*fd_out = socket(af, SOCK_STREAM, 0)) == -1) {            if (errno == EAFNOSUPPORT) {                rs_log_notice("socket address family %d not supported", af);                continue;            } else {                rs_log_error("socket creation failed: %s", strerror(errno));                return EXIT_BIND_FAILED;            }        } else {            ret = dcc_listen_by_addr(*fd_out, res->ai_addr, res->ai_addrlen);            freeaddrinfo(res);            return ret;        }    }    rs_log_error("failed to find any supported socket family");    return EXIT_BIND_FAILED;}#else /* ndef ENABLE_RFC2553 *//* This version uses inet_aton */int dcc_socket_listen(int port, int *listen_fd, const char *listen_addr){    struct sockaddr_in sock;    if (port < 1 || port > 65535) {        /* htons() will truncate, not check */        rs_log_error("port number out of range: %d", port);        return EXIT_BAD_ARGUMENTS;    }    memset((char *) &sock, 0, sizeof(sock));    sock.sin_port = htons(port);    sock.sin_family = PF_INET;    if (listen_addr) {        if (!inet_aton(listen_addr, &sock.sin_addr)) {            rs_log_error("listen address \"%s\" is not a valid IPv4 address",                         listen_addr);            return EXIT_BAD_ARGUMENTS;        }    } else {        sock.sin_addr.s_addr = INADDR_ANY;    }    if ((*listen_fd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {	rs_log_error("socket creation failed: %s", strerror(errno));	return EXIT_BIND_FAILED;    }    return dcc_listen_by_addr(*listen_fd, (struct sockaddr *) &sock,                              sizeof sock);}#endif  /* ndef ENABLE_RFC2553 *//** * Determine if a file descriptor is in fact a socket **/int is_a_socket(int fd){    int v, l;    l = sizeof(int);    return (getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *) &v, &l) == 0);}/** * Log client IP address and perform access control checks. * * Note that PSA may be NULL if the sockaddr is unknown. **/int dcc_check_client(struct sockaddr *psa,                     int salen,                     struct dcc_allow_list *allowed){    char *client_ip;    struct dcc_allow_list *l;    int ret;        if ((ret = dcc_sockaddr_to_string(psa, salen, &client_ip)) != 0)        return ret;        rs_log_info("connection from %s", client_ip);    free(client_ip);    if (!psa)        /* if no sockaddr, must be a pipe or something. */        return 0;    if (!allowed)        /* if no ACL, default open */        return 0;        for (l = allowed; l; l = l->next) {        if (psa->sa_family == AF_INET) {            in_addr_t cli_inaddr;            cli_inaddr = ((struct sockaddr_in *) psa)->sin_addr.s_addr;                            if ((ret = dcc_check_address(cli_inaddr, l->addr, l->mask)) == 0)                break;#ifdef ENABLE_RFC2553        } else if (psa->sa_family == AF_INET6) {            const struct sockaddr_in6 *sa6 = (const struct sockaddr_in6 *) psa;            const struct in6_addr *a6 = &sa6->sin6_addr;            const in_addr_t *a4;                        if (IN6_IS_ADDR_V4MAPPED(a6) || IN6_IS_ADDR_V4COMPAT(a6)) {                a4 = (const in_addr_t *) &a6->s6_addr[12];                if ((ret = dcc_check_address(*a4, l->addr, l->mask)) == 0)                    break;            } else {                rs_log_notice("ipv6 ACLs not implemented");                return EXIT_ACCESS_DENIED;            }#endif        } else {            ret = EXIT_ACCESS_DENIED;            rs_log_notice("access denied from unknown address family %d",                          psa->sa_family);            break;        }    }    if (ret != 0) {        rs_log_error("connection denied by access list");    }    return ret;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -