Beispiel #1
0
int
sbappendcontrol(struct sockbuf *sb, struct mbuf *m0, struct mbuf *control)
{
	struct mbuf *m, *mlast, *n;
	int space = 0;

	if (control == NULL)
		panic("sbappendcontrol");
	for (m = control; ; m = m->m_next) {
		space += m->m_len;
		if (m->m_next == NULL)
			break;
	}
	n = m;			/* save pointer to last control buffer */
	for (m = m0; m; m = m->m_next)
		space += m->m_len;
	if (space > sbspace(sb))
		return (0);
	n->m_next = m0;			/* concatenate data to control */

	SBLASTRECORDCHK(sb, "sbappendcontrol 1");

	for (m = control; m->m_next != NULL; m = m->m_next)
		sballoc(sb, m);
	sballoc(sb, m);
	mlast = m;
	SBLINKRECORD(sb, control);

	sb->sb_mbtail = mlast;
	SBLASTMBUFCHK(sb, "sbappendcontrol");

	SBLASTRECORDCHK(sb, "sbappendcontrol 2");

	return (1);
}
Beispiel #2
0
int
sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0,
    struct mbuf *control)
{
	struct mbuf *m, *n, *mlast;
	int space;

	SOCKBUF_LOCK_ASSERT(sb);

	if (control == 0)
		panic("sbappendcontrol_locked");
	space = m_length(control, &n) + m_length(m0, NULL);

	if (space > sbspace(sb))
		return (0);
	n->m_next = m0;			/* concatenate data to control */

	SBLASTRECORDCHK(sb);

	for (m = control; m->m_next; m = m->m_next)
		sballoc(sb, m);
	sballoc(sb, m);
	mlast = m;
	SBLINKRECORD(sb, control);

	sb->sb_mbtail = mlast;
	SBLASTMBUFCHK(sb);

	SBLASTRECORDCHK(sb);
	return (1);
}
Beispiel #3
0
/* Helper routine that appends data, control, and address to a sockbuf. */
static int
sbappendaddr_locked_internal(struct sockbuf *sb, const struct sockaddr *asa,
    struct mbuf *m0, struct mbuf *control, struct mbuf *ctrl_last)
{
	struct mbuf *m, *n, *nlast;
#if MSIZE <= 256
	if (asa->sa_len > MLEN)
		return (0);
#endif
	m = m_get(M_NOWAIT, MT_SONAME);
	if (m == NULL)
		return (0);
	m->m_len = asa->sa_len;
	bcopy(asa, mtod(m, caddr_t), asa->sa_len);
	if (m0)
		m_clrprotoflags(m0);
	if (ctrl_last)
		ctrl_last->m_next = m0;	/* concatenate data to control */
	else
		control = m0;
	m->m_next = control;
	for (n = m; n->m_next != NULL; n = n->m_next)
		sballoc(sb, n);
	sballoc(sb, n);
	nlast = n;
	SBLINKRECORD(sb, m);

	sb->sb_mbtail = nlast;
	SBLASTMBUFCHK(sb);

	SBLASTRECORDCHK(sb);
	return (1);
}
Beispiel #4
0
/*
 * Append address and data, and optionally, control (ancillary) data to the
 * receive queue of a socket.  If present, m0 must include a packet header
 * with total length.  Returns 0 if no space in sockbuf or insufficient
 * mbufs.
 */
int
ofp_sbappendaddr_locked(struct sockbuf *sb,
		    odp_packet_t pkt, odp_packet_t control)
{
	SOCKBUF_LOCK_ASSERT(sb);

	if (control != ODP_PACKET_INVALID)
		odp_packet_free(control);

	sb->sb_mb[sb->sb_put++] = pkt;
	if (sb->sb_put >= SOCKBUF_LEN)
		sb->sb_put = 0;

	if (sb->sb_put == sb->sb_get) {
		sb->sb_put--;
		if (sb->sb_put < 0)
			sb->sb_put = SOCKBUF_LEN-1;
		OFP_ERR("Buffers full, sb_get=%d max_num=%d",
			  sb->sb_get, SOCKBUF_LEN);
		return 0;
	}

	sballoc(sb, pkt);
	return (1);
}
/*
 * As above, except the mbuf chain
 * begins a new record.
 */
