⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lwld.c

📁 g729 coding ipaddressing
💻 C
📖 第 1 页 / 共 4 页
字号:
	    if (cstat >= 0) {
		if (send(sock, q->q_pkt, q->q_rll, 0) < 0) {
		    perror("forwarding look who's listening source ID message");
		    break;
		} else {
		    Lock(fwdlistLock);
		    f->head = q->next;
		    if (f->head == NULL) {
			f->tail = NULL;
		    }
		    free(q);
		    f->queuelen--;
		    if (f->queuelen < 0) {
			fprintf(stderr, "%s: forward queue underflow to %s.\n", 
			    prog, f->sitename);
			f->queuelen = 0;
		    }
		    Unlock(fwdlistLock);
		    if (debugging) {
			fprintf(stderr, "%s: forwarded packet to server %s. Queue length now %d.\n",
			    prog, f->sitename, f->queuelen);
		    }
		}
	    } else {

		/* As LWL servers go up and down, failures to connect
		   to forwarding destinations are not uncommon.  Further,
		   while a server is down, we get here on every packet
		   we attempt to forward.  To avoid blithering all
		   over the log, we only note such failure if in
		   prolix or debugging mode. */

		if (prolix || debugging) {
		    perror("connecting forwarding socket");
		}
		break;
	    }
	    close(sock);
	    sock = -1;
	}

	/* If we bailed out of the above loop due to an error in
	   forwarding the packet, make sure the socket is closed. */

	if (sock >= 0) {
	    close(sock);
	    sock = -1;
	}
	sleep(ForwarderSleep);
    }

#ifdef DBTHREAD
fprintf(stderr, "Exited forwarder thread for %s\n", f->sitename);
#endif
    f->status = -1;		      /* Forwarder terminated */
    return NULL;
}
#endif

/*  FORWARDLIST  --  Parse a list of servers to forward packets to. */

static void forwardList(cp)
  char *cp;
{
#ifdef THREADS
    struct forwarder *f;
    char *ep, *np;

    while (TRUE) {
	while (*cp != 0 && isspace(*cp)) {
	    cp++;
	}
	if (*cp == 0) {
	    break;
	}
	if ((np = strchr(cp, ',')) != NULL) {
	    *np++ = 0;
	}
	f = (struct forwarder *) malloc(sizeof(struct forwarder));
	if (f != NULL) {
	    bzero(f, sizeof(struct forwarder));
	    f->status = 1;
	    f->sitename = cp;
	    f->port = Internet_Port + 2;
	    if ((ep = strchr(cp, ':')) != NULL) {
		*ep = 0;
		f->port = atoi(ep + 1);
	    }
	    f->next = fwdlist;
	    fwdlist = f;
	    if (pthread_create(&(f->thread), &detached, forwarder_thread, f) != 0) {
		fprintf(stderr, "%s: Cannot launch forwarder thread for %s: %s",
		    prog, cp, strerror(errno));
		free(f);
	    }
	} else {
	    fprintf(stderr, "%s: out of memory allocating forwarder for %s\n",
		prog, cp);
	    break;
	}
	if (np == NULL) {
	    break;
	}
	cp = np;
    }
#else
    struct hostent *h;
    char *ep, *np;
    long iadr;
    int n;

    lookhost.sin_family = AF_INET;

    while (lwl_nsites < LWL_MAX_SITES) {
	n = lwl_nsites;
	while (*cp != 0 && isspace(*cp)) {
	    cp++;
	}
	if (*cp == 0) {
	    break;
	}
	if ((np = strchr(cp, ',')) != NULL) {
	    *np++ = 0;
	}
	lwl_ports[lwl_nsites] = Internet_Port + 2;
	if ((ep = strchr(cp, ':')) != NULL) {
	    *ep = 0;
	    lwl_ports[lwl_nsites] = atoi(ep + 1);
	}
	if (isdigit(*cp) && (iadr = inet_addr(cp)) != -1) {
	    bcopy((char *) &iadr, (char *) (&lwl_sites[lwl_nsites]),
		  sizeof iadr);
	    lwl_nsites++;
	} else {
	    h = gethostbyname(cp);
	    if (h != NULL) {
		bcopy((char *) (h->h_addr), 
		      (char *) (&lwl_sites[lwl_nsites]),
		      sizeof(unsigned long));
		lwl_nsites++;
	    } else {
		fprintf(stderr, "%s: warning, forward destination %s unknown.\n",
		    prog, cp);
	    }
	}
	if (debugging && lwl_nsites > n) {
	    fprintf(stderr, "%s: forwarding to LWL server %s: %s.\n", prog,
		inet_ntoa(lwl_sites[n]), cp);
	}
	if (np == NULL) {
	    break;
	}
	cp = np;
    }
#endif
}

