示例#1
0
static void query_usetcp(adns_query qu, struct timeval now) {
  qu->state= query_tcpw;
  qu->timeout= now;
  timevaladd(&qu->timeout,TCPWAITMS);
  LIST_LINK_TAIL(qu->ads->tcpw,qu);
  adns__querysend_tcp(qu,now);
  adns__tcp_tryconnect(qu->ads,now);
}
示例#2
0
文件: mutex.c 项目: NZRS/bind9-collab
isc_result_t
isc_mutex_unlock_profile(isc_mutex_t *mp, const char *file, int line) {
	struct timeval unlock_t;

	UNUSED(file);
	UNUSED(line);

	if (mp->stats->cur_locker != NULL) {
		gettimeofday(&unlock_t, NULL);
		timevalsub(&unlock_t, &mp->stats->lock_t);
		timevaladd(&mp->stats->locked_total, &unlock_t);
		timevaladd(&mp->stats->cur_locker->locked_total, &unlock_t);
		mp->stats->cur_locker = NULL;
	}

	return ((pthread_mutex_unlock((&mp->mutex)) == 0) ? \
		ISC_R_SUCCESS : ISC_R_UNEXPECTED);
}
示例#3
0
文件: mutex.c 项目: NZRS/bind9-collab
isc_result_t
isc_mutex_lock_profile(isc_mutex_t *mp, const char *file, int line) {
	struct timeval prelock_t;
	struct timeval postlock_t;
	isc_mutexlocker_t *locker = NULL;
	int i;

	gettimeofday(&prelock_t, NULL);

	if (pthread_mutex_lock(&mp->mutex) != 0)
		return (ISC_R_UNEXPECTED);

	gettimeofday(&postlock_t, NULL);
	mp->stats->lock_t = postlock_t;

	timevalsub(&postlock_t, &prelock_t);

	mp->stats->count++;
	timevaladd(&mp->stats->wait_total, &postlock_t);

	for (i = 0; i < ISC_MUTEX_MAX_LOCKERS; i++) {
		if (mp->stats->lockers[i].file == NULL) {
			locker = &mp->stats->lockers[i];
			locker->file = file;
			locker->line = line;
			break;
		} else if (mp->stats->lockers[i].file == file &&
			   mp->stats->lockers[i].line == line) {
			locker = &mp->stats->lockers[i];
			break;
		}
	}

	if (locker != NULL) {
		locker->count++;
		timevaladd(&locker->wait_total, &postlock_t);
	}

	mp->stats->cur_locker = locker;

	return (ISC_R_SUCCESS);
}
示例#4
0
void adns__query_send( adns_query qu, struct timeval now )
{
	struct sockaddr_in servaddr;
	int serv, r;
	adns_state ads;

	assert( qu->state == query_tosend );
	if( ( qu->flags & adns_qf_usevc ) || ( qu->query_dglen > DNS_MAXUDP ) ) 
	{
		query_usetcp( qu, now );
		return;
	}
	if( qu->retries >= UDPMAXRETRIES ) 
	{
		adns__query_fail( qu, adns_s_timeout );
		return;
	}

	serv = qu->udpnextserver;
	os_memset( &servaddr, 0, sizeof( servaddr ) );

	ads = qu->ads;
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr = ads->servers[serv].addr;
	servaddr.sin_port = htons(DNS_PORT);

	r = os_sock_sendto( ads->udpsocket, (char *)qu->query_dgram, qu->query_dglen, 0,
		   ( const struct sockaddr * ) &servaddr, sizeof( servaddr ) );
	if( r < 0 && os_sock_errno == OS_SOCK_EMSGSIZE ) 
	{
		qu->retries = 0;
		query_usetcp( qu, now );
		return;
	}
	if( r < 0 && os_sock_errno!= OS_SOCK_EAGAIN )
		adns__warn( ads, serv, 0, "sendto failed: %s", os_sock_getlasterrorstring() );

	qu->timeout = now;
	timevaladd( &qu->timeout, UDPRETRYMS );
	qu->udpsent |= ( 1 << serv );
	qu->udpnextserver = ( serv + 1 ) % ads->nservers;
	qu->retries++;
	ALIST_LINK_TAIL( ads->udpw, qu );
}
示例#5
0
static int
pmtimer_resume(device_t dev)
{
	int pl;
	u_int second, minute, hour;
	struct timeval resume_time, tmp_time;

	/* modified for adjkerntz */
	pl = splsoftclock();
	timer_restore();		/* restore the all timers */
	inittodr(0);			/* adjust time to RTC */
	microtime(&resume_time);
	getmicrotime(&tmp_time);
	timevaladd(&tmp_time, &diff_time);

#ifdef FIXME
	/* XXX THIS DOESN'T WORK!!! */
	time = tmp_time;
#endif

#ifdef PMTIMER_FIXUP_CALLTODO
	/* Calculate the delta time suspended */
	timevalsub(&resume_time, &suspend_time);
	/* Fixup the calltodo list with the delta time. */
	adjust_timeout_calltodo(&resume_time);
#endif /* PMTIMER_FIXUP_CALLTODOK */
	splx(pl);
#ifndef PMTIMER_FIXUP_CALLTODO
	second = resume_time.tv_sec - suspend_time.tv_sec; 
#else /* PMTIMER_FIXUP_CALLTODO */
	/* 
	 * We've already calculated resume_time to be the delta between 
	 * the suspend and the resume. 
	 */
	second = resume_time.tv_sec; 
#endif /* PMTIMER_FIXUP_CALLTODO */
	hour = second / 3600;
	second %= 3600;
	minute = second / 60;
	second %= 60;
	log(LOG_NOTICE, "wakeup from sleeping state (slept %02d:%02d:%02d)\n",
		hour, minute, second);
	return (0);
}
示例#6
0
int
nanosleep(const struct timespec *ts, struct timespec *rts)
{
    struct timeval timeout, endtime, now;
    int rval;

    timeout.tv_sec = ts->tv_sec;
    timeout.tv_usec = ts->tv_nsec / 1000;
    if (rts != NULL) {
	gettimeofday(&endtime, NULL);
	timevaladd(&endtime, &timeout);
    }
    rval = select(0, NULL, NULL, NULL, &timeout);
    if (rts != NULL && rval == -1 && errno == EINTR) {
	gettimeofday(&now, NULL);
	timevalsub(&endtime, &now);
	rts->tv_sec = endtime.tv_sec;
	rts->tv_nsec = endtime.tv_usec * 1000;
    }
    return rval;
}
示例#7
0
int
nandbus_wait_ready(device_t dev, uint8_t *status)
{
	struct timeval tv, tv2;

	tv2.tv_sec = 0;
	tv2.tv_usec = 50 * 5000; /* 250ms */

	getmicrotime(&tv);
	timevaladd(&tv, &tv2);

	do {
		if (NANDBUS_GET_STATUS(dev, status))
			return (ENXIO);

		if (*status & NAND_STATUS_RDY)
			return (0);

		getmicrotime(&tv2);
	} while (timevalcmp(&tv2, &tv, <=));

	return (EBUSY);
}
示例#8
0
static int
nandsim_delay(struct nandsim_chip *chip, int timeout)
{
	struct nandsim_ev *ev;
	struct timeval delay;
	int tm;

	nand_debug(NDBG_SIM,"Chip[%d] Set delay: %d", chip->chip_num, timeout);

	ev = create_event(chip, NANDSIM_EV_TIMEOUT, 0);
	if (!ev)
		return (-1);

	chip->sm_state = NANDSIM_STATE_TIMEOUT;
	tm = (timeout/10000) * (hz / 100);
	if (callout_reset(&chip->ns_callout, tm, nandsim_callout_eh, ev))
		return (-1);

	delay.tv_sec = chip->read_delay / 1000000;
	delay.tv_usec = chip->read_delay % 1000000;
	timevaladd(&chip->delay_tv, &delay);

	return (0);
}
示例#9
0
ACPI_STATUS
AcpiOsWaitSemaphore(ACPI_HANDLE Handle, UINT32 Units, UINT16 Timeout)
{
#ifndef ACPI_NO_SEMAPHORES
    ACPI_STATUS			result;
    struct acpi_semaphore	*as = (struct acpi_semaphore *)Handle;
    int				rv, tmo;
    struct timeval		timeouttv, currenttv, timelefttv;
    AS_LOCK_DECL;

    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);

    if (as == NULL)
	return_ACPI_STATUS (AE_BAD_PARAMETER);

    if (cold)
	return_ACPI_STATUS (AE_OK);

