Annotation of embedaddon/mpd/src/ccp_deflate.c, revision 1.1.1.2

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: 
1.1.1.2 ! misho     104:     if ((id = NgGetNodeID(-1, path)) == 0) {
        !           105:        Perror("[%s] Cannot get %s node id", b->name, NG_DEFLATE_NODE_TYPE);
        !           106:        goto fail;
        !           107:     }
        !           108: 
1.1       misho     109:     if (dir == COMP_DIR_XMIT) {
                    110:        b->ccp.comp_node_id = id;
                    111:     } else {
                    112:        b->ccp.decomp_node_id = id;
                    113:     }
                    114: 
                    115:     /* Configure DEFLATE node */
                    116:     snprintf(path, sizeof(path), "[%x]:", id);
                    117:     if (NgSendMsg(gCcpCsock, path,
                    118:            NGM_DEFLATE_COOKIE, NGM_DEFLATE_CONFIG, &conf, sizeof(conf)) < 0) {
                    119:        Perror("[%s] can't config %s node at %s",
                    120:            b->name, NG_DEFLATE_NODE_TYPE, path);
1.1.1.2 ! misho     121:        goto fail;
1.1       misho     122:     }
                    123: 
                    124:     return 0;
1.1.1.2 ! misho     125: 
        !           126: fail:
        !           127:     NgFuncShutdownNode(gCcpCsock, b->name, path);
        !           128:     return(-1);