/*  FORWARDLWLMESSAGE  --  If forwarding is enabled, pass this message
			   on to hosts in our forward list, changing the
			   packet protocol header to indicate the packet
			   was forwarded and appending the IP address
			   of the originating host to the end of the packet. */

static void forwardLwlMessage(zp, rll, addr)
  char *zp;			/* Packet address */
  int rll;			/* Total packet length (starting at zp) */
  struct in_addr addr;		/* IP address of originator of this packet */
{
    int i, sock, wasfwd = FALSE;

    zp[0] |= 0x40;		/* Set forwarded packet flag bit */
    bcopy(&addr, zp + rll, sizeof(struct in_addr));
    rll += sizeof(struct in_addr);
#ifdef THREADS
    {
	struct forwarder *f = fwdlist;

	while (f != NULL) {
	    if (f->status == 0) {
		if (f->queuelen > ForwarderMaxQ) {
		    fprintf(stderr, "%s: %s queue too long; forward message discarded.\n",
			prog, f->sitename);
		} else {
		    struct lwl_queueitem *q = (struct lwl_queueitem *) malloc(
			sizeof(struct lwl_queueitem) + rll);

		    if (q != NULL) {
			q->next = NULL;
			q->q_rll = rll;
			bcopy(zp, q->q_pkt, rll);
			Lock(fwdlistLock);
			f->queuelen++;
			if (f->head == NULL) {
			    f->head = f->tail = q;
			} else {
			    f->tail->next = q;
			    f->tail = q;
			}
			Unlock(fwdlistLock);
		    }
		}
	    }
	    f = f->next;
	}
    }
#else
    for (i = 0; i < lwl_nsites; i++) {
	if (lwl_ports[i] >= 0) {
	    int cstat;

	    sock = socket(AF_INET, SOCK_STREAM, 0);
	    if (sock < 0) {
		perror("opening forwarding socket");
		continue;
	    }

	    lookhost.sin_port = htons(lwl_ports[i]);
	    bcopy((char *) (&lwl_sites[i]), (char *) &lookhost.sin_addr.s_addr,
		  sizeof lookhost.sin_addr.s_addr);

	    errno = 0;
	    do {
		cstat = connect(sock, (struct sockaddr *) &(lookhost), sizeof lookhost);
		if (cstat >= 0) {
		    break;
		}
	    } while (errno == EINTR);
	    if (cstat >= 0) {
		if (send(sock, zp, rll, 0) < 0) {
		    perror("forwarding look who's listening source ID message");
		} else {
		    if (debugging) {
			fprintf(stderr, "%s: forwarded packet to server %s.\n",
			    prog, inet_ntoa(lookhost.sin_addr));
		    }
		}
	    } else {

		/* As LWL servers go up and down, failures to connect
		   to forwarding destinations are not uncommon.  Further,
		   while a server is down, we get here on every packet
		   we attempt to forward.  To avoid blithering all
		   over the log, we only note such failure if in
		   prolix or debugging mode. */

		if (prolix || debugging) {
		    perror("connecting forwarding socket");
		}
	    }
	    close(sock);
	}
    }
#endif
}

/*  QUERYMATCH	--  Determing if query matches a given item.  */

static int queryMatch(q, l)
  char *q;
  struct lwl *l;
{
    char ts[1024];
    int exact = FALSE;
    char *s;

    s = ts;

    /* We give preference to an E-mail address, if given, to a
       canonical address since it's the user's best known published
       identity on the net.  This, of course, runs the risk of
       spoofing, but since anybody can send us an RTCP packet with
       whatever cname they like, there's no added security in insisting
       on using it. */

    strcpy(s, (l->email == NULL) ? l->cname : l->email);
    lcase(s);

    if (*q == '*') {
	exact = TRUE;
	q++;
    }
    if (*s == '*') {
	exact = TRUE;
	s++;
    }
    /* Even if we're using the E-mail name, allow an asterisk on the
       canonical name to require an exact match. */
    if (l->cname[0] == '*') {
	exact = TRUE;
    }

    if (exact) {
	return strcmp(s, q) == 0;
    }

    if (strstr(s, q)) {
	return TRUE;
    }
    if (l->name != NULL) {
	strcpy(s, l->name);
	lcase(s);
	if (strstr(s, q)) {
	   return TRUE;
	}
    }
    return FALSE;
}

/*  RELEASE  --  Check for connections who haven't send us an update
		 once in the timeout interval and close them.  They
		 probably went away without having the courtesy to
		 say good-bye.	*/