#if 0
    if (as->as_units < Units && as->as_timeouts > 10) {
	kprintf("%s: semaphore %p too many timeouts, resetting\n", __func__, as);
	AS_LOCK(as);
	as->as_units = as->as_maxunits;
	if (as->as_pendings)
	    as->as_resetting = 1;
	as->as_timeouts = 0;
	wakeup(as);
	AS_UNLOCK(as);
	return_ACPI_STATUS (AE_TIME);
    }

    if (as->as_resetting)
	return_ACPI_STATUS (AE_TIME);
#endif

    /* a timeout of ACPI_WAIT_FOREVER means "forever" */
    if (Timeout == ACPI_WAIT_FOREVER) {
	tmo = 0;
	timeouttv.tv_sec = ((0xffff/1000) + 1);	/* cf. ACPI spec */
	timeouttv.tv_usec = 0;
    } else {
	/* compute timeout using microseconds per tick */
	tmo = (Timeout * 1000) / (1000000 / hz);
	if (tmo <= 0)
	    tmo = 1;
	timeouttv.tv_sec  = Timeout / 1000;
	timeouttv.tv_usec = (Timeout % 1000) * 1000;
    }

    /* calculate timeout value in timeval */
    getmicrouptime(&currenttv);
    timevaladd(&timeouttv, &currenttv);

    AS_LOCK(as);
    ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
	"get %d units from semaphore %p (has %d), timeout %d\n",
	Units, as, as->as_units, Timeout));
    for (;;) {
	if (as->as_maxunits == ACPI_NO_UNIT_LIMIT) {
	    result = AE_OK;
	    break;
	}
	if (as->as_units >= Units) {
	    as->as_units -= Units;
	    result = AE_OK;
	    break;
	}

	/* limit number of pending treads */
	if (as->as_pendings >= ACPI_SEMAPHORES_MAX_PENDING) {
	    result = AE_TIME;
	    break;
	}

	/* if timeout values of zero is specified, return immediately */
	if (Timeout == 0) {
	    result = AE_TIME;
	    break;
	}

	ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
	    "semaphore blocked, calling ssleep(%p, %p, %d, \"acsem\", %d)\n",
	    as, &as->as_spin, PCATCH, tmo));

	as->as_pendings++;

	if (acpi_semaphore_debug) {
	    kprintf("%s: Sleep %jd, pending %jd, semaphore %p, thread %jd\n",
		__func__, (intmax_t)Timeout,
		(intmax_t)as->as_pendings, as,
		(intmax_t)AcpiOsGetThreadId());
	}

	rv = ssleep(as, &as->as_spin, PCATCH, "acsem", tmo);

	as->as_pendings--;

