Annotation of embedaddon/mpd/src/ccp_deflate.c, revision 1.1.1.1
1.1 misho 1:
2: /*
3: * ccp_deflate.c
4: *
5: * Written by Alexander Motin <mav@FreeBSD.org>
6: */
7:
8: #include "defs.h"
9:
10: #ifdef CCP_DEFLATE
11:
12: #include "ppp.h"
13: #include "ccp.h"
14: #include "util.h"
15: #include "ngfunc.h"
16:
17: #include <netgraph/ng_message.h>
18: #include <netgraph.h>
19:
20: /*
21: * INTERNAL FUNCTIONS
22: */
23:
24: static int DeflateInit(Bund b, int direction);
25: static int DeflateConfigure(Bund b);
26: static char *DeflateDescribe(Bund b, int xmit, char *buf, size_t len);
27: static void DeflateCleanup(Bund b, int direction);
28:
29: static u_char *DeflateBuildConfigReq(Bund b, u_char *cp, int *ok);
30: static void DeflateDecodeConfigReq(Fsm fp, FsmOption opt, int mode);
31: static Mbuf DeflateRecvResetReq(Bund b, int id, Mbuf bp, int *noAck);
32: static Mbuf DeflateSendResetReq(Bund b);
33: static void DeflateRecvResetAck(Bund b, int id, Mbuf bp);
34: static int DeflateNegotiated(Bund b, int xmit);
35: static int DeflateSubtractBloat(Bund b, int size);
36: static int DeflateStat(Context ctx, int dir);
37:
38: /*
39: * GLOBAL VARIABLES
40: */
41:
42: const struct comptype gCompDeflateInfo =
43: {
44: "deflate",
45: CCP_TY_DEFLATE,
46: 2,
47: DeflateInit,
48: DeflateConfigure,
49: NULL,
50: DeflateDescribe,
51: DeflateSubtractBloat,
52: DeflateCleanup,
53: DeflateBuildConfigReq,
54: DeflateDecodeConfigReq,
55: DeflateSendResetReq,
56: DeflateRecvResetReq,
57: DeflateRecvResetAck,
58: DeflateNegotiated,
59: DeflateStat,
60: NULL,
61: NULL,
62: };
63:
64: /*
65: * DeflateInit()
66: */
67:
68: static int
69: DeflateInit(Bund b, int dir)
70: {
71: DeflateInfo const deflate = &b->ccp.deflate;
72: struct ng_deflate_config conf;
73: struct ngm_mkpeer mp;
74: char path[NG_PATHSIZ];
75: const char *deflatehook, *ppphook;
76: ng_ID_t id;
77:
78: /* Initialize configuration structure */
79: memset(&conf, 0, sizeof(conf));
80: conf.enable = 1;
81: if (dir == COMP_DIR_XMIT) {
82: ppphook = NG_PPP_HOOK_COMPRESS;
83: deflatehook = NG_DEFLATE_HOOK_COMP;
84: conf.windowBits = deflate->xmit_windowBits;
85: } else {
86: ppphook = NG_PPP_HOOK_DECOMPRESS;
87: deflatehook = NG_DEFLATE_HOOK_DECOMP;
88: conf.windowBits = deflate->recv_windowBits;
89: }
90:
91: /* Attach a new DEFLATE node to the PPP node */
92: snprintf(path, sizeof(path), "[%x]:", b->nodeID);
93: strcpy(mp.type, NG_DEFLATE_NODE_TYPE);
94: strcpy(mp.ourhook, ppphook);
95: strcpy(mp.peerhook, deflatehook);
96: if (NgSendMsg(gCcpCsock, path,
97: NGM_GENERIC_COOKIE, NGM_MKPEER, &mp, sizeof(mp)) < 0) {
98: Perror("[%s] can't create %s node", b->name, mp.type);
99: return(-1);
100: }
101:
102: strlcat(path, ppphook, sizeof(path));
103:
104: id = NgGetNodeID(-1, path);
105: if (dir == COMP_DIR_XMIT) {
106: b->ccp.comp_node_id = id;
107: } else {
108: b->ccp.decomp_node_id = id;
109: }
110:
111: /* Configure DEFLATE node */
112: snprintf(path, sizeof(path), "[%x]:", id);
113: if (NgSendMsg(gCcpCsock, path,
114: NGM_DEFLATE_COOKIE, NGM_DEFLATE_CONFIG, &conf, sizeof(conf)) < 0) {
115: Perror("[%s] can't config %s node at %s",
116: b->name, NG_DEFLATE_NODE_TYPE, path);
117: NgFuncShutdownNode(gCcpCsock, b->name, path);
118: return(-1);
119: }
120:
121: return 0;
122: }
123:
124: /*
125: * DeflateConfigure()
126: */
127:
128: static int
129: DeflateConfigure(Bund b)
130: {
131: CcpState const ccp = &b->ccp;
132: DeflateInfo const deflate = &ccp->deflate;
133:
134: deflate->xmit_windowBits=15;
135: deflate->recv_windowBits=0;
136:
137: return(0);
138: }
139:
140: /*
141: * DeflateCleanup()
142: */
143:
144: static char *
145: DeflateDescribe(Bund b, int dir, char *buf, size_t len)
146: {
147: CcpState const ccp = &b->ccp;
148: DeflateInfo const deflate = &ccp->deflate;
149:
150: switch (dir) {
151: case COMP_DIR_XMIT:
152: snprintf(buf, len, "win %d", deflate->xmit_windowBits);
153: break;
154: case COMP_DIR_RECV:
155: snprintf(buf, len, "win %d", deflate->recv_windowBits);
156: break;
157: default:
158: assert(0);
159: return(NULL);
160: }
161: return (buf);
162: }
163:
164: /*
165: * DeflateCleanup()
166: */
167:
168: void
169: DeflateCleanup(Bund b, int dir)
170: {
171: char path[NG_PATHSIZ];
172:
173: /* Remove node */
174: if (dir == COMP_DIR_XMIT) {
175: snprintf(path, sizeof(path), "[%x]:", b->ccp.comp_node_id);
176: b->ccp.comp_node_id = 0;
177: } else {
178: snprintf(path, sizeof(path), "[%x]:", b->ccp.decomp_node_id);
179: b->ccp.decomp_node_id = 0;
180: }
181: NgFuncShutdownNode(gCcpCsock, b->name, path);
182: }
183:
184: /*
185: * DeflateRecvResetReq()
186: */
187:
188: static Mbuf
189: DeflateRecvResetReq(Bund b, int id, Mbuf bp, int *noAck)
190: {
191: char path[NG_PATHSIZ];
192: /* Forward ResetReq to the DEFLATE compression node */
193: snprintf(path, sizeof(path), "[%x]:", b->ccp.comp_node_id);
194: if (NgSendMsg(gCcpCsock, path,
195: NGM_DEFLATE_COOKIE, NGM_DEFLATE_RESETREQ, NULL, 0) < 0) {
196: Perror("[%s] reset-req to %s node", b->name, NG_DEFLATE_NODE_TYPE);
197: }
198: return(NULL);
199: }
200:
201: /*
202: * DeflateSendResetReq()
203: */
204:
205: static Mbuf
206: DeflateSendResetReq(Bund b)
207: {
208: return(NULL);
209: }
210:
211: /*
212: * DeflateRecvResetAck()
213: */
214:
215: static void
216: DeflateRecvResetAck(Bund b, int id, Mbuf bp)
217: {
218: char path[NG_PATHSIZ];
219: /* Forward ResetReq to the DEFLATE compression node */
220: snprintf(path, sizeof(path), "[%x]:", b->ccp.decomp_node_id);
221: if (NgSendMsg(gCcpCsock, path,
222: NGM_DEFLATE_COOKIE, NGM_DEFLATE_RESETREQ, NULL, 0) < 0) {
223: Perror("[%s] reset-ack to %s node", b->name, NG_DEFLATE_NODE_TYPE);
224: }
225: }
226:
227: /*
228: * DeflateBuildConfigReq()
229: */
230:
231: static u_char *
232: DeflateBuildConfigReq(Bund b, u_char *cp, int *ok)
233: {
234: CcpState const ccp = &b->ccp;
235: DeflateInfo const deflate = &ccp->deflate;
236: u_int16_t opt;
237:
238: if (deflate->xmit_windowBits > 0) {
239: opt = ((deflate->xmit_windowBits-8)<<12) + (8<<8) + (0<<2) + 0;
240:
241: cp = FsmConfValue(cp, CCP_TY_DEFLATE, -2, &opt);
242: *ok = 1;
243: }
244: return (cp);
245: }
246:
247: /*
248: * DeflateDecodeConfigReq()
249: */
250:
251: static void
252: DeflateDecodeConfigReq(Fsm fp, FsmOption opt, int mode)
253: {
254: Bund b = (Bund)fp->arg;
255: CcpState const ccp = &b->ccp;
256: DeflateInfo const deflate = &ccp->deflate;
257: u_int16_t o;
258: u_char window, method, chk;
259:
260: /* Sanity check */
261: if (opt->len != 4) {
262: Log(LG_CCP, ("[%s] bogus length %d", b->name, opt->len));
263: if (mode == MODE_REQ)
264: FsmRej(fp, opt);
265: return;
266: }
267:
268: /* Get bits */
269: memcpy(&o, opt->data, 2);
270: o = ntohs(o);
271: window = (o>>12)&0x000F;
272: method = (o>>8)&0x000F;
273: chk = o&0x0003;
274:
275: /* Display it */
276: Log(LG_CCP, ("[%s] 0x%04x: w:%d, m:%d, c:%d", b->name, o, window, method, chk));
277:
278: /* Deal with it */
279: switch (mode) {
280: case MODE_REQ:
281: if ((window > 0) && (window<=7) && (method == 8) && (chk == 0)) {
282: deflate->recv_windowBits = window + 8;
283: FsmAck(fp, opt);
284: } else {
285: o = htons((7<<12) + (8<<8) + (0<<2) + 0);
286: memcpy(opt->data, &o, 2);
287: FsmNak(fp, opt);
288: }
289: break;
290:
291: case MODE_NAK:
292: if ((window > 0) && (window<=7) && (method == 8) && (chk == 0))
293: deflate->xmit_windowBits = window + 8;
294: else {
295: deflate->xmit_windowBits = 0;
296: }
297: break;
298: }
299: }
300:
301: /*
302: * DeflateNegotiated()
303: */
304:
305: static int
306: DeflateNegotiated(Bund b, int dir)
307: {
308: return 1;
309: }
310:
311: /*
312: * DeflateSubtractBloat()
313: */
314:
315: static int
316: DeflateSubtractBloat(Bund b, int size)
317: {
318: return(size + CCP_OVERHEAD); /* Compression compensate header size */
319: }
320:
321: static int
322: DeflateStat(Context ctx, int dir)
323: {
324: Bund b = ctx->bund;
325: char path[NG_PATHSIZ];
326: struct ng_deflate_stats stats;
327: union {
328: u_char buf[sizeof(struct ng_mesg) + sizeof(stats)];
329: struct ng_mesg reply;
330: } u;
331:
332: switch (dir) {
333: case COMP_DIR_XMIT:
334: snprintf(path, sizeof(path), "mpd%d-%s:%s", gPid, b->name,
335: NG_PPP_HOOK_COMPRESS);
336: break;
337: case COMP_DIR_RECV:
338: snprintf(path, sizeof(path), "mpd%d-%s:%s", gPid, b->name,
339: NG_PPP_HOOK_DECOMPRESS);
340: break;
341: default:
342: assert(0);
343: }
344: if (NgFuncSendQuery(path, NGM_DEFLATE_COOKIE, NGM_DEFLATE_GET_STATS, NULL, 0,
345: &u.reply, sizeof(u), NULL) < 0) {
346: Perror("[%s] can't get %s stats", b->name, NG_DEFLATE_NODE_TYPE);
347: return(0);
348: }
349: memcpy(&stats, u.reply.data, sizeof(stats));
350: switch (dir) {
351: case COMP_DIR_XMIT:
352: Printf("\tBytes\t: %llu -> %llu (%+lld%%)\r\n",
353: stats.InOctets,
354: stats.OutOctets,
355: ((stats.InOctets!=0)?
356: ((int64_t)(stats.OutOctets - stats.InOctets)*100/(int64_t)stats.InOctets):
357: 0));
358: Printf("\tFrames\t: %llu -> %lluc + %lluu\r\n",
359: stats.FramesPlain,
360: stats.FramesComp,
361: stats.FramesUncomp);
362: Printf("\tErrors\t: %llu\r\n",
363: stats.Errors);
364: break;
365: case COMP_DIR_RECV:
366: Printf("\tBytes\t: %llu <- %llu (%+lld%%)\r\n",
367: stats.OutOctets,
368: stats.InOctets,
369: ((stats.OutOctets!=0)?
370: ((int64_t)(stats.InOctets - stats.OutOctets)*100/(int64_t)stats.OutOctets):
371: 0));
372: Printf("\tFrames\t: %llu <- %lluc + %lluu\r\n",
373: stats.FramesPlain,
374: stats.FramesComp,
375: stats.FramesUncomp);
376: Printf("\tErrors\t: %llu\r\n",
377: stats.Errors);
378: break;
379: default:
380: assert(0);
381: }
382: return (0);
383: }
384:
385: #endif /* CCP_DEFLATE */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>