Poundいじって遊んでみた

PoundではRemoteAddressが使えないって騒いでいる人がいたのでつけてみた。
そんなことしたければapacheでやればいいじゃんって話だけど。

  • 機能

コンフィグのService部分にRemoteAddress IPと書くとマッチしたIPしかServiceに振り分けられなくなる。
RemoteAddressはひとつのServiceに複数かけて、一応Regexが使える。

IPアドレスの癖にネットワークアドレスが書けないあたりが残念な感じ。
そのうちCのネットワーク周りの勉強も兼ねて書き換えたい。

PoundのConfigでRemoteAddressを使えるようにするパッチ

$ diff -uar --exclude=config.log --exclude=config.status Pound-2.4.1 Pound-2.4.1.RemoteAddress/
diff -uar --exclude=config.log --exclude=config.status Pound-2.4.1/config.c Pound-2.4.1.RemoteAddress/config.c
--- Pound-2.4.1/config.c        2008-04-05 18:45:43.000000000 +0900
+++ Pound-2.4.1.RemoteAddress/config.c  2008-05-02 00:51:48.000000000 +0900
@@ -78,6 +78,7 @@
 static regex_t  Service, ServiceName, URL, HeadRequire, HeadDeny, BackEnd, Emergency, Priority, HAport, HAportAddr;
 static regex_t  Redirect, RedirectN, TimeOut, Session, Type, TTL, ID, DynScale;
 static regex_t  ClientCert, AddHeader, Ciphers, CAlist, VerifyList, CRLlist, NoHTTPS11;
+static regex_t  RemoteAddress;
 static regex_t  Grace;

 static regmatch_t   matches[5];
@@ -435,6 +436,28 @@
                 logmsg(LOG_ERR, "line %d: URL bad pattern \"%s\" - aborted", n_lin, lin + matches[1].rm_so);
                 exit(1);
             }   