#if 0
	if (as->as_resetting) {
	    /* semaphore reset, return immediately */
	    if (as->as_pendings == 0) {
		as->as_resetting = 0;
	    }
	    result = AE_TIME;
	    break;
	}
#endif

	ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "ssleep(%d) returned %d\n", tmo, rv));
	if (rv == EWOULDBLOCK) {
	    result = AE_TIME;
	    break;
	}

	/* check if we already awaited enough */
	timelefttv = timeouttv;
	getmicrouptime(&currenttv);
	timevalsub(&timelefttv, &currenttv);
	if (timelefttv.tv_sec < 0) {
	    ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "await semaphore %p timeout\n",
		as));
	    result = AE_TIME;
	    break;
	}

	/* adjust timeout for the next sleep */
	tmo = (timelefttv.tv_sec * 1000000 + timelefttv.tv_usec) /
	    (1000000 / hz);
	if (tmo <= 0)
	    tmo = 1;

	if (acpi_semaphore_debug) {
	    kprintf("%s: Wakeup timeleft(%ju, %ju), tmo %ju, sem %p, thread %jd\n",
		__func__,
		(intmax_t)timelefttv.tv_sec, (intmax_t)timelefttv.tv_usec,
		(intmax_t)tmo, as, (intmax_t)AcpiOsGetThreadId());
	}
    }

    if (acpi_semaphore_debug) {
	if (result == AE_TIME && Timeout > 0) {
	    kprintf("%s: Timeout %d, pending %d, semaphore %p\n",
		__func__, Timeout, as->as_pendings, as);
	}
	if (ACPI_SUCCESS(result) &&
	    (as->as_timeouts > 0 || as->as_pendings > 0))
	{
	    kprintf("%s: Acquire %d, units %d, pending %d, sem %p, thread %jd\n",
		__func__, Units, as->as_units, as->as_pendings, as,
		(intmax_t)AcpiOsGetThreadId());
	}
    }

    if (result == AE_TIME)
	as->as_timeouts++;
    else
	as->as_timeouts = 0;

    AS_UNLOCK(as);
    return_ACPI_STATUS (result);
#else
    return_ACPI_STATUS (AE_OK);
