Changeset View
Changeset View
Standalone View
Standalone View
sys/netgraph/ng_deflate.c
Show All 35 Lines | |||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/mbuf.h> | #include <sys/mbuf.h> | ||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/endian.h> | #include <sys/endian.h> | ||||
#include <sys/errno.h> | #include <sys/errno.h> | ||||
#include <sys/syslog.h> | #include <sys/syslog.h> | ||||
#include <sys/zlib.h> | #include <contrib/zlib/zlib.h> | ||||
#include <netgraph/ng_message.h> | #include <netgraph/ng_message.h> | ||||
#include <netgraph/netgraph.h> | #include <netgraph/netgraph.h> | ||||
#include <netgraph/ng_parse.h> | #include <netgraph/ng_parse.h> | ||||
#include <netgraph/ng_deflate.h> | #include <netgraph/ng_deflate.h> | ||||
#include "opt_netgraph.h" | #include "opt_netgraph.h" | ||||
Show All 24 Lines | |||||
static ng_constructor_t ng_deflate_constructor; | static ng_constructor_t ng_deflate_constructor; | ||||
static ng_rcvmsg_t ng_deflate_rcvmsg; | static ng_rcvmsg_t ng_deflate_rcvmsg; | ||||
static ng_shutdown_t ng_deflate_shutdown; | static ng_shutdown_t ng_deflate_shutdown; | ||||
static ng_newhook_t ng_deflate_newhook; | static ng_newhook_t ng_deflate_newhook; | ||||
static ng_rcvdata_t ng_deflate_rcvdata; | static ng_rcvdata_t ng_deflate_rcvdata; | ||||
static ng_disconnect_t ng_deflate_disconnect; | static ng_disconnect_t ng_deflate_disconnect; | ||||
/* Helper functions */ | /* Helper functions */ | ||||
static void *z_alloc(void *, u_int items, u_int size); | |||||
static void z_free(void *, void *ptr); | |||||
static int ng_deflate_compress(node_p node, | static int ng_deflate_compress(node_p node, | ||||
struct mbuf *m, struct mbuf **resultp); | struct mbuf *m, struct mbuf **resultp); | ||||
static int ng_deflate_decompress(node_p node, | static int ng_deflate_decompress(node_p node, | ||||
struct mbuf *m, struct mbuf **resultp); | struct mbuf *m, struct mbuf **resultp); | ||||
static void ng_deflate_reset_req(node_p node); | static void ng_deflate_reset_req(node_p node); | ||||
/* Parse type for struct ng_deflate_config. */ | /* Parse type for struct ng_deflate_config. */ | ||||
static const struct ng_parse_struct_field ng_deflate_config_type_fields[] | static const struct ng_parse_struct_field ng_deflate_config_type_fields[] | ||||
▲ Show 20 Lines • Show All 155 Lines • ▼ Show 20 Lines | if (priv->cfg.enable) { | ||||
priv->cfg.enable = 0; | priv->cfg.enable = 0; | ||||
} | } | ||||
/* Configuration is OK, reset to it. */ | /* Configuration is OK, reset to it. */ | ||||
priv->cfg = *cfg; | priv->cfg = *cfg; | ||||
if (priv->cfg.enable) { | if (priv->cfg.enable) { | ||||
priv->cx.next_in = NULL; | priv->cx.next_in = NULL; | ||||
priv->cx.zalloc = z_alloc; | |||||
priv->cx.zfree = z_free; | |||||
int res; | int res; | ||||
if (priv->compress) { | if (priv->compress) { | ||||
if ((res = deflateInit2(&priv->cx, | if ((res = deflateInit2(&priv->cx, | ||||
Z_DEFAULT_COMPRESSION, Z_DEFLATED, | Z_DEFAULT_COMPRESSION, Z_DEFLATED, | ||||
-cfg->windowBits, 8, | -cfg->windowBits, 8, | ||||
Z_DEFAULT_STRATEGY)) != Z_OK) { | Z_DEFAULT_STRATEGY)) != Z_OK) { | ||||
log(LOG_NOTICE, | log(LOG_NOTICE, | ||||
"deflateInit2: error %d, %s\n", | "deflateInit2: error %d, %s\n", | ||||
▲ Show 20 Lines • Show All 108 Lines • ▼ Show 20 Lines | |||||
static int | static int | ||||
ng_deflate_shutdown(node_p node) | ng_deflate_shutdown(node_p node) | ||||
{ | { | ||||
const priv_p priv = NG_NODE_PRIVATE(node); | const priv_p priv = NG_NODE_PRIVATE(node); | ||||
/* Take down netgraph node. */ | /* Take down netgraph node. */ | ||||
if (priv->cfg.enable) { | if (priv->cfg.enable) { | ||||
if (priv->compress) | if (priv->compress) | ||||
deflateEnd(&priv->cx); | deflateEnd(&priv->cx); | ||||
else | else | ||||
inflateEnd(&priv->cx); | inflateEnd(&priv->cx); | ||||
emaste: unrelated whitespace change? | |||||
} | } | ||||
free(priv, M_NETGRAPH_DEFLATE); | free(priv, M_NETGRAPH_DEFLATE); | ||||
NG_NODE_SET_PRIVATE(node, NULL); | NG_NODE_SET_PRIVATE(node, NULL); | ||||
NG_NODE_UNREF(node); /* let the node escape */ | NG_NODE_UNREF(node); /* let the node escape */ | ||||
return (0); | return (0); | ||||
} | } | ||||
Show All 20 Lines | ng_deflate_disconnect(hook_p hook) | ||||
return (0); | return (0); | ||||
} | } | ||||
/************************************************************************ | /************************************************************************ | ||||
HELPER STUFF | HELPER STUFF | ||||
************************************************************************/ | ************************************************************************/ | ||||
/* | /* | ||||
* Space allocation and freeing routines for use by zlib routines. | |||||
*/ | |||||
static void * | |||||
z_alloc(void *notused, u_int items, u_int size) | |||||
{ | |||||
return (malloc(items * size, M_NETGRAPH_DEFLATE, M_NOWAIT)); | |||||
} | |||||
static void | |||||
z_free(void *notused, void *ptr) | |||||
{ | |||||
free(ptr, M_NETGRAPH_DEFLATE); | |||||
} | |||||
/* | |||||
* Compress/encrypt a packet and put the result in a new mbuf at *resultp. | * Compress/encrypt a packet and put the result in a new mbuf at *resultp. | ||||
* The original mbuf is not free'd. | * The original mbuf is not free'd. | ||||
*/ | */ | ||||
static int | static int | ||||
ng_deflate_compress(node_p node, struct mbuf *m, struct mbuf **resultp) | ng_deflate_compress(node_p node, struct mbuf *m, struct mbuf **resultp) | ||||
{ | { | ||||
const priv_p priv = NG_NODE_PRIVATE(node); | const priv_p priv = NG_NODE_PRIVATE(node); | ||||
int outlen, inlen; | int outlen, inlen; | ||||
Show All 32 Lines | ng_deflate_compress(node_p node, struct mbuf *m, struct mbuf **resultp) | ||||
} else { | } else { | ||||
priv->cx.next_in = priv->inbuf + 1; /* compress protocol */ | priv->cx.next_in = priv->inbuf + 1; /* compress protocol */ | ||||
priv->cx.avail_in = inlen - 1; | priv->cx.avail_in = inlen - 1; | ||||
} | } | ||||
priv->cx.next_out = priv->outbuf + 2 + DEFLATE_HDRLEN; | priv->cx.next_out = priv->outbuf + 2 + DEFLATE_HDRLEN; | ||||
priv->cx.avail_out = outlen - 2 - DEFLATE_HDRLEN; | priv->cx.avail_out = outlen - 2 - DEFLATE_HDRLEN; | ||||
/* Compress. */ | /* Compress. */ | ||||
rtn = deflate(&priv->cx, Z_PACKET_FLUSH); | rtn = deflate(&priv->cx, Z_SYNC_FLUSH); | ||||
ota_j.email.ne.jpUnsubmitted Done Inline ActionsZ_PACKET_FLUSH is the FreeBSD only and specific implementation. ota_j.email.ne.jp: Z_PACKET_FLUSH is the FreeBSD only and specific implementation. | |||||
/* Check return value. */ | /* Check return value. */ | ||||
if (rtn != Z_OK) { | if (rtn != Z_OK) { | ||||
priv->stats.Errors++; | priv->stats.Errors++; | ||||
log(LOG_NOTICE, "ng_deflate: compression error: %d (%s)\n", | log(LOG_NOTICE, "ng_deflate: compression error: %d (%s)\n", | ||||
rtn, priv->cx.msg); | rtn, priv->cx.msg); | ||||
NG_FREE_M(m); | NG_FREE_M(m); | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
/* Calculate resulting size. */ | /* Calculate resulting size. */ | ||||
outlen -= priv->cx.avail_out; | outlen -= priv->cx.avail_out; | ||||
Done Inline Actionsmaybe a kassert that outlen > 4 && the last 4 bytes are the expected 00 00 ff ff? emaste: maybe a kassert that outlen > 4 && the last 4 bytes are the expected 00 00 ff ff? | |||||
/* If we can't compress this packet, send it as-is. */ | /* If we can't compress this packet, send it as-is. */ | ||||
if (outlen > inlen) { | if (outlen > inlen) { | ||||
/* Return original packet uncompressed. */ | /* Return original packet uncompressed. */ | ||||
*resultp = m; | *resultp = m; | ||||
priv->stats.FramesUncomp++; | priv->stats.FramesUncomp++; | ||||
priv->stats.OutOctets+=inlen; | priv->stats.OutOctets+=inlen; | ||||
} else { | } else { | ||||
/* Install header. */ | /* Install header. */ | ||||
▲ Show 20 Lines • Show All 88 Lines • ▼ Show 20 Lines | if (proto == PROT_COMPD) { | ||||
/* Prepare to decompress. */ | /* Prepare to decompress. */ | ||||
priv->cx.next_in = priv->inbuf + offset; | priv->cx.next_in = priv->inbuf + offset; | ||||
priv->cx.avail_in = inlen - offset; | priv->cx.avail_in = inlen - offset; | ||||
/* Reserve space for protocol decompression. */ | /* Reserve space for protocol decompression. */ | ||||
priv->cx.next_out = priv->outbuf + 1; | priv->cx.next_out = priv->outbuf + 1; | ||||
priv->cx.avail_out = outlen - 1; | priv->cx.avail_out = outlen - 1; | ||||
/* Decompress. */ | /* Decompress. */ | ||||
rtn = inflate(&priv->cx, Z_PACKET_FLUSH); | rtn = inflate(&priv->cx, Z_SYNC_FLUSH); | ||||
/* Check return value. */ | /* Check return value. */ | ||||
if (rtn != Z_OK && rtn != Z_STREAM_END) { | if (rtn != Z_OK && rtn != Z_STREAM_END) { | ||||
priv->stats.Errors++; | priv->stats.Errors++; | ||||
NG_FREE_M(m); | NG_FREE_M(m); | ||||
priv->seqnum = 0; | priv->seqnum = 0; | ||||
log(LOG_NOTICE, "%s: decompression error: %d (%s)\n", | log(LOG_NOTICE, "%s: decompression error: %d (%s)\n", | ||||
__func__, rtn, priv->cx.msg); | __func__, rtn, priv->cx.msg); | ||||
Show All 37 Lines | if (proto == PROT_COMPD) { | ||||
if (priv->inbuf[0] == 0) { | if (priv->inbuf[0] == 0) { | ||||
priv->cx.next_in = priv->inbuf + 1; /* compress protocol */ | priv->cx.next_in = priv->inbuf + 1; /* compress protocol */ | ||||
priv->cx.avail_in = inlen - 1; | priv->cx.avail_in = inlen - 1; | ||||
} else { | } else { | ||||
priv->cx.next_in = priv->inbuf; | priv->cx.next_in = priv->inbuf; | ||||
priv->cx.avail_in = inlen; | priv->cx.avail_in = inlen; | ||||
} | } | ||||
rtn = inflateIncomp(&priv->cx); | rtn = inflateInit(&priv->cx); | ||||
/* Check return value */ | /* Check return value */ | ||||
if (rtn != Z_OK) { | if (rtn != Z_OK) { | ||||
priv->stats.Errors++; | priv->stats.Errors++; | ||||
log(LOG_NOTICE, "%s: inflateIncomp error: %d (%s)\n", | log(LOG_NOTICE, "%s: inflateInit error: %d (%s)\n", | ||||
__func__, rtn, priv->cx.msg); | __func__, rtn, priv->cx.msg); | ||||
NG_FREE_M(m); | NG_FREE_M(m); | ||||
priv->seqnum = 0; | priv->seqnum = 0; | ||||
Done Inline ActionsDoes this fnflate() really do a work? ota_j.email.ne.jp: Does this fnflate() really do a work?
Its output buffer begins with priv->outbuf just like… | |||||
Done Inline ActionsYes, this would pass the uncompressed data through inflate engine and update the dictionary, which will be used for later decompression (the first few packets are not compressible normally). delphij: Yes, this would pass the uncompressed data through inflate engine and update the dictionary… | |||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
*resultp = m; | *resultp = m; | ||||
priv->stats.FramesPlain++; | priv->stats.FramesPlain++; | ||||
priv->stats.OutOctets += inlen; | priv->stats.OutOctets += inlen; | ||||
} | } | ||||
Show All 23 Lines |
unrelated whitespace change?