void
sbappendrecord(struct sockbuf *sb, struct mbuf *m0)
{
	struct mbuf	*m;

	KASSERT(solocked(sb->sb_so));

	if (m0 == 0)
		return;

#ifdef MBUFTRACE
	m_claimm(m0, sb->sb_mowner);
#endif
	/*
	 * Put the first mbuf on the queue.
	 * Note this permits zero length records.
	 */
	sballoc(sb, m0);
	SBLASTRECORDCHK(sb, "sbappendrecord 1");
	SBLINKRECORD(sb, m0);
	m = m0->m_next;
	m0->m_next = 0;
	if (m && (m0->m_flags & M_EOR)) {
		m0->m_flags &= ~M_EOR;
		m->m_flags |= M_EOR;
	}
	sbcompress(sb, m, m0);
	SBLASTRECORDCHK(sb, "sbappendrecord 2");
}
/*
 * As above, except the mbuf chain begins a new record.
 */
void
sbappendrecord_locked(struct sockbuf *sb, struct mbuf *m0)
{
	struct mbuf *m;

	SOCKBUF_LOCK_ASSERT(sb);

	if (m0 == NULL)
		return;
	m_clrprotoflags(m0);
	/*
	 * Put the first mbuf on the queue.  Note this permits zero length
	 * records.
	 */
	sballoc(sb, m0);
	SBLASTRECORDCHK(sb);
	SBLINKRECORD(sb, m0);
	sb->sb_mbtail = m0;
	m = m0->m_next;
	m0->m_next = 0;
	if (m && (m0->m_flags & M_EOR)) {
		m0->m_flags &= ~M_EOR;
		m->m_flags |= M_EOR;
	}
	/* always call sbcompress() so it can do SBLASTMBUFCHK() */
	sbcompress(sb, m, m0);
}
Beispiel #7
0
/*
 * Append the data in mbuf chain (m) into the socket buffer sb following mbuf
 * (n).  If (n) is NULL, the buffer is presumed empty.
 *
 * When the data is compressed, mbufs in the chain may be handled in one of
 * three ways:
 *
 * (1) The mbuf may simply be dropped, if it contributes nothing (no data, no
 *     record boundary, and no change in data type).
 *
 * (2) The mbuf may be coalesced -- i.e., data in the mbuf may be copied into
 *     an mbuf already in the socket buffer.  This can occur if an
 *     appropriate mbuf exists, there is room, and no merging of data types
 *     will occur.
 *
 * (3) The mbuf may be appended to the end of the existing mbuf chain.
 *
 * If any of the new mbufs is marked as M_EOR, mark the last mbuf appended as
 * end-of-record.
 */
void
sbcompress(struct sockbuf *sb, struct mbuf *m, struct mbuf *n)
{
	int eor = 0;
	struct mbuf *o;

	SOCKBUF_LOCK_ASSERT(sb);

	while (m) {
		eor |= m->m_flags & M_EOR;
		if (m->m_len == 0 &&
		    (eor == 0 ||
		     (((o = m->m_next) || (o = n)) &&
		      o->m_type == m->m_type))) {
			if (sb->sb_lastrecord == m)
				sb->sb_lastrecord = m->m_next;
			m = m_free(m);
			continue;
		}
		if (n && (n->m_flags & M_EOR) == 0 &&
		    M_WRITABLE(n) &&
		    ((sb->sb_flags & SB_NOCOALESCE) == 0) &&
		    m->m_len <= M_TRAILINGSPACE(n) &&
		    n->m_type == m->m_type) {
			if (n->m_flags & M_HOLE) {
				n->m_len += m->m_len;
				sb->sb_cc += m->m_len;
				m = m_free(m);
				continue;
			} else if (m->m_len <= MCLBYTES / 4) { /* XXX: Don't copy too much */
				bcopy(mtod(m, caddr_t),
				      mtod(n, caddr_t) + n->m_len,
				      (unsigned)m->m_len);
				n->m_len += m->m_len;
				sb->sb_cc += m->m_len;
				if (m->m_type != MT_DATA &&
				    m->m_type != MT_OOBDATA)
				/* XXX: Probably don't need.*/
					sb->sb_ctl += m->m_len;
				m = m_free(m);
				continue;
			}
		}
		if (n)
			n->m_next = m;
		else
			sb->sb_mb = m;
		sb->sb_mbtail = m;
		sballoc(sb, m);
		n = m;
		m->m_flags &= ~M_EOR;
		m = m->m_next;
		n->m_next = 0;
	}
	if (eor) {
		KASSERT(n != NULL, ("sbcompress: eor && n == NULL"));
		n->m_flags |= eor;
	}
	SBLASTMBUFCHK(sb);
}
Beispiel #8
0
/*
 * Append address and data, and optionally, control (ancillary) data
 * to the receive queue of a socket.  If present,
 * m0 must include a packet header with total length.
 * Returns 0 if no space in sockbuf or insufficient mbufs.
 */