#endif /* !ACPI_NO_SEMAPHORES */
}
示例#10
0
int
procfs_doprocstatus(PFS_FILL_ARGS)
{
	struct session *sess;
	struct thread *tdfirst;
	struct tty *tp;
	struct ucred *cr;
	const char *wmesg;
	char *pc;
	char *sep;
	int pid, ppid, pgid, sid;
	int i;

	pid = p->p_pid;
	PROC_LOCK(p);
	ppid = p->p_pptr ? p->p_pptr->p_pid : 0;
	pgid = p->p_pgrp->pg_id;
	sess = p->p_pgrp->pg_session;
	SESS_LOCK(sess);
	sid = sess->s_leader ? sess->s_leader->p_pid : 0;

/* comm pid ppid pgid sid tty ctty,sldr start ut st wmsg
				euid ruid rgid,egid,groups[1 .. ngroups]
*/

	pc = p->p_comm;
	do {
		if (*pc < 33 || *pc > 126 || *pc == '\\')
			sbuf_printf(sb, "\\%03o", *pc);
		else
			sbuf_putc(sb, *pc);
	} while (*++pc);
	sbuf_printf(sb, " %d %d %d %d ", pid, ppid, pgid, sid);
	if ((p->p_flag & P_CONTROLT) && (tp = sess->s_ttyp))
		sbuf_printf(sb, "%s ", devtoname(tp->t_dev));
	else
		sbuf_printf(sb, "- ");

	sep = "";
	if (sess->s_ttyvp) {
		sbuf_printf(sb, "%sctty", sep);
		sep = ",";
	}
	if (SESS_LEADER(p)) {
		sbuf_printf(sb, "%ssldr", sep);
		sep = ",";
	}
	SESS_UNLOCK(sess);
	if (*sep != ',') {
		sbuf_printf(sb, "noflags");
	}

	tdfirst = FIRST_THREAD_IN_PROC(p);
	thread_lock(tdfirst);
	if (tdfirst->td_wchan != NULL) {
		KASSERT(tdfirst->td_wmesg != NULL,
		    ("wchan %p has no wmesg", tdfirst->td_wchan));
		wmesg = tdfirst->td_wmesg;
	} else
		wmesg = "nochan";
	thread_unlock(tdfirst);

	if (p->p_flag & P_INMEM) {
		struct timeval start, ut, st;

		PROC_SLOCK(p);
		calcru(p, &ut, &st);
		PROC_SUNLOCK(p);
		start = p->p_stats->p_start;
		timevaladd(&start, &boottime);
		sbuf_printf(sb, " %jd,%ld %jd,%ld %jd,%ld",
		    (intmax_t)start.tv_sec, start.tv_usec,
		    (intmax_t)ut.tv_sec, ut.tv_usec,
		    (intmax_t)st.tv_sec, st.tv_usec);
	} else
		sbuf_printf(sb, " -1,-1 -1,-1 -1,-1");

	sbuf_printf(sb, " %s", wmesg);

	cr = p->p_ucred;

	sbuf_printf(sb, " %lu %lu %lu",
		(u_long)cr->cr_uid,
		(u_long)cr->cr_ruid,
		(u_long)cr->cr_rgid);

	/* egid (cr->cr_svgid) is equal to cr_ngroups[0]
	   see also getegid(2) in /sys/kern/kern_prot.c */

	for (i = 0; i < cr->cr_ngroups; i++) {
		sbuf_printf(sb, ",%lu", (u_long)cr->cr_groups[i]);
	}

	if (jailed(cr)) {
		mtx_lock(&cr->cr_prison->pr_mtx);
		sbuf_printf(sb, " %s",
		    prison_name(td->td_ucred->cr_prison, cr->cr_prison));
		mtx_unlock(&cr->cr_prison->pr_mtx);
	} else {
		sbuf_printf(sb, " -");
	}
	PROC_UNLOCK(p);
	sbuf_printf(sb, "\n");

	return (0);
}
示例#11
0
/* send all of the routing table or just do a flash update
 */
