--------------------- PatchSet 3348 Date: 2001/11/20 22:55:51 Author: jkay Branch: push Tag: (none) Log: update forwarding support. Members: src/dist.c:1.1->1.1.2.1 --- /dev/null Wed Feb 14 00:55:47 2007 +++ squid/src/dist.c Wed Feb 14 00:56:33 2007 @@ -0,0 +1,157 @@ +/* + * $Id: dist.c,v 1.1.2.1 2001/11/20 22:55:51 jkay Exp $ + * + * Distribution network algorithm. + * + * AUTHOR: Jon Kay, 1997 + * + * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ + * -------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from the + * Internet community. Development is led by Duane Wessels of the + * National Laboratory for Applied Network Research and funded by + * the National Science Foundation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include "squid.h" + +static void distUpdate(Updatee *u); + +static char urlbuf[MAX_URL + 48]; + + +/* Updatee management */ + +/* Create new updatee ds & add to object's updatee list */ +Updatee * +distNewUpdatee(StoreEntry *entry, struct in_addr host, int dport) +{ + Updatee *u; + + /* Don't add a client if it isn't interested in updates */ + if (dport == 0) + return(NULL); + + /* Make sure new guy isn't already on list */ + for (u = entry->updatees; u; u = u->next) { + if (u->saddr.sin_addr.s_addr == host.s_addr + && u->saddr.sin_port == dport) + return(u); + } + + /* Need new updatee, alloc and add to list */ + u = xcalloc(sizeof(*u), 1); + u->next = entry->updatees; + u->entry = entry; + u->saddr.sin_family = AF_INET; + u->saddr.sin_addr = host; + u->saddr.sin_port = dport; + u->lastmod = entry->lastmod; + entry->updatees = u; + return(u); +} + +void +distDelUpdatee(StoreEntry *entry, struct sockaddr_in *sin) +{ + Updatee *i, **optr; + + optr = &entry->updatees; + for (i = entry->updatees; i; i = i->next) { + if (i->saddr.sin_addr.s_addr == sin->sin_addr.s_addr + && i->saddr.sin_port == sin->sin_port) { + (*optr) = i->next; + xfree(i); + } + optr = &i->next; + } +} + +void +distDelUpdatees(Updatee *u) +{ + Updatee *nu; + + for ( ; u; u = nu) { + nu = u->next; + xfree(u); + } +} + + +/* Code to distribute contents of entry to updatees */ + +static void +distUpdate(Updatee *u) +{ + if (u->lastmod >= u->entry->lastmod) + /* Already has this version */ + return; + u->lastmod = u->entry->lastmod; /* Mark version being xferred */ + ++statCounter.push.dists; + + u->p = putSend(u->entry, &u->saddr, (PF *) 0, 0, 1 /* dodist */); +} + +/* Distribute entry contents to anybody interested */ +void +distEntryUpdate(StoreEntry *entry, request_t *req, struct sockaddr_in *peer) +{ + struct sockaddr_in *me = &Config.Sockaddr.http->s; + Updatee *u; + + /* Open distribution socket to everybody interested */ + for (u = entry->updatees; u; u = u->next) { + if (!req || !req->dport || req->dport != u->saddr.sin_port + || peer->sin_addr.s_addr != me->sin_addr.s_addr) + /* Send if got a dist and it isn't to where we got this update */ + distUpdate(u); + } +} + + +/* Best-case object consistency support */ + +/* Change url from http: to httpdist1234: */ +/* Note: returns pointer to static buffer - contents change on next call. */ +char * +distifyUrl(char *url) +{ + char distbuf[20]; /* dist string holder */ + int plen, poff; + char *eop; + + /* Find the end of the protocol field */ + if ((eop = strchr(url, ':')) == NULL) + /* Give up if not of form http://... */ + return(url); + poff = eop - url; + + snprintf(distbuf, sizeof(distbuf), "dist%d", + ntohs(Config.Sockaddr.http->s.sin_port)); + plen = strlen(distbuf); + + /* Assemble the new URL */ + xmemcpy(urlbuf, url, poff); + xmemcpy(urlbuf + poff, distbuf, plen); + xstrncpy(urlbuf + poff + plen, url + poff, MAX_URL); + + return(urlbuf); +} +