int
sbappendaddr(struct sockbuf *sb, struct sockaddr *asa, struct mbuf *m0,
    struct mbuf *control)
{
	struct mbuf *m, *n, *nlast;
	int space = asa->sa_len;

	if (m0 && (m0->m_flags & M_PKTHDR) == 0)
		panic("sbappendaddr");
	if (m0)
		space += m0->m_pkthdr.len;
	for (n = control; n; n = n->m_next) {
		space += n->m_len;
		if (n->m_next == NULL)	/* keep pointer to last control buf */
			break;
	}
	if (space > sbspace(sb))
		return (0);
	if (asa->sa_len > MLEN)
		return (0);
	MGET(m, M_DONTWAIT, MT_SONAME);
	if (m == NULL)
		return (0);
	m->m_len = asa->sa_len;
	memcpy(mtod(m, caddr_t), asa, asa->sa_len);
	if (n)
		n->m_next = m0;		/* concatenate data to control */
	else
		control = m0;
	m->m_next = control;

	SBLASTRECORDCHK(sb, "sbappendaddr 1");

	for (n = m; n->m_next != NULL; n = n->m_next)
		sballoc(sb, n);
	sballoc(sb, n);
	nlast = n;
	SBLINKRECORD(sb, m);

	sb->sb_mbtail = nlast;
	SBLASTMBUFCHK(sb, "sbappendaddr");

	SBLASTRECORDCHK(sb, "sbappendaddr 2");

	return (1);
}
/*
 * Append address and data, and optionally, control (ancillary) data to the
 * receive queue of a socket.  If present, m0 must include a packet header
 * with total length.  Returns 0 if no space in sockbuf or insufficient
 * mbufs.
 */
int
sbappendaddr_locked(struct sockbuf *sb, const struct sockaddr *asa,
    struct mbuf *m0, struct mbuf *control)
{
	struct mbuf *m, *n, *nlast;
	int space = asa->sa_len;

	SOCKBUF_LOCK_ASSERT(sb);

	if (m0 && (m0->m_flags & M_PKTHDR) == 0)
		panic("sbappendaddr_locked");
	if (m0)
		space += m0->m_pkthdr.len;
	space += m_length(control, &n);

	if (space > sbspace(sb))
		return (0);
#if MSIZE <= 256
	if (asa->sa_len > MLEN)
		return (0);
#endif
	MGET(m, M_DONTWAIT, MT_SONAME);
	if (m == 0)
		return (0);
	m->m_len = asa->sa_len;
	bcopy(asa, mtod(m, caddr_t), asa->sa_len);
	if (n){
		CHECK_ADD_LINKCNT(n, m0, NULL, "sbappendaddr_locked");
		n->m_next = m0;		/* concatenate data to control */
	}else
		control = m0;
	CHECK_ADD_LINKCNT(m, control, NULL, "sbappendaddr_locked");	
	m->m_next = control;
	for (n = m; n->m_next != NULL; n = n->m_next)
		sballoc(sb, n);
	sballoc(sb, n);
	nlast = n;
	SBLINKRECORD(sb, m);

	sb->sb_mbtail = nlast;
	SBLASTMBUFCHK(sb);

	SBLASTRECORDCHK(sb);
	return (1);
}
/* Helper routine that appends data, control, and address to a sockbuf. */
static int
sbappendaddr_locked_internal(struct sockbuf *sb, const struct sockaddr *asa,
    struct mbuf *m0, struct mbuf *control, struct mbuf *ctrl_last)
{
	struct mbuf *m, *n, *nlast;
#if MSIZE <= 256
	if (asa->sa_len > MLEN)
		return (0);
#endif
	m = m_get(M_NOWAIT, MT_SONAME);
	if (m == NULL)
		return (0);
	m->m_len = asa->sa_len;
	bcopy(asa, mtod(m, caddr_t), asa->sa_len);
	if (m0) {
		m_clrprotoflags(m0);
		m_tag_delete_chain(m0, NULL);
		/*
		 * Clear some persistent info from pkthdr.
		 * We don't use m_demote(), because some netgraph consumers
		 * expect M_PKTHDR presence.
		 */
		m0->m_pkthdr.rcvif = NULL;
		m0->m_pkthdr.flowid = 0;
		m0->m_pkthdr.csum_flags = 0;
		m0->m_pkthdr.fibnum = 0;
		m0->m_pkthdr.rsstype = 0;
	}
	if (ctrl_last)
		ctrl_last->m_next = m0;	/* concatenate data to control */
	else
		control = m0;
	m->m_next = control;
	for (n = m; n->m_next != NULL; n = n->m_next)
		sballoc(sb, n);
	sballoc(sb, n);
	nlast = n;
	SBLINKRECORD(sb, m);