void
rip_bcast(int flash)
{
#ifdef _HAVE_SIN_LEN
	static struct sockaddr_in dst = {sizeof(dst), AF_INET, 0, {0}, {0}};
#else
	static struct sockaddr_in dst = {AF_INET};
#endif
	struct interface *ifp;
	enum output_type type;
	int vers;
	struct timeval rtime;


	need_flash = 0;
	intvl_random(&rtime, MIN_WAITTIME, MAX_WAITTIME);
	no_flash = rtime;
	timevaladd(&no_flash, &now);

	if (rip_sock < 0)
		return;

	trace_act("send %s and inhibit dynamic updates for %.3f sec",
		  flash ? "dynamic update" : "all routes",
		  rtime.tv_sec + ((float)rtime.tv_usec)/1000000.0);

	for (ifp = ifnet; ifp != NULL; ifp = ifp->int_next) {
		/* Skip interfaces not doing RIP.
		 * Do try broken interfaces to see if they have healed.
		 */
		if (IS_RIP_OUT_OFF(ifp->int_state))
			continue;

		/* skip turned off interfaces */
		if (!iff_up(ifp->int_if_flags))
			continue;

		vers = (ifp->int_state & IS_NO_RIPV1_OUT) ? RIPv2 : RIPv1;

		if (ifp->int_if_flags & IFF_BROADCAST) {
			/* ordinary, hardware interface */
			dst.sin_addr.s_addr = ifp->int_brdaddr;

			if (vers == RIPv2
			    && !(ifp->int_state  & IS_NO_RIP_MCAST)) {
				type = OUT_MULTICAST;
			} else {
				type = OUT_BROADCAST;
			}

		} else if (ifp->int_if_flags & IFF_POINTOPOINT) {
			/* point-to-point hardware interface */
			dst.sin_addr.s_addr = ifp->int_dstaddr;
			type = OUT_UNICAST;

		} else if (ifp->int_state & IS_REMOTE) {
			/* remote interface */
			dst.sin_addr.s_addr = ifp->int_addr;
			type = OUT_UNICAST;

		} else {
			/* ATM, HIPPI, etc. */
			continue;
		}

		supply(&dst, ifp, type, flash, vers, 1);
	}

	update_seqno++;			/* all routes are up to date */
}
示例#12
0
文件: readmsg.c 项目: Alkzndr/freebsd
struct tsp *
readmsg(int type, char *machfrom, struct timeval *intvl, struct netinfo *netfrom)
{
	int length;
	fd_set ready;
	static struct tsplist *head = &msgslist;
	static struct tsplist *tail = &msgslist;
	static int msgcnt = 0;
	struct tsplist *prev;
	register struct netinfo *ntp;
	register struct tsplist *ptr;
	ssize_t n;

	if (trace) {
		fprintf(fd, "readmsg: looking for %s from %s, %s\n",
			tsptype[type], machfrom == NULL ? "ANY" : machfrom,
			netfrom == NULL ? "ANYNET" : inet_ntoa(netfrom->net));
		if (head->p != 0) {
			length = 1;
			for (ptr = head->p; ptr != 0; ptr = ptr->p) {
				/* do not repeat the hundreds of messages */
				if (++length > 3) {
					if (ptr == tail) {
						fprintf(fd,"\t ...%d skipped\n",
							length);
					} else {
						continue;
					}
				}
				fprintf(fd, length > 1 ? "\t" : "queue:\t");
				print(&ptr->info, &ptr->addr);
			}
		}
	}

	ptr = head->p;
	prev = head;

	/*
	 * Look for the requested message scanning through the
	 * linked list. If found, return it and free the space
	 */

	while (ptr != NULL) {
		if (LOOKAT(ptr->info, type, machfrom, netfrom, ptr->addr)) {
again:
			msgin = ptr->info;
			from = ptr->addr;
			from_when = ptr->when;
			prev->p = ptr->p;
			if (ptr == tail)
				tail = prev;
			free((char *)ptr);
			fromnet = NULL;
			if (netfrom == NULL)
			    for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
				    if ((ntp->mask & from.sin_addr.s_addr) ==
					ntp->net.s_addr) {
					    fromnet = ntp;
					    break;
				    }
			    }
			else
			    fromnet = netfrom;
			if (trace) {
				fprintf(fd, "readmsg: found ");
				print(&msgin, &from);
			}

/* The protocol can get far behind.  When it does, it gets
 *	hopelessly confused.  So delete duplicate messages.
 */
			for (ptr = prev; (ptr = ptr->p) != NULL; prev = ptr) {
				if (ptr->addr.sin_addr.s_addr
					== from.sin_addr.s_addr
				    && ptr->info.tsp_type == msgin.tsp_type) {
					if (trace)
						fprintf(fd, "\tdup ");
					goto again;
				}
			}
			msgcnt--;
			return(&msgin);
		} else {
			prev = ptr;
			ptr = ptr->p;
		}
	}

	/*
	 * If the message was not in the linked list, it may still be
	 * coming from the network. Set the timer and wait
	 * on a select to read the next incoming message: if it is the
	 * right one, return it, otherwise insert it in the linked list.
	 */

	(void)gettimeofday(&rtout, NULL);
	timevaladd(&rtout, intvl);
	FD_ZERO(&ready);
	for (;;) {
		(void)gettimeofday(&rtime, NULL);
		timevalsub(&rwait, &rtout, &rtime);
		if (rwait.tv_sec < 0)
			rwait.tv_sec = rwait.tv_usec = 0;
		else if (rwait.tv_sec == 0
			 && rwait.tv_usec < 1000000/CLK_TCK)
			rwait.tv_usec = 1000000/CLK_TCK;

		if (trace) {
			fprintf(fd, "readmsg: wait %jd.%6ld at %s\n",
				(intmax_t)rwait.tv_sec, rwait.tv_usec, date());
			/* Notice a full disk, as we flush trace info.
			 * It is better to flush periodically than at
			 * every line because the tracing consists of bursts
			 * of many lines.  Without care, tracing slows
			 * down the code enough to break the protocol.
			 */
			if (rwait.tv_sec != 0
			    && EOF == fflush(fd))
				traceoff("Tracing ended for cause at %s\n");
		}

		FD_SET(sock, &ready);
		if (!select(sock+1, &ready, (fd_set *)0, (fd_set *)0,
			   &rwait)) {
			if (rwait.tv_sec == 0 && rwait.tv_usec == 0)
				return(0);
			continue;
		}
		length = sizeof(from);
		if ((n = recvfrom(sock, (char *)&msgin, sizeof(struct tsp), 0,
			     (struct sockaddr*)&from, &length)) < 0) {
			syslog(LOG_ERR, "recvfrom: %m");
			exit(1);
		}
		/*
		 * The 4.3BSD protocol spec had a 32-byte tsp_name field, and
		 * this is still OS-dependent.  Demand that the packet is at
		 * least long enough to hold a 4.3BSD packet.
		 */
		if (n < (ssize_t)(sizeof(struct tsp) - MAXHOSTNAMELEN + 32)) {
			syslog(LOG_NOTICE,
			    "short packet (%zd/%zu bytes) from %s",
			      n, sizeof(struct tsp) - MAXHOSTNAMELEN + 32,
			      inet_ntoa(from.sin_addr));
			continue;
		}
		(void)gettimeofday(&from_when, NULL);
		bytehostorder(&msgin);

		if (msgin.tsp_vers > TSPVERSION) {
			if (trace) {
			    fprintf(fd,"readmsg: version mismatch\n");
			    /* should do a dump of the packet */
			}
			continue;
		}

		if (memchr(msgin.tsp_name,
		    '\0', sizeof msgin.tsp_name) == NULL) {
			syslog(LOG_NOTICE, "hostname field not NUL terminated "
			    "in packet from %s", inet_ntoa(from.sin_addr));
			continue;
		}

		fromnet = NULL;
		for (ntp = nettab; ntp != NULL; ntp = ntp->next)
			if ((ntp->mask & from.sin_addr.s_addr) ==
			    ntp->net.s_addr) {
				fromnet = ntp;
				break;
			}

		/*
		 * drop packets from nets we are ignoring permanently
		 */
		if (fromnet == NULL) {
			/*
			 * The following messages may originate on
			 * this host with an ignored network address
			 */
			if (msgin.tsp_type != TSP_TRACEON &&
			    msgin.tsp_type != TSP_SETDATE &&
			    msgin.tsp_type != TSP_MSITE &&
			    msgin.tsp_type != TSP_TEST &&
			    msgin.tsp_type != TSP_TRACEOFF) {
				if (trace) {
				    fprintf(fd,"readmsg: discard null net ");
				    print(&msgin, &from);
				}
				continue;
			}
		}

		/*
		 * Throw away messages coming from this machine,
		 * unless they are of some particular type.
		 * This gets rid of broadcast messages and reduces
		 * master processing time.
		 */
		if (!strcmp(msgin.tsp_name, hostname)
		    && msgin.tsp_type != TSP_SETDATE
		    && msgin.tsp_type != TSP_TEST
		    && msgin.tsp_type != TSP_MSITE
		    && msgin.tsp_type != TSP_TRACEON
		    && msgin.tsp_type != TSP_TRACEOFF
		    && msgin.tsp_type != TSP_LOOP) {
			if (trace) {
				fprintf(fd, "readmsg: discard own ");
				print(&msgin, &from);
			}
			continue;
		}

		/*
		 * Send acknowledgements here; this is faster and
		 * avoids deadlocks that would occur if acks were
		 * sent from a higher level routine.  Different
		 * acknowledgements are necessary, depending on
		 * status.
		 */
		if (fromnet == NULL)	/* do not de-reference 0 */
			ignoreack();
		else if (fromnet->status == MASTER)
			masterack();
		else if (fromnet->status == SLAVE)
			slaveack();
		else
			ignoreack();

		if (LOOKAT(msgin, type, machfrom, netfrom, from)) {
			if (trace) {
				fprintf(fd, "readmsg: ");
				print(&msgin, &from);
			}
			return(&msgin);
		} else if (++msgcnt > NHOSTS*3) {

/* The protocol gets hopelessly confused if it gets too far
*	behind.  However, it seems able to recover from all cases of lost
*	packets.  Therefore, if we are swamped, throw everything away.
*/
			if (trace)
				fprintf(fd,
					"readmsg: discarding %d msgs\n",
					msgcnt);
			msgcnt = 0;
			while ((ptr=head->p) != NULL) {
				head->p = ptr->p;
				free((char *)ptr);
			}
			tail = head;
		} else {
			tail->p = (struct tsplist *)
				    malloc(sizeof(struct tsplist));
			tail = tail->p;
			tail->p = NULL;
			tail->info = msgin;
			tail->addr = from;
			/* timestamp msgs so SETTIMEs are correct */
			tail->when = from_when;
		}
	}
}
示例#13
0
/*
 * Measures the differences between machines' clocks using
 * ICMP timestamp messages.
 * maxmsec	wait this many msec at most
 * wmsec	msec to wait for an answer
 * print	print complaints on stderr
 */
