Roxen.git / server / base_server / roxen.pike

version» Context lines:

Roxen.git/server/base_server/roxen.pike:1:   // This file is part of Roxen WebServer.   // Copyright © 1996 - 2004, Roxen IS.   //   // The Roxen WebServer main program.   //   // Per Hedbor, Henrik Grubbström, Pontus Hagland, David Hedbor and others.   // ABS and suicide systems contributed freely by Francesco Chemolli    - constant cvs_version="$Id: roxen.pike,v 1.984 2008/09/15 16:34:13 mast Exp $"; + constant cvs_version="$Id: roxen.pike,v 1.985 2008/09/17 14:25:51 mast Exp $";      //! @appears roxen   //!   //! The Roxen WebServer main program.      // The argument cache. Used by the image cache.   ArgCache argcache;      // Some headerfiles   #define IN_ROXEN
Roxen.git/server/base_server/roxen.pike:61: Inside #if defined(THREAD_DEBUG)
     #ifdef THREAD_DEBUG   # define THREAD_WERR(X) report_debug("Thread: "+X+"\n")   #else   # define THREAD_WERR(X)   #endif      // Needed to get core dumps of seteuid()'ed processes on Linux.   #if constant(System.dumpable)   #define enable_coredumps(X) System.dumpable(X) - #elif constant(system.dumpable) - // Pike 7.2. - #define enable_coredumps(X) system.dumpable(X) +    #else   #define enable_coredumps(X)   #endif      #define DDUMP(X) sol( combine_path( __FILE__, "../../" + X ), dump )   protected function sol = master()->set_on_load;      #ifdef TEST_EUID_CHANGE   int test_euid_change;   #endif