	sb->sb_mbtail = nlast;
	SBLASTMBUFCHK(sb);

	SBLASTRECORDCHK(sb);
	return (1);
}
Beispiel #11
0
/*
 * Append address and data, and optionally, control (ancillary) data
 * to the receive queue of a socket.  If present,
 * m0 must include a packet header with total length.
 * Returns 0 if insufficient mbufs.
 */
int
sbappendaddr(struct sockbuf *sb, const struct sockaddr *asa, struct mbuf *m0,
	     struct mbuf *control)
{
	struct mbuf *m, *n;
	int eor;

	mbuftrackid(m0, 19);
	mbuftrackid(control, 20);
	if (m0 && (m0->m_flags & M_PKTHDR) == 0)
		panic("sbappendaddr");
	sbcheck(sb);

	for (n = control; n; n = n->m_next) {
		if (n->m_next == NULL)	/* keep pointer to last control buf */
			break;
	}
	if (asa->sa_len > MLEN)
		return (0);
	MGET(m, MB_DONTWAIT, MT_SONAME);
	if (m == NULL)
		return (0);
	KKASSERT(m->m_nextpkt == NULL);
	m->m_len = asa->sa_len;
	bcopy(asa, mtod(m, caddr_t), asa->sa_len);
	if (n)
		n->m_next = m0;		/* concatenate data to control */
	else
		control = m0;
	m->m_next = control;
	for (n = m; n; n = n->m_next)
		sballoc(sb, n);

	if (sb->sb_mb == NULL)
		sb->sb_mb = m;
	else
		sb->sb_lastrecord->m_nextpkt = m;
	sb->sb_lastrecord = m;

	/*
	 * Propogate M_EOR to the last mbuf and calculate sb_lastmbuf
	 * so sbappend() can find it.
	 */
	eor = m->m_flags;
	while (m->m_next) {
		m->m_flags &= ~M_EOR;
		m = m->m_next;
		eor |= m->m_flags;
	}
	m->m_flags |= eor & M_EOR;
	sb->sb_lastmbuf = m;

	return (1);
}
void
sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0,
    struct mbuf *control)
{
	struct mbuf *m, *mlast;

	m_clrprotoflags(m0);
	m_last(control)->m_next = m0;

	SBLASTRECORDCHK(sb);

	for (m = control; m->m_next; m = m->m_next)
		sballoc(sb, m);
	sballoc(sb, m);
	mlast = m;
	SBLINKRECORD(sb, control);

	sb->sb_mbtail = mlast;
	SBLASTMBUFCHK(sb);

	SBLASTRECORDCHK(sb);
}
Beispiel #13
0
/*
 * Compress mbuf chain m into the socket
 * buffer sb following mbuf n.  If n
 * is null, the buffer is presumed empty.
 */
void
sbcompress(struct sockbuf *sb, struct mbuf *m, struct mbuf *n)
{
	int eor = 0;
	struct mbuf *o;

	while (m) {
		eor |= m->m_flags & M_EOR;
		if (m->m_len == 0 &&
		    (eor == 0 ||
		    (((o = m->m_next) || (o = n)) &&
		    o->m_type == m->m_type))) {
			if (sb->sb_lastrecord == m)
				sb->sb_lastrecord = m->m_next;
			m = m_free(m);
			continue;
		}
		if (n && (n->m_flags & M_EOR) == 0 &&
		    /* M_TRAILINGSPACE() checks buffer writeability */
		    m->m_len <= MCLBYTES / 4 && /* XXX Don't copy too much */
		    m->m_len <= M_TRAILINGSPACE(n) &&
		    n->m_type == m->m_type) {
			memcpy(mtod(n, caddr_t) + n->m_len, mtod(m, caddr_t),
			    m->m_len);
			n->m_len += m->m_len;
			sb->sb_cc += m->m_len;
			if (m->m_type != MT_CONTROL && m->m_type != MT_SONAME)
				sb->sb_datacc += m->m_len;
			m = m_free(m);
			continue;
		}
		if (n)
			n->m_next = m;
		else
			sb->sb_mb = m;
		sb->sb_mbtail = m;
		sballoc(sb, m);
		n = m;
		m->m_flags &= ~M_EOR;
		m = m->m_next;
		n->m_next = NULL;
	}
	if (eor) {
		if (n)
			n->m_flags |= eor;
		else
			printf("semi-panic: sbcompress");
	}
	SBLASTMBUFCHK(sb, __func__);
}
Beispiel #14
0
/*
 * Same as sbappend(), except the mbuf chain begins a new record.
 */
