SVN commit 1297686 by coolo: - let the daemon create a UNIX domain socket and listen to it additionally to the TCP socket - let the client try the UNIX domain socket first before trying TCP M +11 -1 client/main.cpp M +1 -1 configure.in M +93 -51 daemon/main.cpp M +27 -1 services/comm.cpp M +1 -0 services/comm.h --- trunk/icecream/client/main.cpp #1297685:1297686 @@ -269,8 +269,18 @@ if ( icecc && !strcasecmp(icecc, "no") ) return build_local( job, 0 ); - MsgChannel *local_daemon = Service::createChannel( "127.0.0.1", 10245, 0/*timeout*/); + /* try several options to reach the local daemon - 2 sockets, one TCP */ + MsgChannel *local_daemon = Service::createChannel( "/var/run/iceccd.socket" ); if ( ! local_daemon ) { + string path = getenv("HOME"); + path += "/.iceccd.socket"; + local_daemon = Service::createChannel( path ); + } + + if (!local_daemon) + local_daemon = Service::createChannel( "127.0.0.1", 10245, 0/*timeout*/); + + if ( ! local_daemon ) { log_warning() << "no local daemon found\n"; return build_local( job, 0 ); } --- trunk/icecream/configure.in #1297685:1297686 @@ -13,7 +13,7 @@ AC_PROG_CXX if test "$GCC" = yes then - CFLAGS="-g -W -Wall -Wimplicit \ + CFLAGS="-g -W -Wall \ -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings \ -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes \ -Wnested-externs $CFLAGS" --- trunk/icecream/daemon/main.cpp #1297685:1297686 @@ -1,4 +1,4 @@ -/* +/* -*- c-file-style: "java"; indent-tabs-mode: nil -*- This file is part of Icecream. Copyright (c) 2004 Stephan Kulow @@ -367,49 +367,6 @@ exit(1); } -int setup_listen_fd() -{ - int listen_fd; - if ((listen_fd = socket (PF_INET, SOCK_STREAM, 0)) < 0) { - log_perror ("socket()"); - return -1; - } - - int optval = 1; - if (setsockopt (listen_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) { - log_perror ("setsockopt()"); - return -1; - } - - int count = 5; - while ( count ) { - struct sockaddr_in myaddr; - myaddr.sin_family = AF_INET; - myaddr.sin_port = htons (PORT); - myaddr.sin_addr.s_addr = INADDR_ANY; - if (bind (listen_fd, (struct sockaddr *) &myaddr, - sizeof (myaddr)) < 0) { - log_perror ("bind()"); - sleep( 2 ); - if ( !--count ) - return -1; - continue; - } else - break; - } - - if (listen (listen_fd, 20) < 0) - { - log_perror ("listen()"); - return -1; - } - - fcntl(listen_fd, F_SETFD, FD_CLOEXEC); - - return listen_fd; -} - - struct timeval last_stat; int mem_limit = 100; unsigned int max_kids = 0; @@ -424,7 +381,8 @@ string envbasedir; uid_t nobody_uid; gid_t nobody_gid; - int listen_fd; + int tcp_listen_fd; + int unix_listen_fd; string machine_name; string nodename; bool noremote; @@ -452,7 +410,8 @@ envbasedir = "/tmp/icecc-envs"; nobody_uid = 65534; nobody_gid = 65533; - listen_fd = -1; + tcp_listen_fd = -1; + unix_listen_fd = -1; new_client_id = 0; next_scheduler_connect = 0; cache_size = 0; @@ -496,8 +455,79 @@ void close_scheduler(); bool reconnect(); int working_loop(); + bool setup_listen_fds(); }; +bool Daemon::setup_listen_fds() +{ + tcp_listen_fd = -1; + if (!noremote) { // if we only listen to local clients, there is no point in going TCP + if ((tcp_listen_fd = socket (PF_INET, SOCK_STREAM, 0)) < 0) { + log_perror ("socket()"); + return false; + } + + int optval = 1; + if (setsockopt (tcp_listen_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) { + log_perror ("setsockopt()"); + return false; + } + + int count = 5; + while ( count ) { + struct sockaddr_in myaddr; + myaddr.sin_family = AF_INET; + myaddr.sin_port = htons (PORT); + myaddr.sin_addr.s_addr = INADDR_ANY; + if (bind (tcp_listen_fd, (struct sockaddr *) &myaddr, + sizeof (myaddr)) < 0) { + log_perror ("bind()"); + sleep( 2 ); + if ( !--count ) + return false; + continue; + } else + break; + } + + if (listen (tcp_listen_fd, 20) < 0) { + log_perror ("listen()"); + return false; + } + + fcntl(tcp_listen_fd, F_SETFD, FD_CLOEXEC); + } + + if ((unix_listen_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { + log_perror ("socket()"); + return false; + } + struct sockaddr_un myaddr; + memset(&myaddr, 0, sizeof(myaddr)); + myaddr.sun_family = AF_UNIX; + if (getuid()==0) { + strncpy(myaddr.sun_path, "/var/run/iceccd.socket", sizeof(myaddr.sun_path)-1); + } else { + strncpy(myaddr.sun_path, getenv("HOME"), sizeof(myaddr.sun_path)-1); + strncat(myaddr.sun_path, "/.iceccd.socket", sizeof(myaddr.sun_path)-1-strlen(myaddr.sun_path)); + unlink(myaddr.sun_path); + } + + if (bind(unix_listen_fd, (struct sockaddr*)&myaddr, sizeof(myaddr)) < 0) { + log_perror("bind()"); + return false; + } + + if (listen (unix_listen_fd, 20) < 0) { + log_perror ("listen()"); + return false; + } + + fcntl(unix_listen_fd, F_SETFD, FD_CLOEXEC); + + return true; +} + void Daemon::determine_system() { struct utsname uname_buf; @@ -1250,8 +1280,14 @@ struct timeval tv; FD_ZERO( &listen_set ); - FD_SET( listen_fd, &listen_set ); - int max_fd = listen_fd; + int max_fd = 0; + if (tcp_listen_fd != -1) { + FD_SET( tcp_listen_fd, &listen_set ); + max_fd = tcp_listen_fd; + } + FD_SET( unix_listen_fd, &listen_set ); + if (unix_listen_fd > max_fd) // very likely + max_fd = unix_listen_fd; for (map::const_iterator it = fd2chan.begin(); it != fd2chan.end();) { @@ -1339,7 +1375,13 @@ } } - if ( FD_ISSET( listen_fd, &listen_set ) ) { + int listen_fd = -1; + if ( tcp_listen_fd != -1 && FD_ISSET( tcp_listen_fd, &listen_set ) ) + listen_fd = tcp_listen_fd; + if ( FD_ISSET( unix_listen_fd, &listen_set ) ) + listen_fd = unix_listen_fd; + + if ( listen_fd != -1) { struct sockaddr cli_addr; socklen_t cli_len = sizeof cli_addr; int acc_fd = accept(listen_fd, &cli_addr, &cli_len); @@ -1673,9 +1715,9 @@ for (list::const_iterator it = nl.begin(); it != nl.end(); ++it) trace() << *it << endl; - d.listen_fd = setup_listen_fd(); - if ( d.listen_fd == -1 ) // error + if ( !d.setup_listen_fds() ) // error return 1; return d.working_loop(); } + --- trunk/icecream/services/comm.cpp #1297685:1297686 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -656,13 +657,38 @@ if (connect (remote_fd, (struct sockaddr *) &remote_addr, sizeof (remote_addr)) < 0) { close( remote_fd ); - trace() << "connect failed\n"; + trace() << "connect failed on " << hostname << endl; return 0; } } + trace() << "connected to " << hostname << endl; return createChannel(remote_fd, (struct sockaddr *)&remote_addr, sizeof( remote_addr )); } +MsgChannel *Service::createChannel (const string &socket_path) +{ + int remote_fd; + struct sockaddr_un remote_addr; + + if ((remote_fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) + { + log_perror("socket()"); + return 0; + } + + remote_addr.sun_family = AF_UNIX; + strncpy(remote_addr.sun_path, socket_path.c_str(), sizeof(remote_addr.sun_path) - 1); + + if (connect (remote_fd, (struct sockaddr *) &remote_addr, sizeof (remote_addr)) < 0) + { + close( remote_fd ); + trace() << "connect failed on " << socket_path << endl; + return 0; + } + trace() << "connected to " << socket_path << endl; + return createChannel(remote_fd, (struct sockaddr *)&remote_addr, sizeof( remote_addr )); +} + static std::string shorten_filename(const std::string& str) { --- trunk/icecream/services/comm.h #1297685:1297686 @@ -212,6 +212,7 @@ class Service { public: static MsgChannel *createChannel( const std::string &host, unsigned short p, int timeout); + static MsgChannel *createChannel( const std::string &domain_socket ); static MsgChannel *createChannel( int remote_fd, struct sockaddr *, socklen_t ); };