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; }