"Fossies" - the Fresh Open Source Software Archive

Member "Pound-3.0.2/src/util.c" (28 Nov 2021, 5501 Bytes) of package /linux/www/Pound-3.0.2.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "util.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 3.0e_vs_3.0.1.

    1 /*
    2  * Pound - the reverse-proxy load-balancer
    3  * Copyright (C) 2002-2020 Apsis GmbH
    4  *
    5  * This file is part of Pound.
    6  *
    7  * Pound is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 3 of the License, or
   10  * (at your option) any later version.
   11  *
   12  * Pound is distributed in the hope that it will be useful,
   13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15  * GNU General Public License for more details.
   16  *
   17  * You should have received a copy of the GNU General Public License
   18  * along with this program.  If not, see <http://www.gnu.org/licenses/> .
   19  *
   20  * Contact information:
   21  * Apsis GmbH
   22  * P.O.Box
   23  * 8707 Uetikon am See
   24  * Switzerland
   25  * EMail: roseg@apsis.ch
   26  */
   27 
   28 #include    "pound.h"
   29 
   30 #ifdef HAVE_STDARG_H
   31 void
   32 logmsg(int level, const char *fmt, ...)
   33 {
   34     char    buf[MAXBUF];
   35     va_list ap;
   36 
   37     if(level > global.log_level)
   38         return;
   39     buf[MAXBUF - 1] = '\0';
   40     va_start(ap, fmt);
   41     vsnprintf(buf, MAXBUF - 1, fmt, ap);
   42     va_end(ap);
   43     if(global.log_level > 0)
   44         fprintf(stderr, "%s\n", buf);
   45     else
   46         syslog(global.log_facility | LOG_INFO, "%s", buf);
   47     return;
   48 }
   49 #else
   50 void
   51 logmsg(int level, const char *fmt, va_alist)
   52 va_dcl
   53 {
   54     char    buf[MAXBUF];
   55     va_list ap;
   56     struct tm   *t_now, t_res;
   57 
   58     if(level > global.log_level)
   59         return;
   60     buf[MAXBUF - 1] = '\0';
   61     va_start(ap);
   62     vsnprintf(buf, MAXBUF - 1, fmt, ap);
   63     va_end(ap);
   64     if(global.log_level > 0)
   65         fprintf(stderr, "%s\n", buf);
   66     else
   67         syslog(global.log_facility | LOG_INFO, "%s", buf);
   68     return;
   69 }
   70 #endif
   71 
   72 void *
   73 thr_resurrect(void *arg)
   74 {
   75     BACKEND **dead_be, *t_be;
   76     int     n_be, i, j, flags;
   77     struct pollfd    *dead_poll;
   78     char    be_addr[NI_MAXHOST];
   79 
   80     logmsg(1, "Starting resurrector thread %s:%d", __FILE__, __LINE__);
   81     for(;;) {
   82         sleep(RESURRECT_CYCLE - RESURRECT_TO);
   83         logmsg(2, "Resurrect: wake-up %s:%d", __FILE__, __LINE__);
   84         for(n_be = 0, i = 0; i < backends_len; i++)
   85             if(backends[i].is_dead)
   86                 n_be++;
   87         if(n_be == 0)
   88             continue;
   89         if((dead_be = calloc(n_be, sizeof(BACKEND *))) == NULL) {
   90             logmsg(0, "resurrect: out of memory");
   91             continue;
   92         }
   93         if((dead_poll = calloc(n_be, sizeof(struct pollfd))) == NULL) {
   94             free(dead_be);
   95             logmsg(0, "resurrect: out of memory");
   96             continue;
   97         }
   98         for(i = 0, j = 0; i < backends_len && j < n_be; i++)
   99             if(backends[i].is_dead) {
  100                 dead_poll[j].fd = socket(backends[i].addr->ai_family, SOCK_STREAM, 0);
  101                 flags = fcntl(dead_poll[j].fd, F_GETFL, &flags);
  102                 fcntl(dead_poll[j].fd, F_SETFL, flags | O_NONBLOCK);
  103                 if(!connect(dead_poll[j].fd, backends[i].addr->ai_addr, backends[i].addr->ai_addrlen)) {
  104                     logmsg(2, "Resurrect: backend %d immediate connect %s:%d", i, __FILE__, __LINE__);
  105                     backends[i].is_dead = 0;
  106                     close(dead_poll[j].fd);
  107                     continue;
  108                 }
  109                 if(errno != EINPROGRESS) {
  110                     backends[i].is_dead = 1;
  111                     close(dead_poll[j].fd);
  112                     continue;
  113                 }
  114                 dead_poll[j].events = POLLOUT;
  115                 dead_be[j++] = &backends[i];
  116             }
  117         n_be = j;
  118         sleep(RESURRECT_TO);
  119         logmsg(2, "Resurrect: check backends %s:%d", i, __FILE__, __LINE__);
  120         poll(dead_poll, n_be, 1);
  121         for(i = 0; i < n_be; i++) {
  122             if(dead_poll[i].revents & POLLOUT) {
  123                 dead_be[i]->is_dead = 0;
  124                 getnameinfo(dead_be[i]->addr->ai_addr, dead_be[i]->addr->ai_addrlen, be_addr, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
  125                 logmsg(0, "Backend %s resurrected", be_addr);
  126             }
  127             close(dead_poll[i].fd);
  128         }
  129         free(dead_be);
  130         free(dead_poll);
  131     }
  132 }
  133 
  134 void
  135 time_stamp(char *buf)
  136 {
  137     time_t      t_now;
  138     struct tm   *s_now;
  139 
  140     t_now = time(NULL);
  141     s_now = localtime(&t_now);
  142     if(s_now == NULL) {
  143         *buf = '\0';
  144         return;
  145     }
  146     strftime(buf, MAXBUF, "%c", s_now);
  147     return;
  148 }
  149 
  150 int
  151 do_sni(void *data, mbedtls_ssl_context *ctx, const unsigned char *host_name, size_t host_len)
  152 {
  153     char    *name;
  154     int     i, j;
  155     SNI     **sni;
  156 
  157     logmsg(1, "%lX start sni %s:%d", pthread_self(), __FILE__, __LINE__);
  158     sni = (SNI **)data;
  159     if((name = malloc(host_len + 1)) == NULL) {
  160         logmsg(0, "SNI: out of memory!");
  161         return 0;
  162     }
  163     memset(name, '\0', host_len + 1);
  164     strncpy(name, host_name, host_len);
  165     logmsg(4, "%lX sni for %s %s:%d", pthread_self(), name, __FILE__, __LINE__);
  166     for(i = 0; sni[i] != NULL; i++)
  167     for(j = 0; j < sni[i]->host_len; j++)
  168         if(!regexec(&sni[i]->host[j], name, 0, NULL, REG_ICASE)) {
  169             logmsg(2, "%lX: found match at %d %s:%d", pthread_self(), j, __FILE__, __LINE__);
  170             return mbedtls_ssl_set_hs_own_cert(ctx, &sni[i]->certificate, &sni[i]->key);
  171         }
  172     /* if no match found: use the default certificate (from conf, aka the first sni) and let the client figure it out */
  173     logmsg(2, "%lX %s: no match found %s:%d", pthread_self(), name, __FILE__, __LINE__);
  174     return 0;
  175 }