int					/* status val defined in globals.h */
measure(u_long maxmsec, u_long wmsec, char *hname, struct sockaddr_in *addr, int print)
{
	int length;
	int measure_status;
	int rcvcount, trials;
	int cc, count;
	fd_set ready;
	long sendtime, recvtime, histime1, histime2;
	long idelta, odelta, total;
	long min_idelta, min_odelta;
	struct timeval tdone, tcur, ttrans, twait, tout;
	u_char packet[PACKET_IN], opacket[64];
	register struct icmp *icp = (struct icmp *) packet;
	register struct icmp *oicp = (struct icmp *) opacket;
	struct ip *ip = (struct ip *) packet;

	min_idelta = min_odelta = 0x7fffffff;
	measure_status = HOSTDOWN;
	measure_delta = HOSTDOWN;
	trials = 0;
	errno = 0;

	/* open raw socket used to measure time differences */
	if (sock_raw < 0) {
		sock_raw = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
		if (sock_raw < 0)  {
			syslog(LOG_ERR, "opening raw socket: %m");
			goto quit;
		}
	}


	/*
	 * empty the icmp input queue
	 */
	FD_ZERO(&ready);
	for (;;) {
		tout.tv_sec = tout.tv_usec = 0;
		FD_SET(sock_raw, &ready);
		if (select(sock_raw+1, &ready, 0,0, &tout)) {
			length = sizeof(struct sockaddr_in);
			cc = recvfrom(sock_raw, (char *)packet, PACKET_IN, 0,
				      0,&length);
			if (cc < 0)
				goto quit;
			continue;
		}
		break;
	}

	/*
	 * Choose the smallest transmission time in each of the two
	 * directions. Use these two latter quantities to compute the delta
	 * between the two clocks.
	 */

	oicp->icmp_type = ICMP_TSTAMP;
	oicp->icmp_code = 0;
	oicp->icmp_id = getpid();
	oicp->icmp_rtime = 0;
	oicp->icmp_ttime = 0;
	oicp->icmp_seq = seqno;

	FD_ZERO(&ready);

	(void)gettimeofday(&tdone, NULL);
	mstotvround(&tout, maxmsec);
	timevaladd(&tdone, &tout);		/* when we give up */

	mstotvround(&twait, wmsec);

	rcvcount = 0;
	while (rcvcount < MSGS) {
		(void)gettimeofday(&tcur, NULL);

		/*
		 * keep sending until we have sent the max
		 */
		if (trials < TRIALS) {
			trials++;
			oicp->icmp_otime = htonl((tcur.tv_sec % SECDAY) * 1000
						 + tcur.tv_usec / 1000);
			oicp->icmp_cksum = 0;
			oicp->icmp_cksum = in_cksum((u_short*)oicp,
						    sizeof(*oicp));

			count = sendto(sock_raw, opacket, sizeof(*oicp), 0,
				       (struct sockaddr*)addr,
				       sizeof(struct sockaddr));
			if (count < 0) {
				if (measure_status == HOSTDOWN)
					measure_status = UNREACHABLE;
				goto quit;
			}
			++oicp->icmp_seq;

			ttrans = tcur;
			timevaladd(&ttrans, &twait);
		} else {
			ttrans = tdone;
		}

		while (rcvcount < trials) {
			timevalsub(&tout, &ttrans, &tcur);
			if (tout.tv_sec < 0)
				tout.tv_sec = 0;

			FD_SET(sock_raw, &ready);
			count = select(sock_raw+1, &ready, (fd_set *)0,
				       (fd_set *)0, &tout);
			(void)gettimeofday(&tcur, NULL);
			if (count <= 0)
				break;

			length = sizeof(struct sockaddr_in);
			cc = recvfrom(sock_raw, (char *)packet, PACKET_IN, 0,
				      0,&length);
			if (cc < 0)
				goto quit;

			/*
			 * got something.  See if it is ours
			 */
			icp = (struct icmp *)(packet + (ip->ip_hl << 2));
			if (cc < sizeof(*ip)
			    || icp->icmp_type != ICMP_TSTAMPREPLY
			    || icp->icmp_id != oicp->icmp_id
			    || icp->icmp_seq < seqno
			    || icp->icmp_seq >= oicp->icmp_seq)
				continue;


			sendtime = ntohl(icp->icmp_otime);
			recvtime = ((tcur.tv_sec % SECDAY) * 1000 +
				    tcur.tv_usec / 1000);

			total = recvtime-sendtime;
			if (total < 0)	/* do not hassle midnight */
				continue;

			rcvcount++;
			histime1 = ntohl(icp->icmp_rtime);
			histime2 = ntohl(icp->icmp_ttime);
			/*
			 * a host using a time format different from
			 * msec. since midnight UT (as per RFC792) should
			 * set the high order bit of the 32-bit time
			 * value it transmits.
			 */
			if ((histime1 & 0x80000000) != 0) {
				measure_status = NONSTDTIME;
				goto quit;
			}
			measure_status = GOOD;

			idelta = recvtime-histime2;
			odelta = histime1-sendtime;

			/* do not be confused by midnight */
			if (idelta < -MSEC_DAY/2) idelta += MSEC_DAY;
			else if (idelta > MSEC_DAY/2) idelta -= MSEC_DAY;

			if (odelta < -MSEC_DAY/2) odelta += MSEC_DAY;
			else if (odelta > MSEC_DAY/2) odelta -= MSEC_DAY;

			/* save the quantization error so that we can get a
			 * measurement finer than our system clock.
			 */
			if (total < MIN_ROUND) {
				measure_delta = (odelta - idelta)/2;
				goto quit;
			}

			if (idelta < min_idelta)
				min_idelta = idelta;
			if (odelta < min_odelta)
				min_odelta = odelta;

			measure_delta = (min_odelta - min_idelta)/2;
		}

		if (tcur.tv_sec > tdone.tv_sec
		    || (tcur.tv_sec == tdone.tv_sec
			&& tcur.tv_usec >= tdone.tv_usec))
			break;
	}

quit:
	seqno += TRIALS;		/* allocate our sequence numbers */

	/*
	 * If no answer is received for TRIALS consecutive times,
	 * the machine is assumed to be down
	 */
	if (measure_status == GOOD) {
		if (trace) {
			fprintf(fd,
				"measured delta %4d, %d trials to %-15s %s\n",
			   	measure_delta, trials,
				inet_ntoa(addr->sin_addr), hname);
		}
	} else if (print) {
		if (errno != 0)
			warn("measure %s", hname);
	} else {
		if (errno != 0) {
			syslog(LOG_ERR, "measure %s: %m", hname);
		} else {
			syslog(LOG_ERR, "measure: %s did not respond", hname);
		}
		if (trace) {
			fprintf(fd,
				"measure: %s failed after %d trials\n",
				hname, trials);
			(void)fflush(fd);
		}
	}

	return(measure_status);
}
示例#14
0
/*
 * Write out process accounting information, on process exit.
 * Data to be written out is specified in Leffler, et al.
 * and are enumerated below.  (They're also noted in the system
 * "acct.h" header file.)
 */
