Commit 3b5be452 authored by Mikio Hara's avatar Mikio Hara

net: more accurate parsing of IPv4 header on IPConn

As shown in #9395, inaccurate implementation would be a cause of parsing
IPv4 header twice and corrupted upper-layer message issues.

Change-Id: Ia1a042e7ca58ee4fcb38fe9ec753c2ab100592ca
Reviewed-on: https://go-review.googlesource.com/3001Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent fd4dc91a
...@@ -83,17 +83,28 @@ func (c *IPConn) ReadFromIP(b []byte) (int, *IPAddr, error) { ...@@ -83,17 +83,28 @@ func (c *IPConn) ReadFromIP(b []byte) (int, *IPAddr, error) {
switch sa := sa.(type) { switch sa := sa.(type) {
case *syscall.SockaddrInet4: case *syscall.SockaddrInet4:
addr = &IPAddr{IP: sa.Addr[0:]} addr = &IPAddr{IP: sa.Addr[0:]}
if len(b) >= IPv4len { // discard ipv4 header n = stripIPv4Header(n, b)
hsize := (int(b[0]) & 0xf) * 4
copy(b, b[hsize:])
n -= hsize
}
case *syscall.SockaddrInet6: case *syscall.SockaddrInet6:
addr = &IPAddr{IP: sa.Addr[0:], Zone: zoneToString(int(sa.ZoneId))} addr = &IPAddr{IP: sa.Addr[0:], Zone: zoneToString(int(sa.ZoneId))}
} }
return n, addr, err return n, addr, err
} }
func stripIPv4Header(n int, b []byte) int {
if len(b) < 20 {
return n
}
l := int(b[0]&0x0f) << 2
if 20 > l || l > len(b) {
return n
}
if b[0]>>4 != 4 {
return n
}
copy(b, b[l:])
return n - l
}
// ReadFrom implements the PacketConn ReadFrom method. // ReadFrom implements the PacketConn ReadFrom method.
func (c *IPConn) ReadFrom(b []byte) (int, Addr, error) { func (c *IPConn) ReadFrom(b []byte) (int, Addr, error) {
if !c.ok() { if !c.ok() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment