Use m_unshare()+m_copyback() instead of m_freem()+m_devget() to keep
original mbuf chain headers. It can be less efficient in some cases, but it looks better then mess of copying headers into the nonempty chain.
This commit is contained in:
parent
963ae12224
commit
74ed22786b
@ -459,6 +459,13 @@ ng_deflate_compress(node_p node, struct mbuf *m, struct mbuf **resultp)
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
/* We must own the mbuf chain exclusively to modify it. */
|
||||
m = m_unshare(m, M_DONTWAIT);
|
||||
if (m == NULL) {
|
||||
priv->stats.Errors++;
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
/* Work with contiguous regions of memory. */
|
||||
m_copydata(m, 0, inlen, (caddr_t)priv->inbuf);
|
||||
outlen = DEFLATE_BUF_SIZE;
|
||||
@ -497,19 +504,19 @@ ng_deflate_compress(node_p node, struct mbuf *m, struct mbuf **resultp)
|
||||
priv->stats.FramesUncomp++;
|
||||
priv->stats.OutOctets+=inlen;
|
||||
} else {
|
||||
NG_FREE_M(m);
|
||||
|
||||
/* Install header. */
|
||||
((u_int16_t *)priv->outbuf)[0] = htons(PROT_COMPD);
|
||||
((u_int16_t *)priv->outbuf)[1] = htons(priv->seqnum);
|
||||
|
||||
/* Return packet in an mbuf. */
|
||||
*resultp = m_devget((caddr_t)priv->outbuf, outlen, 0, NULL,
|
||||
NULL);
|
||||
if (*resultp == NULL) {
|
||||
m_copyback(m, 0, outlen, (caddr_t)priv->outbuf);
|
||||
if (m->m_pkthdr.len < outlen) {
|
||||
m_freem(m);
|
||||
priv->stats.Errors++;
|
||||
return (ENOMEM);
|
||||
};
|
||||
} else if (outlen < m->m_pkthdr.len)
|
||||
m_adj(m, outlen - m->m_pkthdr.len);
|
||||
*resultp = m;
|
||||
priv->stats.FramesComp++;
|
||||
priv->stats.OutOctets+=outlen;
|
||||
}
|
||||
@ -546,6 +553,13 @@ ng_deflate_decompress(node_p node, struct mbuf *m, struct mbuf **resultp)
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
/* We must own the mbuf chain exclusively to modify it. */
|
||||
m = m_unshare(m, M_DONTWAIT);
|
||||
if (m == NULL) {
|
||||
priv->stats.Errors++;
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
/* Work with contiguous regions of memory. */
|
||||
m_copydata(m, 0, inlen, (caddr_t)priv->inbuf);
|
||||
|
||||
@ -610,25 +624,24 @@ ng_deflate_decompress(node_p node, struct mbuf *m, struct mbuf **resultp)
|
||||
/* Calculate resulting size. */
|
||||
outlen -= priv->cx.avail_out;
|
||||
|
||||
NG_FREE_M(m);
|
||||
|
||||
/* Decompress protocol. */
|
||||
if ((priv->outbuf[1] & 0x01) != 0) {
|
||||
priv->outbuf[0] = 0;
|
||||
/* Return packet in an mbuf. */
|
||||
*resultp = m_devget((caddr_t)priv->outbuf, outlen, 0,
|
||||
NULL, NULL);
|
||||
m_copyback(m, 0, outlen, (caddr_t)priv->outbuf);
|
||||
} else {
|
||||
outlen--;
|
||||
/* Return packet in an mbuf. */
|
||||
*resultp = m_devget((caddr_t)(priv->outbuf + 1),
|
||||
outlen, 0, NULL, NULL);
|
||||
m_copyback(m, 0, outlen, (caddr_t)(priv->outbuf + 1));
|
||||
}
|
||||
if (*resultp == NULL) {
|
||||
if (m->m_pkthdr.len < outlen) {
|
||||
m_freem(m);
|
||||
priv->stats.Errors++;
|
||||
priv->seqnum = 0;
|
||||
return (ENOMEM);
|
||||
};
|
||||
} else if (outlen < m->m_pkthdr.len)
|
||||
m_adj(m, outlen - m->m_pkthdr.len);
|
||||
*resultp = m;
|
||||
priv->stats.FramesPlain++;
|
||||
priv->stats.OutOctets+=outlen;
|
||||
|
||||
|
@ -470,6 +470,11 @@ ng_mppc_compress(node_p node, struct mbuf **datap)
|
||||
u_int16_t header;
|
||||
struct mbuf *m = *datap;
|
||||
|
||||
/* We must own the mbuf chain exclusively to modify it. */
|
||||
m = m_unshare(m, M_DONTWAIT);
|
||||
if (m == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
/* Initialize */
|
||||
header = d->cc;
|
||||
|
||||
@ -529,8 +534,12 @@ err1:
|
||||
header |= MPPC_FLAG_RESTART;
|
||||
|
||||
/* Replace m by the compresed one. */
|
||||
m_freem(m);
|
||||
m = m_devget((caddr_t)outbuf, outlen, 0, NULL, NULL);
|
||||
m_copyback(m, 0, outlen, (caddr_t)outbuf);
|
||||
if (m->m_pkthdr.len < outlen) {
|
||||
m_freem(m);
|
||||
m = NULL;
|
||||
} else if (outlen < m->m_pkthdr.len)
|
||||
m_adj(m, outlen - m->m_pkthdr.len);
|
||||
}
|
||||
d->flushed = (rtn & MPPC_EXPANDED) != 0
|
||||
|| (flags & MPPC_SAVE_HISTORY) == 0;
|
||||
@ -538,7 +547,7 @@ err1:
|
||||
free(inbuf, M_NETGRAPH_MPPC);
|
||||
free(outbuf, M_NETGRAPH_MPPC);
|
||||
|
||||
/* Check m_devget() result. */
|
||||
/* Check mbuf chain reload result. */
|
||||
if (m == NULL) {
|
||||
if (!d->flushed) {
|
||||
MPPC_InitCompressionHistory(d->history);
|
||||
@ -557,18 +566,6 @@ err1:
|
||||
/* Set header bits */
|
||||
header |= MPPC_FLAG_ENCRYPTED;
|
||||
|
||||
/* We must own the mbuf chain exclusively to modify it. */
|
||||
m = m_unshare(m, M_DONTWAIT);
|
||||
if (m == NULL) {
|
||||
if (!d->flushed) {
|
||||
#ifdef NETGRAPH_MPPC_COMPRESSION
|
||||
MPPC_InitCompressionHistory(d->history);
|
||||
#endif
|
||||
d->flushed = 1;
|
||||
}
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
/* Update key if it's time */
|
||||
if ((d->cfg.bits & MPPE_STATELESS) != 0
|
||||
|| (d->cc & MPPE_UPDATE_MASK) == MPPE_UPDATE_FLAG) {
|
||||
@ -615,6 +612,11 @@ ng_mppc_decompress(node_p node, struct mbuf **datap)
|
||||
u_int numLost;
|
||||
struct mbuf *m = *datap;
|
||||
|
||||
/* We must own the mbuf chain exclusively to modify it. */
|
||||
m = m_unshare(m, M_DONTWAIT);
|
||||
if (m == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
/* Pull off header */
|
||||
if (m->m_pkthdr.len < MPPC_HDRLEN) {
|
||||
m_freem(m);
|
||||
@ -694,11 +696,6 @@ ng_mppc_decompress(node_p node, struct mbuf **datap)
|
||||
d->cfg.startkey, d->key, &d->rc4);
|
||||
}
|
||||
|
||||
/* We must own the mbuf chain exclusively to modify it. */
|
||||
m = m_unshare(m, M_DONTWAIT);
|
||||
if (m == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
/* Decrypt packet */
|
||||
m1 = m;
|
||||
while (m1 != NULL) {
|
||||
@ -786,8 +783,12 @@ failed:
|
||||
free(buf, M_NETGRAPH_MPPC);
|
||||
len = decomplen - destCnt;
|
||||
|
||||
m_freem(m);
|
||||
m = m_devget((caddr_t)decompbuf, len, 0, NULL, NULL);
|
||||
m_copyback(m, 0, len, (caddr_t)decompbuf);
|
||||
if (m->m_pkthdr.len < len) {
|
||||
m_freem(m);
|
||||
m = NULL;
|
||||
} else if (len < m->m_pkthdr.len)
|
||||
m_adj(m, len - m->m_pkthdr.len);
|
||||
free(decompbuf, M_NETGRAPH_MPPC);
|
||||
}
|
||||
#endif
|
||||
|
@ -400,11 +400,16 @@ ng_pred1_compress(node_p node, struct mbuf *m, struct mbuf **resultp)
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
/* We must own the mbuf chain exclusively to modify it. */
|
||||
m = m_unshare(m, M_DONTWAIT);
|
||||
if (m == NULL) {
|
||||
priv->stats.Errors++;
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
/* Work with contiguous regions of memory. */
|
||||
m_copydata(m, 0, inlen, (caddr_t)(priv->inbuf + 2));
|
||||
|
||||
NG_FREE_M(m);
|
||||
|
||||
lenn = htons(inlen & 0x7FFF);
|
||||
|
||||
/* Compute FCS. */
|
||||
@ -437,12 +442,14 @@ ng_pred1_compress(node_p node, struct mbuf *m, struct mbuf **resultp)
|
||||
outlen += 2;
|
||||
|
||||
/* Return packet in an mbuf. */
|
||||
*resultp = m_devget((caddr_t)out, outlen, 0, NULL, NULL);
|
||||
if (*resultp == NULL) {
|
||||
priv->stats.Errors++;
|
||||
return (ENOMEM);
|
||||
};
|
||||
|
||||
m_copyback(m, 0, outlen, (caddr_t)out);
|
||||
if (m->m_pkthdr.len < outlen) {
|
||||
m_freem(m);
|
||||
priv->stats.Errors++;
|
||||
return (ENOMEM);
|
||||
} else if (outlen < m->m_pkthdr.len)
|
||||
m_adj(m, outlen - m->m_pkthdr.len);
|
||||
*resultp = m;
|
||||
priv->stats.OutOctets += outlen;
|
||||
|
||||
return (0);
|
||||
@ -471,6 +478,13 @@ ng_pred1_decompress(node_p node, struct mbuf *m, struct mbuf **resultp)
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
/* We must own the mbuf chain exclusively to modify it. */
|
||||
m = m_unshare(m, M_DONTWAIT);
|
||||
if (m == NULL) {
|
||||
priv->stats.Errors++;
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
/* Work with contiguous regions of memory. */
|
||||
m_copydata(m, 0, inlen, (caddr_t)priv->inbuf);
|
||||
|
||||
@ -485,13 +499,12 @@ ng_pred1_decompress(node_p node, struct mbuf *m, struct mbuf **resultp)
|
||||
|
||||
/* Is data compressed or not really? */
|
||||
if (cf) {
|
||||
NG_FREE_M(m);
|
||||
|
||||
priv->stats.FramesComp++;
|
||||
len1 = Pred1Decompress(node, priv->inbuf + 2, priv->outbuf,
|
||||
inlen - 4, PRED1_BUF_SIZE);
|
||||
if (len != len1) {
|
||||
/* Error is detected. Send reset request */
|
||||
m_freem(m);
|
||||
priv->stats.Errors++;
|
||||
log(LOG_NOTICE, "ng_pred1: Comp length error (%d) "
|
||||
"--> len (%d)\n", len, len1);
|
||||
@ -510,17 +523,21 @@ ng_pred1_decompress(node_p node, struct mbuf *m, struct mbuf **resultp)
|
||||
fcs = Crc16(fcs, priv->inbuf + inlen - 2, 2);
|
||||
|
||||
if (fcs != PPP_GOODFCS) {
|
||||
m_freem(m);
|
||||
priv->stats.Errors++;
|
||||
log(LOG_NOTICE, "ng_pred1: Pred1: Bad CRC-16\n");
|
||||
return (EIO);
|
||||
}
|
||||
|
||||
/* Return packet in an mbuf. */
|
||||
*resultp = m_devget((caddr_t)priv->outbuf, len, 0, NULL, NULL);
|
||||
if (*resultp == NULL) {
|
||||
m_copyback(m, 0, len, (caddr_t)priv->outbuf);
|
||||
if (m->m_pkthdr.len < len) {
|
||||
m_freem(m);
|
||||
priv->stats.Errors++;
|
||||
return (ENOMEM);
|
||||
};
|
||||
} else if (len < m->m_pkthdr.len)
|
||||
m_adj(m, len - m->m_pkthdr.len);
|
||||
*resultp = m;
|
||||
|
||||
} else {
|
||||
priv->stats.FramesUncomp++;
|
||||
|
Loading…
x
Reference in New Issue
Block a user