示例#1
0
文件: pbx_spool.c 项目: OPSF/uClinux
static int scan_service(char *fn, time_t now, time_t atime)
{
	struct outgoing *o;
	FILE *f;
	o = malloc(sizeof(struct outgoing));
	if (o) {
		init_outgoing(o);
		f = fopen(fn, "r+");
		if (f) {
			if (!apply_outgoing(o, fn, f)) {
#if 0
				printf("Filename: %s, Retries: %d, max: %d\n", fn, o->retries, o->maxretries);
#endif
				fclose(f);
				if (o->retries <= o->maxretries) {
					now += o->retrytime;
					if (o->callingpid && (o->callingpid == ast_mainpid)) {
						safe_append(o, time(NULL), "DelayedRetry");
						ast_log(LOG_DEBUG, "Delaying retry since we're currently running '%s'\n", o->fn);
						free_outgoing(o);
					} else {
						/* Increment retries */
						o->retries++;
						/* If someone else was calling, they're presumably gone now
						   so abort their retry and continue as we were... */
						if (o->callingpid)
							safe_append(o, time(NULL), "AbortRetry");

						safe_append(o, now, "StartRetry");
						launch_service(o);
					}
					return now;
				} else {
					ast_log(LOG_EVENT, "Queued call to %s/%s expired without completion after %d attempt%s\n", o->tech, o->dest, o->retries - 1, ((o->retries - 1) != 1) ? "s" : "");
					free_outgoing(o);
					remove_from_queue(o, "Expired");
					return 0;
				}
			} else {
				free_outgoing(o);
				ast_log(LOG_WARNING, "Invalid file contents in %s, deleting\n", fn);
				fclose(f);
				remove_from_queue(o, "Failed");
			}
		} else {
			free_outgoing(o);
			ast_log(LOG_WARNING, "Unable to open %s: %s, deleting\n", fn, strerror(errno));
			remove_from_queue(o, "Failed");
		}
	} else
		ast_log(LOG_WARNING, "Out of memory :(\n");
	return -1;
}
示例#2
0
文件: pppoed.c 项目: alhazred/onarm
/*
 * Dispatch a message from the tunnel driver.  It could be an actual
 * PPPoE message or just an event notification.
 */
static void
handle_input(uint32_t *ctrlbuf, int ctrllen, uint32_t *databuf, int datalen)
{
	poep_t *poep = (poep_t *)databuf;
	union ppptun_name ptn;
	int retv;
	struct strbuf ctrl;
	struct strbuf data;
	void *srvp;
	boolean_t launch;
	struct ppptun_control *ptc;

	if (ctrllen != sizeof (*ptc)) {
		logdbg("bogus %d byte control message from driver",
		    ctrllen);
		return;
	}
	ptc = (struct ppptun_control *)ctrlbuf;

	/* Switch out on event notifications. */
	switch (ptc->ptc_action) {
	case PTCA_TEST:
		logdbg("test reply for discriminator %X", ptc->ptc_discrim);
		return;

	case PTCA_CONTROL:
		break;

	case PTCA_DISCONNECT:
		logdbg("session %d disconnected on %s; send PADT",
		    ptc->ptc_rsessid, ptc->ptc_name);
		poep = poe_mkheader(pkt_output, POECODE_PADT,
		    ptc->ptc_rsessid);
		ptc->ptc_action = PTCA_CONTROL;
		ctrl.len = sizeof (*ptc);
		ctrl.buf = (caddr_t)ptc;
		data.len = poe_length(poep) + sizeof (*poep);
		data.buf = (caddr_t)poep;
		if (putmsg(tunfd, &ctrl, &data, 0) < 0) {
			logerr("putmsg PADT: %s", mystrerror(errno));
		} else {
			output_packets++;
		}
		return;

	case PTCA_UNPLUMB:
		logdbg("%s unplumbed", ptc->ptc_name);
		return;

	default:
		logdbg("unexpected code %d from driver", ptc->ptc_action);
		return;
	}

	/* Only PPPoE control messages get here. */

	input_packets++;
	if (datalen < sizeof (*poep)) {
		logdbg("incomplete PPPoE message from %s/%s",
		    ehost(&ptc->ptc_address), ptc->ptc_name);
		return;
	}

	/* Server handles only PADI and PADR; all others are ignored. */
	if (poep->poep_code == POECODE_PADI) {
		padi_packets++;
	} else if (poep->poep_code == POECODE_PADR) {
		padr_packets++;
	} else {
		loginfo("unexpected %s from %s",
		    poe_codename(poep->poep_code), ehost(&ptc->ptc_address));
		return;
	}
	logdbg("Recv from %s/%s: %s", ehost(&ptc->ptc_address), ptc->ptc_name,
	    poe_codename(poep->poep_code));

	/* Parse out service and formulate template reply. */
	retv = locate_service(poep, datalen, ptc->ptc_name, &ptc->ptc_address,
	    pkt_output, &srvp);

	/* Continue formulating reply */
	launch = B_FALSE;
	if (retv != 1) {
		/* Ignore initiation if we don't offer a service. */
		if (retv <= 0 && poep->poep_code == POECODE_PADI) {
			logdbg("no services; no reply");
			return;
		}
		if (retv == 0)
			(void) poe_add_str((poep_t *)pkt_output, POETT_NAMERR,
			    "No such service.");
	} else {
		/* Exactly one service chosen; if it's PADR, then we start. */
		if (poep->poep_code == POECODE_PADR) {
			launch = B_TRUE;
		}
	}
	poep = (poep_t *)pkt_output;

	/* Select control interface for output. */
	(void) strncpy(ptn.ptn_name, ptc->ptc_name, sizeof (ptn.ptn_name));
	if (strioctl(tunfd, PPPTUN_SCTL, &ptn, sizeof (ptn), 0) < 0) {
		logerr("PPPTUN_SCTL %s: %s", ptn.ptn_name, mystrerror(errno));
		return;
	}

	/* Launch the PPP service */
	if (launch && launch_service(tunfd, poep, srvp, ptc))
		sessions_started++;

	/* Send the reply. */
	ctrl.len = sizeof (*ptc);
	ctrl.buf = (caddr_t)ptc;
	data.len = poe_length(poep) + sizeof (*poep);
	data.buf = (caddr_t)poep;
	if (putmsg(tunfd, &ctrl, &data, 0) < 0) {
		logerr("putmsg %s: %s", ptc->ptc_name, mystrerror(errno));
	} else {
		output_packets++;
		logdbg("Send to   %s/%s: %s", ehost(&ptc->ptc_address),
		    ptc->ptc_name, poe_codename(poep->poep_code));
	}
}