void
sbappendrecord(struct sockbuf *sb, struct mbuf *m0)
{
	struct mbuf *firstmbuf;
	struct mbuf *secondmbuf;

	if (m0 == NULL)
		return;
	mbuftrackid(m0, 18);

	sbcheck(sb);

	/*
	 * Break the first mbuf off from the rest of the mbuf chain.
	 */
	firstmbuf = m0;
	secondmbuf = m0->m_next;
	m0->m_next = NULL;

	/*
	 * Insert the first mbuf of the m0 mbuf chain as the last record of
	 * the sockbuf.  Note this permits zero length records!  Keep the
	 * sockbuf state consistent.
	 */
	if (sb->sb_mb == NULL)
		sb->sb_mb = firstmbuf;
	else
		sb->sb_lastrecord->m_nextpkt = firstmbuf;
	sb->sb_lastrecord = firstmbuf;	/* update hint for new last record */
	sb->sb_lastmbuf = firstmbuf;	/* update hint for new last mbuf */

	/*
	 * propagate the EOR flag so sbcompress() can pick it up
	 */
	if ((firstmbuf->m_flags & M_EOR) && (secondmbuf != NULL)) {
		firstmbuf->m_flags &= ~M_EOR;
		secondmbuf->m_flags |= M_EOR;
	}

	/*
	 * The succeeding call to sbcompress() omits accounting for
	 * the first mbuf, so do it here.
	 */
	sballoc(sb, firstmbuf);

	/* Compact the rest of the mbuf chain in after the first mbuf. */
	sbcompress(sb, secondmbuf, firstmbuf);
}
/*
 * As above except that OOB data
 * is inserted at the beginning of the sockbuf,
 * but after any other OOB data.
 */
void
sbinsertoob(struct sockbuf *sb, struct mbuf *m0)
{
	struct mbuf	*m, **mp;

	KASSERT(solocked(sb->sb_so));

	if (m0 == 0)
		return;

	SBLASTRECORDCHK(sb, "sbinsertoob 1");

	for (mp = &sb->sb_mb; (m = *mp) != NULL; mp = &((*mp)->m_nextpkt)) {
	    again:
		switch (m->m_type) {

		case MT_OOBDATA:
			continue;		/* WANT next train */

		case MT_CONTROL:
			if ((m = m->m_next) != NULL)
				goto again;	/* inspect THIS train further */
		}
		break;
	}
	/*
	 * Put the first mbuf on the queue.
	 * Note this permits zero length records.
	 */
	sballoc(sb, m0);
	m0->m_nextpkt = *mp;
	if (*mp == NULL) {
		/* m0 is actually the new tail */
		sb->sb_lastrecord = m0;
	}
	*mp = m0;
	m = m0->m_next;
	m0->m_next = 0;
	if (m && (m0->m_flags & M_EOR)) {
		m0->m_flags &= ~M_EOR;
		m->m_flags |= M_EOR;
	}
	sbcompress(sb, m, m0);
	SBLASTRECORDCHK(sb, "sbinsertoob 2");
}
/*
 * Compress mbuf chain m into the socket
 * buffer sb following mbuf n.  If n
 * is null, the buffer is presumed empty.
 */
