15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <signal.h> 7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <stdio.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/file.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/stat.h> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h" 17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h" 184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/tools/balsa/split.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/acceptor_thread.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/constants.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/flip_config.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/output_ordering.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/sm_connection.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/sm_interface.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/spdy_interface.h" 26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/tools/flip_server/streamer_interface.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If true, then disables the nagle algorithm); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FLAGS_disable_nagle = true; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The number of times that accept() will be called when the 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// alarm goes off when the accept_using_alarm flag is set to true. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If set to 0, accept() will be performed until the accept queue 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is completely drained and the accept() call returns an error); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32 FLAGS_accepts_per_wake = 0; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The size of the TCP accept backlog); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32 FLAGS_accept_backlog_size = 1024; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If set to false a single socket will be used. If set to true 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// then a new socket will be created for each accept thread. 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that this only works with kernels that support 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SO_REUSEPORT); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FLAGS_reuseport = false; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Flag to force spdy, even if NPN is not negotiated. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FLAGS_force_spdy = false; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The amount of time the server delays before sending back the 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reply); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)double FLAGS_server_think_time_in_s = 0; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)net::FlipConfig g_proxy_config; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)std::vector<std::string>& split(const std::string& s, 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char delim, 57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::vector<std::string>& elems) { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::stringstream ss(s); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string item; 60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) while (std::getline(ss, item, delim)) { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elems.push_back(item); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return elems; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)std::vector<std::string> split(const std::string& s, char delim) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> elems; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return split(s, delim, elems); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GotQuitFromStdin() { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make stdin nonblocking. Yes this is done each time. Oh well. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fcntl(0, F_SETFL, O_NONBLOCK); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char c; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string maybequit; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (read(0, &c, 1) > 0) { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) maybequit += c; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (maybequit.size()) { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "scanning string: \"" << maybequit << "\""; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (maybequit.size() > 1 && 83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) (maybequit.c_str()[0] == 'q' || maybequit.c_str()[0] == 'Q')); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* BoolToStr(bool b) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (b) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "true"; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "false"; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool wantExit = false; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool wantLogClose = false; 94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void SignalHandler(int signum) { 95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) switch (signum) { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SIGTERM: 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SIGINT: 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wantExit = true; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SIGHUP: 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wantLogClose = true; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)static int OpenPidFile(const char* pidfile) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int fd; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct stat pid_stat; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fd = open(pidfile, O_RDWR | O_CREAT, 0600); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fd == -1) { 113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) fprintf(stderr, "Could not open pid file '%s' for reading.\n", pidfile); 114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) exit(1); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = flock(fd, LOCK_EX | LOCK_NB); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == -1) { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (errno == EWOULDBLOCK) { 120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) fprintf(stderr, "Flip server is already running.\n"); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) perror("Error getting lock on pid file"); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(1); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fstat(fd, &pid_stat) == -1) { 128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) fprintf( 129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) stderr, "Could not stat pid file '%s': %s\n", pidfile, strerror(errno)); 130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) exit(1); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pid_stat.st_size != 0) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ftruncate(fd, pid_stat.st_size) == -1) { 134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) fprintf(stderr, 135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "Could not truncate pid file '%s': %s\n", 136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) pidfile, 137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) strerror(errno)); 138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) exit(1); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char pid_str[8]; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) snprintf(pid_str, sizeof(pid_str), "%d", getpid()); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes = static_cast<int>(strlen(pid_str)); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (write(fd, pid_str, strlen(pid_str)) != bytes) { 146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) perror("Could not write pid file"); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close(fd); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(1); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return fd; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)int main(int argc, char** argv) { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int i = 0; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool wait_for_iface = false; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int pidfile_fd; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signal(SIGPIPE, SIG_IGN); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signal(SIGTERM, SignalHandler); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signal(SIGINT, SignalHandler); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signal(SIGHUP, SignalHandler); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::CommandLine::Init(argc, argv); 16546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::CommandLine cl(argc, argv); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cl.HasSwitch("help") || argc < 2) { 168a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) printf("%s <options>\n", argv[0]); 169a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) printf(" Proxy options:\n"); 170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) printf( 171a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\t--proxy<1..n>=\"<listen ip>,<listen port>," 172a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "<ssl cert filename>,\n" 173a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\t <ssl key filename>,<http server ip>," 174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "<http server port>,\n" 175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\t [https server ip],[https server port]," 176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "<spdy only 0|1>\"\n" 177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\t * The https server ip and port may be left empty if they are" 178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) " the same as\n" 179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\t the http server fields.\n" 180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\t * spdy only prevents non-spdy https connections from being" 181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) " passed\n" 182a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\t through the proxy listen ip:port.\n" 183a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\t--forward-ip-header=<header name>\n" 184a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\n Server options:\n" 185a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\t--spdy-server=\"<listen ip>,<listen port>,[ssl cert filename]," 186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\n\t [ssl key filename]\"\n" 187a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\t--http-server=\"<listen ip>,<listen port>,[ssl cert filename]," 188a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\n\t [ssl key filename]\"\n" 189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\t * Leaving the ssl cert and key fields empty will disable ssl" 190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) " for the\n" 191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\t http and spdy flip servers\n" 192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\n Global options:\n" 193a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\t--logdest=<file|system|both>\n" 194a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\t--logfile=<logfile>\n" 195a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\t--wait-for-iface\n" 196a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\t * The flip server will block until the listen ip has been" 197a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) " raised.\n" 198a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\t--ssl-session-expiry=<seconds> (default is 300)\n" 199a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\t--ssl-disable-compression\n" 200a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\t--idle-timeout=<seconds> (default is 300)\n" 201a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\t--pidfile=<filepath> (default /var/run/flip-server.pid)\n" 202a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\t--help\n"); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(0); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cl.HasSwitch("pidfile")) { 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pidfile_fd = OpenPidFile(cl.GetSwitchValueASCII("pidfile").c_str()); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pidfile_fd = OpenPidFile(PIDFILE); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::OutputOrdering::set_server_think_time_in_s(FLAGS_server_think_time_in_s); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cl.HasSwitch("forward-ip-header")) { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::SpdySM::set_forward_ip_header( 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cl.GetSwitchValueASCII("forward-ip-header")); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::StreamerSM::set_forward_ip_header( 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cl.GetSwitchValueASCII("forward-ip-header")); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cl.HasSwitch("logdest")) { 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string log_dest_value = cl.GetSwitchValueASCII("logdest"); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (log_dest_value.compare("file") == 0) { 224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch g_proxy_config.log_destination_ = logging::LOG_TO_FILE; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (log_dest_value.compare("system") == 0) { 226eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch g_proxy_config.log_destination_ = logging::LOG_TO_SYSTEM_DEBUG_LOG; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (log_dest_value.compare("both") == 0) { 228eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch g_proxy_config.log_destination_ = logging::LOG_TO_ALL; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(FATAL) << "Invalid logging destination value: " << log_dest_value; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_proxy_config.log_destination_ = logging::LOG_NONE; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cl.HasSwitch("logfile")) { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_proxy_config.log_filename_ = cl.GetSwitchValueASCII("logfile"); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (g_proxy_config.log_destination_ == logging::LOG_NONE) { 239eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch g_proxy_config.log_destination_ = logging::LOG_TO_FILE; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 241eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else if ((g_proxy_config.log_destination_ & logging::LOG_TO_FILE) != 0) { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(FATAL) << "Logging destination requires a log file to be specified."; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cl.HasSwitch("wait-for-iface")) { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_for_iface = true; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cl.HasSwitch("ssl-session-expiry")) { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string session_expiry = cl.GetSwitchValueASCII("ssl-session-expiry"); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_proxy_config.ssl_session_expiry_ = atoi(session_expiry.c_str()); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cl.HasSwitch("ssl-disable-compression")) { 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_proxy_config.ssl_disable_compression_ = true; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cl.HasSwitch("idle-timeout")) { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_proxy_config.idle_socket_timeout_s_ = 260a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) atoi(cl.GetSwitchValueASCII("idle-timeout").c_str()); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cl.HasSwitch("force_spdy")) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::SMConnection::set_force_spdy(true); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 266eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch logging::LoggingSettings settings; 267eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch settings.logging_dest = g_proxy_config.log_destination_; 268eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch settings.log_file = g_proxy_config.log_filename_.c_str(); 269eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch settings.lock_log = logging::DONT_LOCK_LOG_FILE; 270eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch logging::InitLogging(settings); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(INFO) << "Flip SPDY proxy started with configuration:"; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(INFO) << "Logging destination : " << g_proxy_config.log_destination_; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(INFO) << "Log file : " << g_proxy_config.log_filename_; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(INFO) << "Forward IP Header : " 276a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) << (net::SpdySM::forward_ip_header().length() 277a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ? net::SpdySM::forward_ip_header() 278a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : "<disabled>"); 279a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) LOG(INFO) << "Wait for interfaces : " << (wait_for_iface ? "true" 280a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : "false"); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(INFO) << "Accept backlog size : " << FLAGS_accept_backlog_size; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(INFO) << "Accepts per wake : " << FLAGS_accepts_per_wake; 283a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) LOG(INFO) << "Disable nagle : " << (FLAGS_disable_nagle ? "true" 284a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : "false"); 285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) LOG(INFO) << "Reuseport : " << (FLAGS_reuseport ? "true" 286a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : "false"); 287a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) LOG(INFO) << "Force SPDY : " << (FLAGS_force_spdy ? "true" 288a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : "false"); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(INFO) << "SSL session expiry : " 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << g_proxy_config.ssl_session_expiry_; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(INFO) << "SSL disable compression : " 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << g_proxy_config.ssl_disable_compression_; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(INFO) << "Connection idle timeout : " 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << g_proxy_config.idle_socket_timeout_s_; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Proxy Acceptors 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (true) { 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i += 1; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::stringstream name; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name << "proxy" << i; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!cl.HasSwitch(name.str())) { 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string value = cl.GetSwitchValueASCII(name.str()); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> valueArgs = split(value, ','); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_EQ((unsigned int)9, valueArgs.size()); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int spdy_only = atoi(valueArgs[8].c_str()); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If wait_for_iface is enabled, then this call will block 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // indefinitely until the interface is raised. 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_proxy_config.AddAcceptor(net::FLIP_HANDLER_PROXY, 311a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) valueArgs[0], 312a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) valueArgs[1], 313a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) valueArgs[2], 314a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) valueArgs[3], 315a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) valueArgs[4], 316a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) valueArgs[5], 317a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) valueArgs[6], 318a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) valueArgs[7], 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spdy_only, 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FLAGS_accept_backlog_size, 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FLAGS_disable_nagle, 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FLAGS_accepts_per_wake, 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FLAGS_reuseport, 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_for_iface, 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Spdy Server Acceptor 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::MemoryCache spdy_memory_cache; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cl.HasSwitch("spdy-server")) { 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spdy_memory_cache.AddFiles(); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string value = cl.GetSwitchValueASCII("spdy-server"); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> valueArgs = split(value, ','); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (valueArgs.size() < 4) 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) valueArgs.push_back(std::string()); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_proxy_config.AddAcceptor(net::FLIP_HANDLER_SPDY_SERVER, 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) valueArgs[0], 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) valueArgs[1], 339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) valueArgs[2], 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) valueArgs[3], 341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FLAGS_accept_backlog_size, 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FLAGS_disable_nagle, 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FLAGS_accepts_per_wake, 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FLAGS_reuseport, 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_for_iface, 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &spdy_memory_cache); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Spdy Server Acceptor 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::MemoryCache http_memory_cache; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cl.HasSwitch("http-server")) { 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) http_memory_cache.AddFiles(); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string value = cl.GetSwitchValueASCII("http-server"); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> valueArgs = split(value, ','); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (valueArgs.size() < 4) 361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) valueArgs.push_back(std::string()); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_proxy_config.AddAcceptor(net::FLIP_HANDLER_HTTP_SERVER, 363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) valueArgs[0], 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) valueArgs[1], 365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) valueArgs[2], 366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) valueArgs[3], 367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), 368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), 369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FLAGS_accept_backlog_size, 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FLAGS_disable_nagle, 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FLAGS_accepts_per_wake, 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FLAGS_reuseport, 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_for_iface, 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &http_memory_cache); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<net::SMAcceptorThread*> sm_worker_threads_; 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < g_proxy_config.acceptors_.size(); i++) { 383a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) net::FlipAcceptor* acceptor = g_proxy_config.acceptors_[i]; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) sm_worker_threads_.push_back(new net::SMAcceptorThread( 386a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) acceptor, (net::MemoryCache*)acceptor->memory_cache_)); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that spdy_memory_cache is not threadsafe, it is merely 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread compatible. Thus, if ever we are to spawn multiple threads, 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we either must make the MemoryCache threadsafe, or use 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a separate MemoryCache for each thread. 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The latter is what is currently being done as we spawn 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a separate thread for each http and spdy server acceptor. 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sm_worker_threads_.back()->InitWorker(); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sm_worker_threads_.back()->Start(); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!wantExit) { 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close logfile when HUP signal is received. Logging system will 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // automatically reopen on next log message. 402a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (wantLogClose) { 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wantLogClose = false; 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "HUP received, reopening log file."; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::CloseLogFile(); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GotQuitFromStdin()) { 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < sm_worker_threads_.size(); ++i) { 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sm_worker_threads_[i]->Quit(); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < sm_worker_threads_.size(); ++i) { 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sm_worker_threads_[i]->Join(); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 416a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) usleep(1000 * 10); // 10 ms 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unlink(PIDFILE); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close(pidfile_fd); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 423