int
acct_process(proc_t p)
{
	struct acct an_acct;
	struct rusage rup, *r;
	struct timeval ut, st, tmp;
	int t;
	int error;
	struct vnode *vp;
	kauth_cred_t safecred;
	struct session * sessp;
	boolean_t fstate;

	/* If accounting isn't enabled, don't bother */
	vp = acctp;
	if (vp == NULLVP)
		return (0);

	/*
	 * Get process accounting information.
	 */

	/* (1) The name of the command that ran */
	bcopy(p->p_comm, an_acct.ac_comm, sizeof an_acct.ac_comm);

	/* (2) The amount of user and system time that was used */
	calcru(p, &ut, &st, NULL);
	an_acct.ac_utime = encode_comp_t(ut.tv_sec, ut.tv_usec);
	an_acct.ac_stime = encode_comp_t(st.tv_sec, st.tv_usec);

	/* (3) The elapsed time the commmand ran (and its starting time) */
	an_acct.ac_btime = p->p_start.tv_sec;
	microtime(&tmp);
	timevalsub(&tmp, &p->p_start);
	an_acct.ac_etime = encode_comp_t(tmp.tv_sec, tmp.tv_usec);

	/* (4) The average amount of memory used */
	proc_lock(p);
	rup = p->p_stats->p_ru;
	proc_unlock(p);
	r = &rup;
	tmp = ut;
	timevaladd(&tmp, &st);
	t = tmp.tv_sec * hz + tmp.tv_usec / tick;
	if (t)
		an_acct.ac_mem = (r->ru_ixrss + r->ru_idrss + r->ru_isrss) / t;
	else
		an_acct.ac_mem = 0;

	/* (5) The number of disk I/O operations done */
	an_acct.ac_io = encode_comp_t(r->ru_inblock + r->ru_oublock, 0);

	/* (6) The UID and GID of the process */
	safecred = kauth_cred_proc_ref(p);

	an_acct.ac_uid = safecred->cr_ruid;
	an_acct.ac_gid = safecred->cr_rgid;

	/* (7) The terminal from which the process was started */
	
	sessp = proc_session(p);
	if ((p->p_flag & P_CONTROLT) && (sessp != SESSION_NULL) && (sessp->s_ttyp != TTY_NULL)) {
		fstate = thread_funnel_set(kernel_flock, TRUE);
		an_acct.ac_tty = sessp->s_ttyp->t_dev;
		(void) thread_funnel_set(kernel_flock, fstate);
	 }else
		an_acct.ac_tty = NODEV;

	if (sessp != SESSION_NULL)
		session_rele(sessp);

	/* (8) The boolean flags that tell how the process terminated, etc. */
	an_acct.ac_flag = p->p_acflag;

	/*
	 * Now, just write the accounting information to the file.
	 */
	if ((error = vnode_getwithref(vp)) == 0) {
	        error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&an_acct, sizeof (an_acct),
				(off_t)0, UIO_SYSSPACE32, IO_APPEND|IO_UNIT, safecred,
				(int *)0, p);
		vnode_put(vp);
	}

	kauth_cred_unref(&safecred);
	return (error);
}