void
sbcompress(struct sockbuf *sb, struct mbuf *m, struct mbuf *n)
{
	int		eor;
	struct mbuf	*o;

	KASSERT(solocked(sb->sb_so));

	eor = 0;
	while (m) {
		eor |= m->m_flags & M_EOR;
		if (m->m_len == 0 &&
		    (eor == 0 ||
		     (((o = m->m_next) || (o = n)) &&
		      o->m_type == m->m_type))) {
			if (sb->sb_lastrecord == m)
				sb->sb_lastrecord = m->m_next;
			m = m_free(m);
			continue;
		}
		if (n && (n->m_flags & M_EOR) == 0 &&
		    /* M_TRAILINGSPACE() checks buffer writeability */
		    m->m_len <= MCLBYTES / 4 && /* XXX Don't copy too much */
		    m->m_len <= M_TRAILINGSPACE(n) &&
		    n->m_type == m->m_type) {
			memcpy(mtod(n, char *) + n->m_len, mtod(m, void *),
			    (unsigned)m->m_len);
			n->m_len += m->m_len;
			sb->sb_cc += m->m_len;
			m = m_free(m);
			continue;
		}
		if (n)
			n->m_next = m;
		else
			sb->sb_mb = m;
		sb->sb_mbtail = m;
		sballoc(sb, m);
		n = m;
		m->m_flags &= ~M_EOR;
		m = m->m_next;
		n->m_next = 0;
	}
Beispiel #17
0
int ofp_sockbuf_put_last(struct sockbuf *sb, odp_packet_t pkt)
{
	/* Offer to event function */
	if (packet_accepted_as_event_locked(sb, pkt))
		return 0;

	int next = sb->sb_put + 1;
	if (next >= SOCKBUF_LEN)
		next = 0;

	if (next == sb->sb_get) {
		ofp_sockbuf_packet_free(pkt);
		OFP_ERR("No more room, next=%d", next);
		return -1;
	}

	sb->sb_mb[sb->sb_put] = pkt;
	sb->sb_put = next;
	sballoc(sb, pkt);
	return 0;
}
Beispiel #18
0
/*
 * As above, except the mbuf chain
 * begins a new record.
 */
void
sbappendrecord(struct sockbuf *sb, struct mbuf *m0)
{
	struct mbuf *m;

	if (m0 == NULL)
		return;

	/*
	 * Put the first mbuf on the queue.
	 * Note this permits zero length records.
	 */
	sballoc(sb, m0);
	SBLASTRECORDCHK(sb, "sbappendrecord 1");
	SBLINKRECORD(sb, m0);
	m = m0->m_next;
	m0->m_next = NULL;
	if (m && (m0->m_flags & M_EOR)) {
		m0->m_flags &= ~M_EOR;
		m->m_flags |= M_EOR;
	}
	sbcompress(sb, m, m0);
	SBLASTRECORDCHK(sb, "sbappendrecord 2");
}
/*
 * Append address and data, and optionally, control (ancillary) data
 * to the receive queue of a socket.  If present,
 * m0 must include a packet header with total length.
 * Returns 0 if no space in sockbuf or insufficient mbufs.
 */
int
sbappendaddr(struct sockbuf *sb, const struct sockaddr *asa, struct mbuf *m0,
	struct mbuf *control)
{
	struct mbuf	*m, *n, *nlast;
	int		space, len;

	KASSERT(solocked(sb->sb_so));

	space = asa->sa_len;

	if (m0 != NULL) {
		if ((m0->m_flags & M_PKTHDR) == 0)
			panic("sbappendaddr");
		space += m0->m_pkthdr.len;
#ifdef MBUFTRACE
		m_claimm(m0, sb->sb_mowner);
#endif
	}
	for (n = control; n; n = n->m_next) {
		space += n->m_len;
		MCLAIM(n, sb->sb_mowner);
		if (n->m_next == 0)	/* keep pointer to last control buf */
			break;
	}
	if (space > sbspace(sb))
		return (0);
	MGET(m, M_DONTWAIT, MT_SONAME);
	if (m == 0)
		return (0);
	MCLAIM(m, sb->sb_mowner);
	/*
	 * XXX avoid 'comparison always true' warning which isn't easily
	 * avoided.
	 */
	len = asa->sa_len;
	if (len > MLEN) {
		MEXTMALLOC(m, asa->sa_len, M_NOWAIT);
		if ((m->m_flags & M_EXT) == 0) {
			m_free(m);
			return (0);
		}
	}
	m->m_len = asa->sa_len;
	memcpy(mtod(m, void *), asa, asa->sa_len);
	if (n)
		n->m_next = m0;		/* concatenate data to control */
	else
		control = m0;
	m->m_next = control;

	SBLASTRECORDCHK(sb, "sbappendaddr 1");

	for (n = m; n->m_next != NULL; n = n->m_next)
		sballoc(sb, n);
	sballoc(sb, n);
	nlast = n;
	SBLINKRECORD(sb, m);

	sb->sb_mbtail = nlast;
	SBLASTMBUFCHK(sb, "sbappendaddr");
	SBLASTRECORDCHK(sb, "sbappendaddr 2");

	return (1);
}
Beispiel #20
0
int main(int argc, char *argv[])
{
	struct token_s *token;
	FILE *fp;
	STRBUF *sb;
	struct token_s **tokens=NULL;
	size_t ntokens=0;
	struct node_s root_node;
	int lno=1, cno=0;
	struct token_s end_token={NULL, 0, TT_END, 0, 0, NULL, 0, 0};
	const char *testmodule=NULL, *testcode=NULL;
	size_t parsed;

	if (argc>1 && !strcmp(argv[1], "-t")) {
		if (argc>2) testmodule=argv[2];
		if (argc>3) testcode=argv[3];
		test(testmodule, testcode);
		return EXIT_SUCCESS;
	}

	sb=sballoc(1024);

	if (argc>1) fp=fopen(argv[1], "r");
	else fp=stdin;

	if (!fp) {
		fprintf(stderr, "ERROR: Can\'t open file %s for reading\n", argv[1]);
		return EXIT_FAILURE;
	}

	while ((token=gettoken(fp, sb, &lno, &cno))) {
		/* TODO: Handle TT_UNKNOWN as error in the future */

		if (token->type==TT_PREPROCESSOR) {
			skip_to_eol(fp, sb, &lno, &cno);
			continue;
		}

		if (!istobeignored(token) && token->type!=TT_NULL) {
			//(void)puts(" Added");
			tokens=(struct token_s **)realloc(tokens, ++ntokens * sizeof *tokens);
			tokens[ntokens-1]=token;
		}
	}
	tokens=(struct token_s **)realloc(tokens, ++ntokens * sizeof *tokens);
	tokens[ntokens-1]=&end_token;

	memset(&root_node, 0, sizeof root_node);
	root_node.type=NT_ROOT;

	parsed=parse(&root_node, tokens);

	//printf(" ====== Nodes (JSON)\n");
	print_node_json(&root_node, 0);

	putchar('\n');

	/*(void)getchar();*/

	(void)sbfree(sb);

	printf("tokens=%d, parsed=%d\n", (int)ntokens-1, (int)parsed);

	return (ntokens-1u)==parsed ? EXIT_SUCCESS : EXIT_FAILURE;
}
Beispiel #21
0
/*
 * Compress mbuf chain m into the socket buffer sb following mbuf tailm.
 * If tailm is null, the buffer is presumed empty.  Also, as a side-effect,
 * increment the sockbuf counts for each mbuf in the chain.
 */
void
sbcompress(struct sockbuf *sb, struct mbuf *m, struct mbuf *tailm)
{
	int eor = 0;
	struct mbuf *free_chain = NULL;

	mbuftrackid(m, 23);

	sbcheck(sb);
	while (m) {
		struct mbuf *o;

		eor |= m->m_flags & M_EOR;
		/*
		 * Disregard empty mbufs as long as we don't encounter
		 * an end-of-record or there is a trailing mbuf of
		 * the same type to propagate the EOR flag to.
		 *
		 * Defer the m_free() call because it can block and break
		 * the atomicy of the sockbuf.
		 */
		if (m->m_len == 0 &&
		    (eor == 0 ||
		     (((o = m->m_next) || (o = tailm)) &&
		      o->m_type == m->m_type))) {
			o = m->m_next;
			m->m_next = free_chain;
			free_chain = m;
			m = o;
			continue;
		}

		/* See if we can coalesce with preceding mbuf. */
		if (tailm && !(tailm->m_flags & M_EOR) && M_WRITABLE(tailm) &&
		    m->m_len <= MCLBYTES / 4 && /* XXX: Don't copy too much */
		    m->m_len <= M_TRAILINGSPACE(tailm) &&
		    tailm->m_type == m->m_type) {
			u_long mbcnt_sz;

			bcopy(mtod(m, caddr_t),
			      mtod(tailm, caddr_t) + tailm->m_len,
			      (unsigned)m->m_len);
			tailm->m_len += m->m_len;

			sb->sb_cc += m->m_len;		/* update sb counter */

			/*
			 * Fix the wrongly updated mbcnt_prealloc
			 */
			mbcnt_sz = MSIZE;
			if (m->m_flags & M_EXT)
				mbcnt_sz += m->m_ext.ext_size;
			atomic_subtract_long(&sb->sb_mbcnt_prealloc, mbcnt_sz);

			o = m->m_next;
			m->m_next = free_chain;
			free_chain = m;
			m = o;
			continue;
		}

		/* Insert whole mbuf. */
		if (tailm == NULL) {
			KASSERT(sb->sb_mb == NULL,
				("sbcompress: sb_mb not NULL"));
			sb->sb_mb = m;		/* only mbuf in sockbuf */
			sb->sb_lastrecord = m;	/* new last record */
		} else {
			tailm->m_next = m;	/* tack m on following tailm */
		}
		sb->sb_lastmbuf = m;	/* update last mbuf hint */

		tailm = m;	/* just inserted mbuf becomes the new tail */
		m = m->m_next;		/* advance to next mbuf */
		tailm->m_next = NULL;	/* split inserted mbuf off from chain */

		/* update sb counters for just added mbuf */
		sballoc(sb, tailm);

		/* clear EOR on intermediate mbufs */
		tailm->m_flags &= ~M_EOR;
	}

	/*
	 * Propogate EOR to the last mbuf
	 */
	if (eor) {
		if (tailm)
			tailm->m_flags |= eor;
		else
			kprintf("semi-panic: sbcompress");
	}

	/*
	 * Clean up any defered frees.
	 */
	while (free_chain)
		free_chain = m_free(free_chain);

	sbcheck(sb);
}
int
sbappendaddrchain(struct sockbuf *sb, const struct sockaddr *asa,
		  struct mbuf *m0, int sbprio)
{
	int space;
	struct mbuf *m, *n, *n0, *nlast;
	int error;

	KASSERT(solocked(sb->sb_so));

	/*
	 * XXX sbprio reserved for encoding priority of this* request:
	 *  SB_PRIO_NONE --> honour normal sb limits
	 *  SB_PRIO_ONESHOT_OVERFLOW --> if socket has any space,
	 *	take whole chain. Intended for large requests
	 *      that should be delivered atomically (all, or none).
	 * SB_PRIO_OVERDRAFT -- allow a small (2*MLEN) overflow
	 *       over normal socket limits, for messages indicating
	 *       buffer overflow in earlier normal/lower-priority messages
	 * SB_PRIO_BESTEFFORT -->  ignore limits entirely.
	 *       Intended for  kernel-generated messages only.
	 *        Up to generator to avoid total mbuf resource exhaustion.
	 */
	(void)sbprio;

	if (m0 && (m0->m_flags & M_PKTHDR) == 0)
		panic("sbappendaddrchain");

	space = sbspace(sb);

#ifdef notyet
	/*
	 * Enforce SB_PRIO_* limits as described above.
	 */
#endif

	n0 = NULL;
	nlast = NULL;
	for (m = m0; m; m = m->m_nextpkt) {
		struct mbuf *np;

#ifdef MBUFTRACE
		m_claimm(m, sb->sb_mowner);
#endif

		/* Prepend sockaddr to this record (m) of input chain m0 */
	  	n = m_prepend_sockaddr(sb, m, asa);
		if (n == NULL) {
			error = ENOBUFS;
			goto bad;
		}

		/* Append record (asa+m) to end of new chain n0 */
		if (n0 == NULL) {
			n0 = n;
		} else {
			nlast->m_nextpkt = n;
		}
		/* Keep track of last record on new chain */
		nlast = n;

		for (np = n; np; np = np->m_next)
			sballoc(sb, np);
	}

	SBLASTRECORDCHK(sb, "sbappendaddrchain 1");

	/* Drop the entire chain of (asa+m) records onto the socket */
	SBLINKRECORDCHAIN(sb, n0, nlast);

	SBLASTRECORDCHK(sb, "sbappendaddrchain 2");

	for (m = nlast; m->m_next; m = m->m_next)
		;
	sb->sb_mbtail = m;
	SBLASTMBUFCHK(sb, "sbappendaddrchain");

	return (1);

bad:
	/*
	 * On error, free the prepended addreseses. For consistency
	 * with sbappendaddr(), leave it to our caller to free
	 * the input record chain passed to us as m0.
	 */
	while ((n = n0) != NULL) {
	  	struct mbuf *np;

		/* Undo the sballoc() of this record */
		for (np = n; np; np = np->m_next)
			sbfree(sb, np);

		n0 = n->m_nextpkt;	/* iterate at next prepended address */
		MFREE(n, np);		/* free prepended address (not data) */
	}
	return 0;
}