1.1       misho     129: }
                    130: 
                    131: /*
                    132:  * DeflateConfigure()
                    133:  */
                    134: 
                    135: static int
                    136: DeflateConfigure(Bund b)
                    137: {
                    138:     CcpState   const ccp = &b->ccp;
                    139:     DeflateInfo        const deflate = &ccp->deflate;
                    140:   
                    141:     deflate->xmit_windowBits=15;
                    142:     deflate->recv_windowBits=0;
                    143:   
                    144:     return(0);
                    145: }
                    146: 
                    147: /*
                    148:  * DeflateCleanup()
                    149:  */
                    150: 
                    151: static char *
                    152: DeflateDescribe(Bund b, int dir, char *buf, size_t len)
                    153: {
                    154:     CcpState   const ccp = &b->ccp;
                    155:     DeflateInfo        const deflate = &ccp->deflate;
                    156: 
                    157:     switch (dir) {
                    158:        case COMP_DIR_XMIT:
                    159:            snprintf(buf, len, "win %d", deflate->xmit_windowBits);
                    160:            break;
                    161:        case COMP_DIR_RECV:
                    162:            snprintf(buf, len, "win %d", deflate->recv_windowBits);
                    163:            break;
                    164:        default:
                    165:            assert(0);
                    166:            return(NULL);
                    167:     }
                    168:     return (buf);
                    169: }
                    170: 
                    171: /*
                    172:  * DeflateCleanup()
                    173:  */
                    174: 
                    175: void
                    176: DeflateCleanup(Bund b, int dir)
                    177: {
                    178:     char               path[NG_PATHSIZ];
                    179: 
                    180:     /* Remove node */
                    181:     if (dir == COMP_DIR_XMIT) {
                    182:        snprintf(path, sizeof(path), "[%x]:", b->ccp.comp_node_id);
                    183:        b->ccp.comp_node_id = 0;
                    184:     } else {
                    185:        snprintf(path, sizeof(path), "[%x]:", b->ccp.decomp_node_id);
                    186:        b->ccp.decomp_node_id = 0;
                    187:     }
                    188:     NgFuncShutdownNode(gCcpCsock, b->name, path);
                    189: }
                    190: 
                    191: /*
                    192:  * DeflateRecvResetReq()
                    193:  */
                    194: 
                    195: static Mbuf
                    196: DeflateRecvResetReq(Bund b, int id, Mbuf bp, int *noAck)
                    197: {
                    198:     char               path[NG_PATHSIZ];
1.1.1.2 ! misho     199: 
        !           200:     (void)bp;
        !           201:     (void)id;
        !           202:     (void)noAck;
        !           203: 
1.1       misho     204:     /* Forward ResetReq to the DEFLATE compression node */
                    205:     snprintf(path, sizeof(path), "[%x]:", b->ccp.comp_node_id);
                    206:     if (NgSendMsg(gCcpCsock, path,
                    207:            NGM_DEFLATE_COOKIE, NGM_DEFLATE_RESETREQ, NULL, 0) < 0) {
                    208:        Perror("[%s] reset-req to %s node", b->name, NG_DEFLATE_NODE_TYPE);
                    209:     }
                    210:     return(NULL);
                    211: }
                    212: 
                    213: /*
                    214:  * DeflateSendResetReq()
                    215:  */
                    216: 
                    217: static Mbuf
                    218: DeflateSendResetReq(Bund b)
                    219: {
1.1.1.2 ! misho     220:   (void)b;
1.1       misho     221:   return(NULL);
                    222: }
                    223: 
                    224: /*
                    225:  * DeflateRecvResetAck()
                    226:  */
                    227: 
                    228: static void
                    229: DeflateRecvResetAck(Bund b, int id, Mbuf bp)
                    230: {
                    231:     char               path[NG_PATHSIZ];
1.1.1.2 ! misho     232: 
        !           233:     (void)bp;
        !           234:     (void)id;
        !           235: 
1.1       misho     236:     /* Forward ResetReq to the DEFLATE compression node */
                    237:     snprintf(path, sizeof(path), "[%x]:", b->ccp.decomp_node_id);
                    238:     if (NgSendMsg(gCcpCsock, path,
                    239:            NGM_DEFLATE_COOKIE, NGM_DEFLATE_RESETREQ, NULL, 0) < 0) {
                    240:        Perror("[%s] reset-ack to %s node", b->name, NG_DEFLATE_NODE_TYPE);
                    241:     }
                    242: }
                    243: 
                    244: /*
                    245:  * DeflateBuildConfigReq()
                    246:  */
                    247: 
                    248: static u_char *
                    249: DeflateBuildConfigReq(Bund b, u_char *cp, int *ok)
                    250: {
                    251:   CcpState     const ccp = &b->ccp;
                    252:   DeflateInfo  const deflate = &ccp->deflate;
                    253:   u_int16_t    opt;
                    254:   
                    255:   if (deflate->xmit_windowBits > 0) {
                    256:     opt = ((deflate->xmit_windowBits-8)<<12) + (8<<8) + (0<<2) + 0;
                    257:   
                    258:     cp = FsmConfValue(cp, CCP_TY_DEFLATE, -2, &opt);
                    259:     *ok = 1;
                    260:   }
                    261:   return (cp);
                    262: }
                    263: 
                    264: /*
                    265:  * DeflateDecodeConfigReq()
                    266:  */
                    267: 
                    268: static void
                    269: DeflateDecodeConfigReq(Fsm fp, FsmOption opt, int mode)
                    270: {
                    271:     Bund       b = (Bund)fp->arg;
                    272:   CcpState     const ccp = &b->ccp;
                    273:   DeflateInfo  const deflate = &ccp->deflate;
                    274:   u_int16_t     o;
                    275:   u_char       window, method, chk;
                    276: 
                    277:   /* Sanity check */
                    278:   if (opt->len != 4) {
                    279:     Log(LG_CCP, ("[%s]     bogus length %d", b->name, opt->len));
                    280:     if (mode == MODE_REQ)
                    281:       FsmRej(fp, opt);
                    282:     return;
                    283:   }
                    284: 
                    285:   /* Get bits */
                    286:   memcpy(&o, opt->data, 2);
                    287:   o = ntohs(o);
                    288:   window = (o>>12)&0x000F;
                    289:   method = (o>>8)&0x000F;
                    290:   chk = o&0x0003;
                    291: 
                    292:   /* Display it */
                    293:   Log(LG_CCP, ("[%s]     0x%04x: w:%d, m:%d, c:%d", b->name, o, window, method, chk));
                    294: 
                    295:   /* Deal with it */
                    296:   switch (mode) {
                    297:     case MODE_REQ:
                    298:        if ((window > 0) && (window<=7) && (method == 8) && (chk == 0)) {
                    299:            deflate->recv_windowBits = window + 8;
                    300:            FsmAck(fp, opt);
                    301:        } else {
                    302:            o = htons((7<<12) + (8<<8) + (0<<2) + 0);
                    303:            memcpy(opt->data, &o, 2);
                    304:            FsmNak(fp, opt);
                    305:        }
                    306:       break;
                    307: 
                    308:     case MODE_NAK:
                    309:        if ((window > 0) && (window<=7) && (method == 8) && (chk == 0))
                    310:            deflate->xmit_windowBits = window + 8;
                    311:        else {
                    312:            deflate->xmit_windowBits = 0;
                    313:        }
                    314:       break;
                    315:   }
                    316: }
                    317: 
                    318: /*
                    319:  * DeflateNegotiated()
                    320:  */
                    321: 
                    322: static int
                    323: DeflateNegotiated(Bund b, int dir)
                    324: {
1.1.1.2 ! misho     325:   (void)b;
        !           326:   (void)dir;
        !           327: 
1.1       misho     328:   return 1;
                    329: }
                    330: 
                    331: /*
                    332:  * DeflateSubtractBloat()
                    333:  */
                    334: 
                    335: static int
                    336: DeflateSubtractBloat(Bund b, int size)
                    337: {
1.1.1.2 ! misho     338:   (void)b;
        !           339:   (void)size;
        !           340: 
1.1       misho     341:   return(size + CCP_OVERHEAD);  /* Compression compensate header size */
                    342: }
                    343: 
                    344: static int
                    345: DeflateStat(Context ctx, int dir) 
                    346: {
                    347:     Bund                       b = ctx->bund;
                    348:     char                       path[NG_PATHSIZ];
                    349:     struct ng_deflate_stats    stats;
                    350:     union {
                    351:        u_char                  buf[sizeof(struct ng_mesg) + sizeof(stats)];
                    352:        struct ng_mesg          reply;
                    353:     }                          u;
                    354: 
                    355:     switch (dir) {
                    356:        case COMP_DIR_XMIT:
                    357:            snprintf(path, sizeof(path), "mpd%d-%s:%s", gPid, b->name,
                    358:                NG_PPP_HOOK_COMPRESS);
                    359:            break;
                    360:        case COMP_DIR_RECV:
                    361:            snprintf(path, sizeof(path), "mpd%d-%s:%s", gPid, b->name,
                    362:                NG_PPP_HOOK_DECOMPRESS);
                    363:            break;
                    364:        default:
                    365:            assert(0);
                    366:     }
                    367:     if (NgFuncSendQuery(path, NGM_DEFLATE_COOKIE, NGM_DEFLATE_GET_STATS, NULL, 0, 
                    368:        &u.reply, sizeof(u), NULL) < 0) {
                    369:            Perror("[%s] can't get %s stats", b->name, NG_DEFLATE_NODE_TYPE);
                    370:            return(0);
                    371:     }
                    372:     memcpy(&stats, u.reply.data, sizeof(stats));
                    373:     switch (dir) {
                    374:        case COMP_DIR_XMIT:
                    375:            Printf("\tBytes\t: %llu -> %llu (%+lld%%)\r\n",
                    376:                stats.InOctets,
                    377:                stats.OutOctets,
                    378:                ((stats.InOctets!=0)?
                    379:                    ((int64_t)(stats.OutOctets - stats.InOctets)*100/(int64_t)stats.InOctets):
                    380:                    0));
                    381:            Printf("\tFrames\t: %llu -> %lluc + %lluu\r\n",
                    382:                stats.FramesPlain,
                    383:                stats.FramesComp,
                    384:                stats.FramesUncomp);
                    385:            Printf("\tErrors\t: %llu\r\n",
                    386:                stats.Errors);
                    387:            break;
                    388:        case COMP_DIR_RECV:
                    389:            Printf("\tBytes\t: %llu <- %llu (%+lld%%)\r\n",
                    390:                stats.OutOctets,
                    391:                stats.InOctets,
                    392:                ((stats.OutOctets!=0)?
                    393:                    ((int64_t)(stats.InOctets - stats.OutOctets)*100/(int64_t)stats.OutOctets):
                    394:                    0));
                    395:            Printf("\tFrames\t: %llu <- %lluc + %lluu\r\n",
                    396:                stats.FramesPlain,
                    397:                stats.FramesComp,
                    398:                stats.FramesUncomp);
                    399:            Printf("\tErrors\t: %llu\r\n",
                    400:                stats.Errors);
                    401:            break;
                    402:        default:
                    403:            assert(0);
                    404:     }
                    405:     return (0);
                    406: }
                    407: 
                    408: #endif /* CCP_DEFLATE */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>