static void release()
{
    struct lwl *lw, *llr = NULL, *lf;
    time_t now = time(NULL);

    LockConn();
    lw = conn;
    while (lw != NULL) {
	if ((now - lw->ltime) > TimeoutTime) {
	    lf = lw;
	    if (llr == NULL) {
		conn = lw->next;
		lw = conn;
	    } else {
		llr->next = lw->next;
		lw = lw->next;
	    }
/*
fprintf(stderr, "\nTiming out:\n");
dumpLwl(stderr, lf);
*/
	    if (verbose) {
		logLwl(lf, "Timeout: ");
	    }
	    htmlChange = TRUE;
	    destroyLwl(lf);
	} else {
	    llr = lw;
	    lw = lw->next;
	}
    }
    UnlockConn();
#ifndef THREADS
    updHTML();			      /* Update HTML if something's changed recently */
    signal(SIGALRM, release);	      /* Reset signal to handle timeout (Sys V) */
    alarm(TockTock);		      /* Reset the timer */
#endif
}

/*  PLUMBER  --  Catch SIGPIPE signal which occurs when remote user
		 disconnects before we try to send the reply.  */

static void plumber()
{
#ifdef DBTHREAD
fprintf(stderr, "Caught SIGPIPE--continuing.\n");
#endif
    signal(SIGPIPE, plumber);	      /* Reset signal just in case */
}

/*  EXITING  --  Release socket in case of termination.  */

static void exiting()
{
#ifdef DBTHREAD
fprintf(stderr, "Exiting.\n");
#endif
    shutdown(sock, 2);
    close(sock);
    exit(0);
}

/*  PROG_NAME  --  Extract program name from argv[0].  */

static char *prog_name(arg)
  char *arg;
{
    char *cp = strrchr(arg, '/');

    return (cp != NULL) ? cp + 1 : arg;
}

/*  USAGE  --  Print how-to-call information.  */

static void usage()
{
    V fprintf(stderr, "%s  --  Speak Freely: Look Who's Listening Server.\n", prog);
#ifdef THREADS
    V fprintf(stderr, " 	      (Multi-threaded version)\n");
#endif
    V fprintf(stderr, " 	      %s.\n", Relno);
    V fprintf(stderr, "\n");
    V fprintf(stderr, "Usage: %s [options]\n", prog);
    V fprintf(stderr, "Options:\n");
    V fprintf(stderr, " 	  -D	     Debugging output on stderr\n");
    V fprintf(stderr, " 	  -Fserv,... Forward to listed servers\n");
    V fprintf(stderr, " 	  -Hpath     Write HTML status on base path\n");
    V fprintf(stderr, " 	  -Insec     Interval between HTML updates\n");
    V fprintf(stderr, " 	  -Mfile     Load server message from file\n");
    V fprintf(stderr, " 	  -Pport     Listen on given port\n");
    V fprintf(stderr, " 	  -U	     Print this message\n");
    V fprintf(stderr, " 	  -V[V]      List connections and disconnects [-VV: all packets]\n");
#ifdef HEXDUMP
    V fprintf(stderr, " 	  -X	     Dump packets in hex\n");
#endif
    V fprintf(stderr, " 	  -Zpath     Write HTML private directory on base path\n");
    V fprintf(stderr, "\n");
    V fprintf(stderr, "by John Walker\n");
    V fprintf(stderr, "   WWW:	  http://www.fourmilab.ch/\n");
}

/*  ADD_SDES_ITEM  --  Include an SDES item in a reply packet,
		       pruning illegal characters and content,
		       checking for packet overflow, and updating
		       the packet pointer.  */

#define addSDES(item, text) add_sdes_item(item, text, &ap)

static int add_sdes_item(item, text, app)
  int item;
  char *text;
  char **app;
{
    int l, state;
    char prune[258];
    char *ap = *app, *hp, *op = prune;

    /* Copy the text to the "prune" buffer using a simple
       state machine parser, filtering extraneous
       information. */

    state = 0;

    while (*text) {
	unsigned char ch = (unsigned char) *text++;

	if (item == RTCP_SDES_PRIV && op == prune) {
	    /* Allow PRIV item binary prefix field to pass. */
	    *op++ = (char) ch;
	    continue;
	}

	/* Discard non-graphic characters (ISO 8859 standard). */

	if (!isspace(ch) && (ch < ' ' || (ch > '~' && ch < 161))) {
	    continue;
	}

	switch (state) {

	    case 0:		      /* Skipping initial white space */
		if (!isspace(ch)) {
		    state = 1;
		} else {
		    break;
		}
		/* Note fall-through */

	    case 1:		      /* Transcribing to output */
s1:		if (ch == '<') {
		    if ((hp = strchr(text, '>')) != NULL) {
			text = hp + 1;
			if (op > prune && isspace(op[-1])) {
			    state = 2;
			}
			continue;
		    }
		}
		if (isspace(ch)) {
		    ch = ' ';	      /* Convert all white space into blanks */
		    state = 2;
		}
		*op++ = (char) ch;
		break;

	    case 2:		      /* Collapsing multiple white space */
		if (!isspace(ch)) {
		    state = 1;
		    goto s1;
		}
		break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -