home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 2 / amigaformatcd02.iso / comms / netsoftware / cslip.lha / usr / sys / amiga / driver / slip.c-diff < prev   
Encoding:
Text File  |  1992-11-11  |  15.1 KB  |  527 lines

  1. *** cslip.c    Fri Nov  6 03:54:11 1992
  2. --- cslip.c.new    Fri Nov  6 17:07:20 1992
  3. ***************
  4. *** 10,15 ****
  5. --- 10,19 ----
  6.    * time and always left open.  To do slattach, a module is pushed
  7.    * on a tty device and an ioctl done on it to find out which slip
  8.    * interface should be started up using ifconfig(1).
  9. +  *
  10. +  * 92-11-6:
  11. +  * V1.1  Markus Wild  integrated TCP header compression and added code
  12. +  *                    to favor interactive traffic over regular traffic
  13.    */
  14.   
  15.   #include "sys/types.h"
  16. ***************
  17. *** 34,46 ****
  18. --- 38,72 ----
  19.   #include "netinet/in.h"
  20.   #include "netinet/in_var.h"
  21.   #include "netinet/ip_str.h"
  22. + #include "netinet/in_systm.h"
  23. + #include "netinet/ip.h"
  24. + #include "netinet/tcp.h"
  25.   
  26.   extern struct ifstats    *ifstats;    /* per-interface statistics for inet */
  27.   
  28. + #include "slcompress.h"
  29.   #include "slip.h"
  30.   
  31. + /* the code to deal with interactive traffic is from the cslip reference
  32. +    code, sunos/ directory (for streams) */
  33. + /*
  34. +  * The following hack gets around the problem that IP TOS
  35. +  * can't be set in BSD/Sun OS yet.  We want to put "interactive"
  36. +  * traffic on a high priority queue.  To decide if traffic is
  37. +  * interactive, we check that a) it is TCP and b) one of it's ports
  38. +  * if telnet, rlogin or ftp control.
  39. +  */
  40. + static u_short interactive_ports[8] = {
  41. +     0,    513,    0,    0,
  42. +     0,    21,    0,    23,
  43. + };
  44. + #define INTERACTIVE(p) (interactive_ports[(p) & 7] == (p))
  45.   
  46.   #define SLIP_WHICH_INTERFACE 'slwh'
  47. + #define SLIP_GET_CONF_FLAGS  'slgc'
  48. + #define SLIP_SET_CONF_FLAGS  'slsc'
  49.   
  50.   #define SLIP_DLPI_MID    'SD'        /* DLPI Module ID */
  51.   #define SLIP_TTY_MID    'ST'        /* TTY Module ID */
  52. ***************
  53. *** 47,56 ****
  54. --- 73,145 ----
  55.   
  56.   #define SLIP_MAXDEV    5        /* Maximum number of simultaneous */
  57.                       /* active SLIP interfaces. */
  58. + /* explanatory text to the BSD code. I used the suggested MTU, but am
  59. +  * for now using a much higher hi/lo-water pair (seems streams-specific) */
  60. + /*
  61. +  * SLMAX is a hard limit on input packet size.  To simplify the code
  62. +  * and improve performance, we require that packets fit in an mbuf
  63. +  * cluster, and if we get a compressed packet, there's enough extra
  64. +  * room to expand the header into a max length tcp/ip header (128
  65. +  * bytes).  So, SLMAX can be at most
  66. +  *    MCLBYTES - 128
  67. +  *
  68. +  * SLMTU is a hard limit on output packet size.  To insure good
  69. +  * interactive response, SLMTU wants to be the smallest size that
  70. +  * amortizes the header cost.  (Remember that even with
  71. +  * type-of-service queuing, we have to wait for any in-progress
  72. +  * packet to finish.  I.e., we wait, on the average, 1/2 * mtu /
  73. +  * cps, where cps is the line speed in characters per second.
  74. +  * E.g., 533ms wait for a 1024 byte MTU on a 9600 baud line.  The
  75. +  * average compressed header size is 6-8 bytes so any MTU > 90
  76. +  * bytes will give us 90% of the line bandwidth.  A 100ms wait is
  77. +  * tolerable (500ms is not), so want an MTU around 296.  (Since TCP
  78. +  * will send 256 byte segments (to allow for 40 byte headers), the
  79. +  * typical packet size on the wire will be around 260 bytes).  In
  80. +  * 4.3tahoe+ systems, we can set an MTU in a route so we do that &
  81. +  * leave the interface MTU relatively high (so we don't IP fragment
  82. +  * when acting as a gateway to someone using a stupid MTU).
  83. +  *
  84. +  * Similar considerations apply to SLIP_HIWAT:  It's the amount of
  85. +  * data that will be queued 'downstream' of us (i.e., in clists
  86. +  * waiting to be picked up by the tty output interrupt).  If we
  87. +  * queue a lot of data downstream, it's immune to our t.o.s. queuing.
  88. +  * E.g., if SLIP_HIWAT is 1024, the interactive traffic in mixed
  89. +  * telnet/ftp will see a 1 sec wait, independent of the mtu (the
  90. +  * wait is dependent on the ftp window size but that's typically
  91. +  * 1k - 4k).  So, we want SLIP_HIWAT just big enough to amortize
  92. +  * the cost (in idle time on the wire) of the tty driver running
  93. +  * off the end of its clists & having to call back slstart for a
  94. +  * new packet.  For a tty interface with any buffering at all, this
  95. +  * cost will be zero.  Even with a totally brain dead interface (like
  96. +  * the one on a typical workstation), the cost will be <= 1 character
  97. +  * time.  So, setting SLIP_HIWAT to ~100 guarantees that we'll lose
  98. +  * at most 1% while maintaining good interactive response.
  99. +  */
  100. + #if 0 /* BSD implementation constants described in above text */
  101. + #define BUFOFFSET    128
  102. + #define    SLMAX        (MCLBYTES - BUFOFFSET)
  103. + #define    SLBUFSIZE    (SLMAX + BUFOFFSET)
  104. + #define    SLMTU        296
  105. + #define    SLIP_HIWAT    roundup(50,CBSIZE)
  106. + #define    CLISTRESERVE    1024    /* Can't let clists get too low */
  107. + #else
  108. + #ifdef COMMODORE_PARAMETERS
  109.   #define    SLIP_MIN    1
  110.   #define SLIP_MAX    1006        /* Is this some sort of standard? */
  111. + #define SLIP_MTU    SLIP_MAX
  112.   #define SLIP_HIWAT    2048
  113.   #define SLIP_LOWAT    (2*SLIP_HIWAT/3)
  114. + #else
  115. + #define    SLIP_MIN    1
  116. + #define SLIP_MAX    1006        /* Is this some sort of standard? */
  117. + #define SLIP_MTU    296
  118. + #define SLIP_HIWAT    100
  119. + #define SLIP_LOWAT    (2*SLIP_HIWAT/3)
  120. + #endif
  121. + #define BUFOFFSET    128        /* room for decompressed header */
  122. + #endif
  123.   
  124.   struct slipdev
  125.   {
  126. ***************
  127. *** 62,69 ****
  128. --- 151,167 ----
  129.       char ifname[20];
  130.       mblk_t *curblk;            /* Input packet being assembled */
  131.       int escaped;            /* Last character was ESCAPE */
  132. +     u_int sc_flags;            /* see below */
  133. +     struct slcompress sc_comp;        /* tcp compression data */
  134. +     mblk_t *lastpriopkt;        /* last priority interactive message */
  135.   };
  136.   
  137. + /* visible flags */
  138. + #define    SC_COMPRESS    0x0002        /* compress TCP traffic */
  139. + #define    SC_NOICMP    0x0004        /* supress ICMP traffic */
  140. + #define    SC_AUTOCOMP    0x0008        /* auto-enable TCP compression */
  141.   
  142.   /*
  143.    *  DLPI stream data structure definitions
  144. ***************
  145. *** 75,81 ****
  146. --- 173,184 ----
  147.   
  148.   static struct module_info dlpi_minfo =
  149.   {
  150. + #ifdef COMMODORE_PARAMETERS
  151.       SLIP_DLPI_MID, "sld", SLIP_MIN, SLIP_MAX, SLIP_HIWAT, SLIP_LOWAT,
  152. + #else
  153. +     /* these parameters are from the SunOS streams code, who is right?? */
  154. +     SLIP_DLPI_MID, "sld", 0, INFPSZ, 16384, 4096,
  155. + #endif
  156.   };
  157.   
  158.   static struct qinit dlpirinit =
  159. ***************
  160. *** 101,107 ****
  161. --- 204,214 ----
  162.   
  163.   static struct module_info tty_minfo =
  164.   {
  165. + #ifdef COMMODORE_PARAMETERS
  166.       SLIP_TTY_MID, "slipmod", SLIP_MIN, SLIP_MAX, SLIP_HIWAT, SLIP_LOWAT,
  167. + #else
  168. +     SLIP_TTY_MID, "slipmod", 0, INFPSZ, 16384, 4096,
  169. + #endif
  170.   };
  171.   
  172.   static struct qinit ttyrinit =
  173. ***************
  174. *** 164,170 ****
  175.       }
  176.   
  177.       slip->stats.ifs_active = 1;
  178. !     slip->stats.ifs_mtu = SLIP_MAX;
  179.       slip->stats.ifs_ipackets =
  180.           slip->stats.ifs_ierrors =
  181.           slip->stats.ifs_opackets =
  182. --- 271,277 ----
  183.       }
  184.   
  185.       slip->stats.ifs_active = 1;
  186. !     slip->stats.ifs_mtu = SLIP_MTU;
  187.       slip->stats.ifs_ipackets =
  188.           slip->stats.ifs_ierrors =
  189.           slip->stats.ifs_opackets =
  190. ***************
  191. *** 172,177 ****
  192. --- 279,289 ----
  193.   
  194.       WR(rq)->q_ptr = rq->q_ptr = (caddr_t)slip;
  195.       slip->dlpiq = rq;
  196. +     /* seems like a reasonable default to me */
  197. +     slip->sc_flags = SC_AUTOCOMP;
  198. +     sl_compress_init (& slip->sc_comp);
  199. +     slip->lastpriopkt = 0;
  200.       }
  201.   
  202.       return 0;
  203. ***************
  204. *** 448,454 ****
  205.   register struct slipdev *slip;
  206.   mblk_t *dlpimp;
  207.   {
  208. !     mblk_t *bp, *outmp;
  209.   
  210.       if (!canput(WR(slip->ttyq)))
  211.       return 0;
  212. --- 560,568 ----
  213.   register struct slipdev *slip;
  214.   mblk_t *dlpimp;
  215.   {
  216. !     mblk_t *bp, *outmp, *tmpmp=0;
  217. !     struct ip *ip;
  218. !     int s, p, hiprio;
  219.   
  220.       if (!canput(WR(slip->ttyq)))
  221.       return 0;
  222. ***************
  223. *** 461,469 ****
  224.       }
  225.       outmp->b_datap->db_type = M_DATA;
  226.   
  227.   #define putc(ch) (*outmp->b_wptr++ = (ch))
  228.       /* Copy input to output, escaping special characters */
  229. !     for ( bp=dlpimp->b_cont ; bp ; bp=bp->b_cont )
  230.       while (bp->b_wptr > bp->b_rptr)
  231.       {
  232.           unsigned char c = *bp->b_rptr++;
  233. --- 575,624 ----
  234.       }
  235.       outmp->b_datap->db_type = M_DATA;
  236.   
  237. +     ip = (struct ip *)(dlpimp->b_cont->b_rptr);
  238. +     hiprio = 0;
  239. +     if (ip->ip_p == IPPROTO_TCP)
  240. +       {
  241. +     if (slip->sc_flags & SC_COMPRESS)
  242. +       {
  243. +         /* copy over the chain of mblk_t into one buffer. This is to
  244. +            make sure the compression code can assume the whole mess
  245. +            is one packet. It probably would do to just convert the
  246. +            first buffer, but since I don't have any documentation to
  247. +            mblk_t internals.. */
  248. +         if (!(tmpmp = allocb (SLIP_MAX, BPRI_MED)))
  249. +           {
  250. +         ++slip->stats.ifs_oerrors;
  251. +         freemsg (outmp);
  252. +         return 0;
  253. +           }
  254. +         for (bp = dlpimp->b_cont; bp; bp = bp->b_cont)
  255. +           while (bp->b_wptr > bp->b_rptr)
  256. +         *tmpmp->b_wptr++ = *bp->b_rptr++;
  257. +         /* ok, compress the sucker */
  258. +         ip = (struct ip *) tmpmp->b_rptr;
  259. +         p = ((int *)ip)[ip->ip_hl];
  260. +         hiprio = INTERACTIVE(p & 0xffff) || INTERACTIVE(p >> 16);
  261. +         p = sl_compress_tcp (tmpmp, ip, &slip->sc_comp, hiprio);
  262. +         *(u_char *) tmpmp->b_rptr |= p; /* what the ... */
  263. +         bp = tmpmp;
  264. +       }
  265. +     else if ((slip->sc_flags & SC_NOICMP) && ip->ip_p == IPPROTO_ICMP)
  266. +       {
  267. +         freemsg (tmpmp);
  268. +         freemsg (outmp);
  269. +         return 0;
  270. +       }
  271. +     else
  272. +       bp = dlpimp->b_cont;
  273. +       }
  274. +     else
  275. +       bp = dlpimp->b_cont;
  276.   #define putc(ch) (*outmp->b_wptr++ = (ch))
  277.       /* Copy input to output, escaping special characters */
  278. !     for ( ; bp ; bp=bp->b_cont )
  279.       while (bp->b_wptr > bp->b_rptr)
  280.       {
  281.           unsigned char c = *bp->b_rptr++;
  282. ***************
  283. *** 489,497 ****
  284.   #undef putc
  285.   
  286.       ++slip->stats.ifs_opackets;
  287.       putnext(WR(slip->ttyq), outmp);
  288. !     freemsg(dlpimp);
  289.   
  290.       return 1;
  291.   }
  292.   
  293. --- 644,694 ----
  294.   #undef putc
  295.   
  296.       ++slip->stats.ifs_opackets;
  297. + #if 1
  298. +     /* then queue it for later transmission through the port */
  299. +     s = splstr();
  300. +     if (WR(slip->ttyq)) 
  301. +       {    /* inside splstr() in case WR(slip->ttyq) = 0 */
  302. +     if (hiprio) 
  303. +       {    /* macchiavelli mode */
  304. +         register mblk_t    *tp = WR(slip->ttyq)->q_next->q_first;
  305. +         /*
  306. +          * We want this packet to come before other
  307. +          * IP packets but after other TELNET/LOGINSERVER
  308. +          * packets, ignoring real priority messages.
  309. +          */
  310. +         for (; tp != NULL; tp = tp->b_next)
  311. +           if (tp == slip->lastpriopkt)
  312. +         break;
  313. +         if (tp == NULL)
  314. +           tp = WR(slip->ttyq)->q_next->q_first;
  315. +         if (tp == NULL)
  316. +           /* since insq doesn't schedule the q! */
  317. +           putnext(WR(slip->ttyq), outmp);
  318. +         else
  319. +           insq(WR(slip->ttyq)->q_next, tp, outmp);
  320. +         slip->lastpriopkt = outmp;
  321. +       } 
  322. +     else
  323. +       putnext(WR(slip->ttyq), outmp);
  324. +       } 
  325. +     else
  326. +       {
  327. +     freemsg(outmp);
  328. +     outmp = 0;
  329. +       }
  330. +     (void) splx(s);
  331. + #else
  332.       putnext(WR(slip->ttyq), outmp);
  333. ! #endif
  334. !     if (tmpmp)
  335. !       freemsg (tmpmp);
  336.   
  337. +     if (outmp)
  338. +       freemsg(dlpimp);
  339. +     else
  340. +       return 0;
  341.       return 1;
  342.   }
  343.   
  344. ***************
  345. *** 634,639 ****
  346. --- 831,837 ----
  347.   {
  348.       register struct slipdev *slip = (struct slipdev *)q->q_ptr;
  349.       struct iocblk *iocbp = (struct iocblk *)mp->b_rptr;
  350. +     int s;
  351.   
  352.       switch (iocbp->ioc_cmd)
  353.       {
  354. ***************
  355. *** 640,645 ****
  356. --- 838,868 ----
  357.       case SLIP_WHICH_INTERFACE:
  358.       RETURN(M_IOCACK, slip-sliptab, 0);
  359.   
  360. +     case SLIP_GET_CONF_FLAGS:
  361. +     RETURN(M_IOCACK, slip->sc_flags, 0);
  362. +     case SLIP_SET_CONF_FLAGS:
  363. +     if (iocbp->ioc_count == TRANSPARENT)
  364. +       {
  365. +         slip->sc_flags = (*(long *)mp->b_cont->b_rptr) & 0xffff;
  366. + /*        printf("sl: setting flags 0x%x\n", slip->sc_flags);*/
  367. +         freemsg (mp->b_cont);
  368. +         mp->b_cont = 0;
  369. +         RETURN(M_IOCACK, 0, 0);
  370. +       }
  371. +     else
  372. +       {
  373. +         /* fail if I_STR (from streams guide) */
  374. +         if (mp->b_cont)
  375. +           {
  376. +         freemsg (mp->b_cont);
  377. +         mp->b_cont = 0;
  378. +           }
  379. +         mp->b_datap->db_type = M_IOCNAK;
  380. +         qreply (q, mp);
  381. +         break;
  382. +       }
  383.       default:
  384.       RETURN(M_IOCNAK, 0, EINVAL);
  385.       }
  386. ***************
  387. *** 681,702 ****
  388.               {
  389.               mblk_t *dlpimp;
  390.               register dl_unitdata_ind_t *udp;
  391.               dlpimp = allocb(sizeof *udp, BPRI_MED);
  392.               if (dlpimp)
  393. !             {
  394. !                 udp = (dl_unitdata_ind_t *)dlpimp->b_wptr;
  395. !                 udp->dl_primitive = DL_UNITDATA_IND;
  396. !                 udp->dl_dest_addr_length = 0;
  397. !                 udp->dl_dest_addr_offset = sizeof *udp;
  398. !                 udp->dl_src_addr_length = 0;
  399. !                 udp->dl_src_addr_offset = sizeof *udp;
  400. !                 udp->dl_reserved = 0;
  401. !                 dlpimp->b_wptr += sizeof *udp;
  402. !                 dlpimp->b_datap->db_type = M_PROTO;
  403. !                 dlpimp->b_cont = outmp;
  404. !                 ++slip->stats.ifs_ipackets;
  405. !                 putnext(slip->dlpiq, dlpimp);
  406.               }
  407.               else
  408.                   freemsg(outmp);
  409. --- 904,965 ----
  410.               {
  411.               mblk_t *dlpimp;
  412.               register dl_unitdata_ind_t *udp;
  413. +             int c;
  414.               dlpimp = allocb(sizeof *udp, BPRI_MED);
  415.               if (dlpimp)
  416. !               {
  417. !                 int ok = 1;
  418. !                 
  419. !                 if ((c = (*outmp->b_rptr & 0xf0)) != 
  420. !                 (IPVERSION << 4)) 
  421. !                   {
  422. !                 if (c & 0x80)
  423. !                   c = TYPE_COMPRESSED_TCP;
  424. !                 else if (c == TYPE_UNCOMPRESSED_TCP)
  425. !                   *outmp->b_rptr &= 0x4f; /* XXX */
  426. !                 /*
  427. !                  * We've got something that's not an IP packet.
  428. !                  * If compression is enabled, try to decompress it.
  429. !                  * Otherwise, if `auto-enable' compression is on and
  430. !                  * it's a reasonable packet, decompress it and then
  431. !                  * enable compression.  Otherwise, drop it.
  432. !                  */
  433. !                 if (slip->sc_flags & SC_COMPRESS) 
  434. !                   ok = sl_uncompress_tcp (outmp, (u_int)c, 
  435. !                               &slip->sc_comp);
  436. !                 else if ((slip->sc_flags & SC_AUTOCOMP) &&
  437. !                      c == TYPE_UNCOMPRESSED_TCP && 
  438. !                      outmp->b_wptr - outmp->b_rptr >= 40) 
  439. !                   {
  440. !                     ok = sl_uncompress_tcp (outmp, (u_int)c, 
  441. !                                 &slip->sc_comp);
  442. !                     if (ok > 0)
  443. !                       slip->sc_flags |= SC_COMPRESS;
  444. !                   } 
  445. !                   }
  446. !                 
  447. !                 if (ok <= 0)
  448. !                   {
  449. !                 freemsg (outmp);
  450. !                 freemsg (dlpimp);
  451. !                   }
  452. !                 else
  453. !                   {
  454. !                 udp = (dl_unitdata_ind_t *)dlpimp->b_wptr;
  455. !                 udp->dl_primitive = DL_UNITDATA_IND;
  456. !                 udp->dl_dest_addr_length = 0;
  457. !                 udp->dl_dest_addr_offset = sizeof *udp;
  458. !                 udp->dl_src_addr_length = 0;
  459. !                 udp->dl_src_addr_offset = sizeof *udp;
  460. !                 udp->dl_reserved = 0;
  461. !                 
  462. !                 dlpimp->b_wptr += sizeof *udp;
  463. !                 dlpimp->b_datap->db_type = M_PROTO;
  464. !                 dlpimp->b_cont = outmp;
  465. !                 ++slip->stats.ifs_ipackets;
  466. !                 putnext(slip->dlpiq, dlpimp);
  467. !                   }
  468.               }
  469.               else
  470.                   freemsg(outmp);
  471. ***************
  472. *** 727,734 ****
  473.   
  474.               /* if packet is too large, drop it and start over */
  475.               if (!outmp)
  476. !             if (outmp=allocb(SLIP_MAX, BPRI_MED))
  477.                   slip->curblk = outmp;
  478.               else
  479.               {
  480.                   ++slip->stats.ifs_ierrors;
  481. --- 990,1003 ----
  482.   
  483.               /* if packet is too large, drop it and start over */
  484.               if (!outmp)
  485. !             if (outmp=allocb(SLIP_MAX+BUFOFFSET, BPRI_MED))
  486. !               {
  487.                   slip->curblk = outmp;
  488. +                 /* make a hole to possibly insert a decompressed
  489. +                    header */
  490. +                 outmp->b_wptr = outmp->b_rptr = 
  491. +                   outmp->b_datap->db_base + BUFOFFSET;
  492. +               }
  493.               else
  494.               {
  495.                   ++slip->stats.ifs_ierrors;
  496. ***************
  497. *** 739,745 ****
  498.               {
  499.                   ++slip->stats.ifs_ierrors;
  500.                   outmp->b_wptr = outmp->b_rptr =
  501. !                 outmp->b_datap->db_base;
  502.               }
  503.   
  504.               *outmp->b_wptr++ = c;
  505. --- 1008,1014 ----
  506.               {
  507.                   ++slip->stats.ifs_ierrors;
  508.                   outmp->b_wptr = outmp->b_rptr =
  509. !                 outmp->b_datap->db_base + BUFOFFSET;
  510.               }
  511.   
  512.               *outmp->b_wptr++ = c;
  513.