+        } else if(!regexec(&RemoteAddress, lin, 4, matches, 0)) {
+            if(res->remote_address) {
+                for(m = res->remote_address; m->next; m = m->next)
+                    ;
+                if((m->next = (MATCHER *)malloc(sizeof(MATCHER))) == NULL) {
+                    logmsg(LOG_ERR, "line %d: RemoteAddress config: out of memory - aborted", n_lin);
+                    exit(1);
+                }
+                m = m->next;
+            } else {
+                if((res->remote_address = (MATCHER *)malloc(sizeof(MATCHER))) == NULL) {
+                    logmsg(LOG_ERR, "line %d: RemoteAdrress config: out of memory - aborted", n_lin);
+                    exit(1);
+                }
+                m = res->remote_address;
+            }
+            memset(m, 0, sizeof(MATCHER));
+            lin[matches[1].rm_eo] = '\0';
+            if(regcomp(&m->pat, lin + matches[1].rm_so, REG_ICASE | REG_NEWLINE | REG_EXTENDED)) {
+                logmsg(LOG_ERR, "line %d: RemoteAddress bad pattern \"%s\" - aborted", n_lin, lin + matches[1].rm_so);
+                exit(1);
+            }
         } else if(!regexec(&HeadRequire, lin, 4, matches, 0)) {
             if(res->req_head) {
                 for(m = res->req_head; m->next; m = m->next)
@@ -1213,6 +1236,7 @@
     || regcomp(&ListenHTTPS, "^[ \t]*ListenHTTPS[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
     || regcomp(&End, "^[ \t]*End[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
     || regcomp(&Address, "^[ \t]*Address[ \t]+([^ \t]+)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
+    || regcomp(&RemoteAddress, "^[ \t]*RemoteAddress[ \t]+([^ \t]+)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
     || regcomp(&Port, "^[ \t]*Port[ \t]+([1-9][0-9]*)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
     || regcomp(&Cert, "^[ \t]*Cert[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
     || regcomp(&xHTTP, "^[ \t]*xHTTP[ \t]+([01234])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
@@ -1367,6 +1391,7 @@
     regfree(&ListenHTTPS);
     regfree(&End);
     regfree(&Address);
+    regfree(&RemoteAddress);
     regfree(&Port);
     regfree(&Cert);
     regfree(&xHTTP);
diff -uar --exclude=config.log --exclude=config.status Pound-2.4.1/http.c Pound-2.4.1.RemoteAddress/http.c
--- Pound-2.4.1/http.c  2008-04-05 18:45:43.000000000 +0900
+++ Pound-2.4.1.RemoteAddress/http.c    2008-05-01 22:00:40.000000000 +0900
@@ -719,7 +719,7 @@
         }

         /* check that the requested URL still fits the old back-end (if any) */
-        if((svc = get_service(lstn, url, &headers[1])) == NULL) {
+        if((svc = get_service(lstn, url, &headers[1], &from_host)) == NULL) {
             addr2str(caddr, MAXBUF - 1, &from_host, 1);
             logmsg(LOG_NOTICE, "(%lx) e503 no service \"%s\" from %s", pthread_self(), request, caddr);
             err_reply(cl, h503, lstn->err503);
diff -uar --exclude=config.log --exclude=config.status Pound-2.4.1/pound.h Pound-2.4.1.RemoteAddress/pound.h
--- Pound-2.4.1/pound.h 2008-04-05 18:45:43.000000000 +0900
+++ Pound-2.4.1.RemoteAddress/pound.h   2008-05-02 01:01:43.000000000 +0900
@@ -317,6 +317,7 @@
     char                name[KEY_SIZE + 1]; /* symbolic name */
     MATCHER             *url,       /* request matcher */
                         *req_head,  /* required headers */
+                        *remote_address, /* request remote_address */
                         *deny_head; /* forbidden headers */
     BACKEND             *backends;
     BACKEND             *emergency;
@@ -442,7 +443,7 @@
 /*
  * Find the right service for a request
  */
-extern SERVICE  *get_service(const LISTENER *, const char *, char **const);
+extern SERVICE  *get_service(const LISTENER *, const char *, char **const, const struct addrinfo *);

 /*
  * Find the right back-end for a request
diff -uar --exclude=config.log --exclude=config.status Pound-2.4.1/svc.c Pound-2.4.1.RemoteAddress/svc.c
--- Pound-2.4.1/svc.c   2008-04-05 18:45:43.000000000 +0900
+++ Pound-2.4.1.RemoteAddress/svc.c     2008-05-02 01:13:40.000000000 +0900
@@ -302,7 +302,7 @@
 }

 static int
-match_service(const SERVICE *svc, const char *request, char **const headers)
+match_service(const SERVICE *svc, const char *request, char **const headers, const char *caddr)
 {   
     MATCHER *m;
     int     i, found;
@@ -312,6 +312,14 @@
         if(regexec(&m->pat, request, 0, NULL, 0))
             return 0;

+    /* check for remote address */
+    for(m = svc->remote_address; m; m = m->next){
+        if(!regexec(&m->pat, caddr, 0, NULL, 0))
+            break;
+        if(! m->next)
+            return 0;
+    }
+
     /* check for required headers */
     for(m = svc->req_head; m; m = m->next) {
         for(found = i = 0; i < (MAXHEADERS - 1) && !found; i++)
@@ -337,14 +345,15 @@
  * Find the right service for a request
  */
 SERVICE *
-get_service(const LISTENER *lstn, const char *request, char **const headers)
+get_service(const LISTENER *lstn, const char *request, char **const headers, const struct addrinfo *from_host)
 {   
     SERVICE *svc;
-
+    char    caddr[MAXBUF];
+    addr2str(caddr, MAXBUF - 1, from_host, 1);
     for(svc = lstn->services; svc; svc = svc->next) {
         if(svc->disabled)
             continue;
-        if(match_service(svc, request, headers))
+        if(match_service(svc, request, headers, caddr))
             return svc;
     }

@@ -352,7 +361,7 @@
     for(svc = services; svc; svc = svc->next) {
         if(svc->disabled)
             continue;
-        if(match_service(svc, request, headers))
+        if(match_service(svc, request, headers, caddr))
             return svc;
     }