Roxen.git/server/base_server/roxen.pike:1390:   }      class Protocol   //! The basic protocol.   //! Implements reference handling, finding Configuration objects   //! for URLs, and the bind/accept handling.   {    protected Stdio.Port port_obj;       inherit "basic_defvar"; +     int bound; -  +  //! 0 if the port isn't bound, 1 if it is, and -1 if it binding it +  //! failed with EADDRINUSE when told to ignore that error. +  //! +  //! @note +  //! The -1 state should be uncommon since @[register_url] should +  //! remove such objects after the failed bind attempt.       string path;    constant name = "unknown";    constant supports_ipless = 0;    //! If true, the protocol handles ip-less virtual hosting       constant requesthandlerfile = "";    //! Filename of a by-connection handling class. It is also possible    //! to set the 'requesthandler' class member in a overloaded create    //! function.
Roxen.git/server/base_server/roxen.pike:1709:    bound = 1;    return;    }    privs = 0;   #if constant(System.EAFNOSUPPORT)    if (port_obj->errno() == System.EAFNOSUPPORT) {    // Fail permanently.    error("Invalid address " + ip);    }   #endif /* System.EAFNOSUPPORT */ - #if constant(System.EADDRINUSE) || constant(system.EADDRINUSE) -  if ( +    #if constant(System.EADDRINUSE) -  (port_obj->errno() == System.EADDRINUSE) - #else /* !constant(System.EADDRINUSE) */ -  (port_obj->errno() == system.EADDRINUSE) - #endif /* constant(System.EADDRINUSE) */ -  ) { -  if (!ignore_eaddrinuse && (retries++ < 10)) { +  if (port_obj->errno() == System.EADDRINUSE) { +  if (ignore_eaddrinuse) { +  // Told to ignore the bind problem. +  bound = -1; +  return; +  } +  if (retries++ < 10) {    // We may get spurious failures on rebinding ports on some OS'es    // (eg Linux, WIN32). See [bug 3031].    report_error(LOC_M(6, "Failed to bind %s (%s)")+"\n",    get_url(), strerror(port_obj->errno()));    report_notice(LOC_M(62, "Attempt %d. Retrying in 1 minute.")+"\n",    retries);    call_out(bind, 60);    }    }    else - #endif /* constant(System.EADDRINUSE) || constant(system.EADDRINUSE) */ + #endif /* constant(System.EADDRINUSE) */    {    report_error(LOC_M(6, "Failed to bind %s (%s)")+"\n",    get_url(), strerror(port_obj->errno()));   #if 0    werror (describe_backtrace (backtrace()));   #endif    }    }       protected array(int) get_ipv6_sequence(string partition)
Roxen.git/server/base_server/roxen.pike:1894: Inside #if constant(SSL.sslfile)
  {    inherit Protocol;       // SSL context    SSL.context ctx = SSL.context();       int cert_failure;       protected void cert_err_unbind()    { -  if (bound) { +  if (bound > 0) {    port_obj->close();    report_warning ("TLS port %s closed.\n", get_url());    bound = 0;    }    }      #define CERT_WARNING(VAR, MSG, ARGS...) do { \    string msg = (MSG); \    array args = ({ARGS}); \    if (sizeof (args)) msg = sprintf (msg, @args); \
Roxen.git/server/base_server/roxen.pike:2164:    getvar ("ssl_key_file")->set_changed_callback (certificates_changed);    }       string _sprintf( )    {    return "SSLProtocol(" + get_url() + ")";    }   }   #endif    - mapping(string:Protocol) build_protocols_mapping() + mapping(string:program/*(Protocol)*/) build_protocols_mapping()   {    mapping protocols = ([]);    int st = gethrtime();    report_debug("Protocol handlers ... \b");   #ifndef DEBUG    class lazy_load( string prog, string name )    {    program real;    protected void realize()    {
Roxen.git/server/base_server/roxen.pike:2242:   #else    protocols[ s ] = lazy_load( ("../local/protocols/prot_"+s+".pike"),s );   #endif    };    }    report_debug("\bDone [%.1fms]\n", (gethrtime()-st)/1000.0 );    return protocols;   }       - mapping protocols; + mapping(string:program/*(Protocol)*/) protocols;      // prot:ip:port ==> Protocol.   mapping(string:mapping(string:mapping(int:Protocol))) open_ports = ([ ]);      // url:"port" ==> Protocol.   mapping(string:mapping(string:Configuration)) urls = ([]);   array sorted_urls = ({});      array(string) find_ips_for( string what )   {
Roxen.git/server/base_server/roxen.pike:2431:    url, urls[ url ]->conf->name);    return 0;    }    urls[ url ]->port->ref(url, urls[url]);    return 1;    }    else    urls[ url ]->port->unref( url );    }    -  Protocol prot; +  program prot;       if( !( prot = protocols[ protocol ] ) )    {    report_error(LOC_M(21, "Cannot register URL %s, "    "cannot find the protocol %s!")+"\n",    url, protocol);    return 0;    }       if( !port )
Roxen.git/server/base_server/roxen.pike:2518:    m[required_host][port]->ref(url, urls[url]);       urls[url]->port = m[required_host][port];    urls[ourl]->port = m[required_host][port];    continue; /* No need to open a new port */    }       if( !m[ required_host ] )    m[ required_host ] = ([ ]);    -  mixed err; -  if (err = catch { +  if (mixed err = catch {    m[ required_host ][ port ] =    prot( port, required_host,    // Don't complain if binding IPv6 ANY fails with    // EADDRINUSE after we've bound IPv4 ANY. At least on    // Linux, it seems that IPv4 and IPv6 can share the    // same interface, and in that case we're already done    // if we've bound the IPv4 ANY.    required_host == "::" && opened_ipv4_any_port);    }) {    failures++;
Roxen.git/server/base_server/roxen.pike:2548:    "%s\n",    url,    required_host||"ANY",    describe_backtrace(err)));    }    continue;    }       if (!required_host) opened_ipv4_any_port = 1;    -  if( !( m[ required_host ][ port ] ) ) +  Protocol prot_obj = m[required_host][port]; +  +  if( !prot_obj )    {    m_delete( m[ required_host ], port );    failures++;    if (required_host) {    report_warning(LOC_M(22, "Binding the port on IP %s failed\n"    " for URL %s!\n"),    required_host, url);    }    continue;    }    -  +  if (prot_obj->bound == -1) { +  // Got EADDRINUSE for the IPv6 case - see above. Just forget +  // about this one. +  m_delete (m[required_host], port); +  continue; +  }    -  urls[ url ]->port = m[ required_host ][ port ]; -  urls[ ourl ]->port = m[ required_host ][ port ]; -  m[ required_host ][ port ]->ref(url, urls[url]); +  urls[ url ]->port = prot_obj; +  urls[ ourl ]->port = prot_obj; +  prot_obj->ref(url, urls[url]);    -  if( !m[ required_host ][ port ]->bound ) +  if( !prot_obj->bound )    failures++;    }    if (failures == sizeof(required_hosts))    {    report_error(LOC_M(23, "Cannot register URL %s!")+"\n", url);    return 0;    }    sort_urls();    report_notice(" "+LOC_S(3, "Registered %s for %s")+"\n",    url, conf->query_name() );