~ubuntu-branches/ubuntu/saucy/openvpn/saucy-proposed

« back to all changes in this revision

Viewing changes to mss.c

  • Committer: Package Import Robot
  • Author(s): Stéphane Graber
  • Date: 2013-05-24 17:42:45 UTC
  • mfrom: (1.1.19) (10.2.22 sid)
  • Revision ID: package-import@ubuntu.com-20130524174245-g9y6wlforycufqy5
Tags: 2.3.1-2ubuntu1
* Merge from Debian unstable. Remaining changes:
  - debian/openvpn.init.d:
    + Do not use start-stop-daemon and </dev/null to avoid blocking boot.
    + Show per-VPN result messages.
    + Add "--script-security 2" by default for backwards compatabliity.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  OpenVPN -- An application to securely tunnel IP networks
3
 
 *             over a single TCP/UDP port, with support for SSL/TLS-based
4
 
 *             session authentication and key exchange,
5
 
 *             packet encryption, packet authentication, and
6
 
 *             packet compression.
7
 
 *
8
 
 *  Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
9
 
 *
10
 
 *  This program is free software; you can redistribute it and/or modify
11
 
 *  it under the terms of the GNU General Public License version 2
12
 
 *  as published by the Free Software Foundation.
13
 
 *
14
 
 *  This program is distributed in the hope that it will be useful,
15
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 
 *  GNU General Public License for more details.
18
 
 *
19
 
 *  You should have received a copy of the GNU General Public License
20
 
 *  along with this program (see the file COPYING included with this
21
 
 *  distribution); if not, write to the Free Software Foundation, Inc.,
22
 
 *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
 
 */
24
 
 
25
 
#include "syshead.h"
26
 
#include "error.h"
27
 
#include "mss.h"
28
 
#include "memdbg.h"
29
 
 
30
 
/*
31
 
 * Lower MSS on TCP SYN packets to fix MTU
32
 
 * problems which arise from protocol
33
 
 * encapsulation.
34
 
 */
35
 
void
36
 
mss_fixup (struct buffer *buf, int maxmss)
37
 
{
38
 
  const struct openvpn_iphdr *pip;
39
 
  int hlen;
40
 
 
41
 
  if (BLEN (buf) < (int) sizeof (struct openvpn_iphdr))
42
 
    return;
43
 
  
44
 
  verify_align_4 (buf);
45
 
  pip = (struct openvpn_iphdr *) BPTR (buf);
46
 
 
47
 
  hlen = OPENVPN_IPH_GET_LEN (pip->version_len);
48
 
 
49
 
  if (pip->protocol == OPENVPN_IPPROTO_TCP
50
 
      && ntohs (pip->tot_len) == BLEN (buf)
51
 
      && (ntohs (pip->frag_off) & OPENVPN_IP_OFFMASK) == 0
52
 
      && hlen <= BLEN (buf)
53
 
      && BLEN (buf) - hlen
54
 
         >= (int) sizeof (struct openvpn_tcphdr))
55
 
    {
56
 
      struct buffer newbuf = *buf;
57
 
      if (buf_advance (&newbuf, hlen))
58
 
        {
59
 
          struct openvpn_tcphdr *tc = (struct openvpn_tcphdr *) BPTR (&newbuf);
60
 
          if (tc->flags & OPENVPN_TCPH_SYN_MASK)
61
 
            mss_fixup_dowork (&newbuf, (uint16_t) maxmss);
62
 
        }
63
 
    }
64
 
}
65
 
 
66
 
void
67
 
mss_fixup_dowork (struct buffer *buf, uint16_t maxmss)
68
 
{
69
 
  int hlen, olen, optlen;
70
 
  uint8_t *opt;
71
 
  uint16_t *mss;
72
 
  int accumulate;
73
 
  struct openvpn_tcphdr *tc;
74
 
 
75
 
  ASSERT (BLEN (buf) >= (int) sizeof (struct openvpn_tcphdr));
76
 
 
77
 
  verify_align_4 (buf);
78
 
  tc = (struct openvpn_tcphdr *) BPTR (buf);
79
 
  hlen = OPENVPN_TCPH_GET_DOFF (tc->doff_res);
80
 
 
81
 
  /* Invalid header length or header without options. */
82
 
  if (hlen <= (int) sizeof (struct openvpn_tcphdr)
83
 
      || hlen > BLEN (buf))
84
 
    return;
85
 
 
86
 
  for (olen = hlen - sizeof (struct openvpn_tcphdr),
87
 
         opt = (uint8_t *)(tc + 1);
88
 
       olen > 0;
89
 
       olen -= optlen, opt += optlen) {
90
 
    if (*opt == OPENVPN_TCPOPT_EOL)
91
 
      break;
92
 
    else if (*opt == OPENVPN_TCPOPT_NOP)
93
 
      optlen = 1;
94
 
    else {
95
 
      optlen = *(opt + 1);
96
 
      if (optlen <= 0 || optlen > olen)
97
 
        break;
98
 
      if (*opt == OPENVPN_TCPOPT_MAXSEG) {
99
 
        if (optlen != OPENVPN_TCPOLEN_MAXSEG)
100
 
          continue;
101
 
        mss = (uint16_t *)(opt + 2);
102
 
        if (ntohs (*mss) > maxmss) {
103
 
          dmsg (D_MSS, "MSS: %d -> %d",
104
 
               (int) ntohs (*mss),
105
 
               (int) maxmss);
106
 
          accumulate = *mss;
107
 
          *mss = htons (maxmss);
108
 
          accumulate -= *mss;
109
 
          ADJUST_CHECKSUM (accumulate, tc->check);
110
 
        }
111
 
      }
112
 
    }
113
 
  }
114
 
}