aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/net
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2019-04-09 16:43:22 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2019-04-09 16:43:22 +0000
commit9bafe5a81e42406b86a65ef14b011ed9acc96c5d (patch)
tree35478f4f4ff092374f748479debcda06b96dd6dd /libgo/go/net
parent10f47d3d1dc2e1267a32fa6459655b4645a9adad (diff)
parent3fa176b767e14e1d2491775978afac3e87892d1d (diff)
downloadgcc-9bafe5a81e42406b86a65ef14b011ed9acc96c5d.zip
gcc-9bafe5a81e42406b86a65ef14b011ed9acc96c5d.tar.gz
gcc-9bafe5a81e42406b86a65ef14b011ed9acc96c5d.tar.bz2
Merge from trunk revision 270220.
From-SVN: r270233
Diffstat (limited to 'libgo/go/net')
-rw-r--r--libgo/go/net/http/httputil/reverseproxy.go5
-rw-r--r--libgo/go/net/http/httputil/reverseproxy_test.go42
-rw-r--r--libgo/go/net/interface_aix.go8
-rw-r--r--libgo/go/net/interface_stub.go2
-rw-r--r--libgo/go/net/lookup.go5
-rw-r--r--libgo/go/net/lookup_test.go89
-rw-r--r--libgo/go/net/sockoptip_aix.go15
7 files changed, 131 insertions, 35 deletions
diff --git a/libgo/go/net/http/httputil/reverseproxy.go b/libgo/go/net/http/httputil/reverseproxy.go
index 4e10bf3..4b165d6 100644
--- a/libgo/go/net/http/httputil/reverseproxy.go
+++ b/libgo/go/net/http/httputil/reverseproxy.go
@@ -389,6 +389,11 @@ func (p *ReverseProxy) copyResponse(dst io.Writer, src io.Reader, flushInterval
latency: flushInterval,
}
defer mlw.stop()
+
+ // set up initial timer so headers get flushed even if body writes are delayed
+ mlw.flushPending = true
+ mlw.t = time.AfterFunc(flushInterval, mlw.delayedFlush)
+
dst = mlw
}
}
diff --git a/libgo/go/net/http/httputil/reverseproxy_test.go b/libgo/go/net/http/httputil/reverseproxy_test.go
index 5edefa0..367ba73 100644
--- a/libgo/go/net/http/httputil/reverseproxy_test.go
+++ b/libgo/go/net/http/httputil/reverseproxy_test.go
@@ -9,6 +9,7 @@ package httputil
import (
"bufio"
"bytes"
+ "context"
"errors"
"fmt"
"io"
@@ -317,6 +318,47 @@ func TestReverseProxyFlushInterval(t *testing.T) {
}
}
+func TestReverseProxyFlushIntervalHeaders(t *testing.T) {
+ const expected = "hi"
+ stopCh := make(chan struct{})
+ backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ w.Header().Add("MyHeader", expected)
+ w.WriteHeader(200)
+ w.(http.Flusher).Flush()
+ <-stopCh
+ }))
+ defer backend.Close()
+ defer close(stopCh)
+
+ backendURL, err := url.Parse(backend.URL)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ proxyHandler := NewSingleHostReverseProxy(backendURL)
+ proxyHandler.FlushInterval = time.Microsecond
+
+ frontend := httptest.NewServer(proxyHandler)
+ defer frontend.Close()
+
+ req, _ := http.NewRequest("GET", frontend.URL, nil)
+ req.Close = true
+
+ ctx, cancel := context.WithTimeout(req.Context(), 10*time.Second)
+ defer cancel()
+ req = req.WithContext(ctx)
+
+ res, err := frontend.Client().Do(req)
+ if err != nil {
+ t.Fatalf("Get: %v", err)
+ }
+ defer res.Body.Close()
+
+ if res.Header.Get("MyHeader") != expected {
+ t.Errorf("got header %q; expected %q", res.Header.Get("MyHeader"), expected)
+ }
+}
+
func TestReverseProxyCancelation(t *testing.T) {
const backendResponse = "I am the backend"
diff --git a/libgo/go/net/interface_aix.go b/libgo/go/net/interface_aix.go
index 9a8b5bb..1fe9bba 100644
--- a/libgo/go/net/interface_aix.go
+++ b/libgo/go/net/interface_aix.go
@@ -32,6 +32,8 @@ const _RTAX_NETMASK = 2
const _RTAX_IFA = 5
const _RTAX_MAX = 8
+const _SIOCGIFMTU = -0x3fd796aa
+
func getIfList() ([]byte, error) {
needed, err := syscall.Getkerninfo(_KINFO_RT_IFLIST, 0, 0, 0)
if err != nil {
@@ -62,7 +64,7 @@ func interfaceTable(ifindex int) ([]Interface, error) {
}
if ifm.Type == syscall.RTM_IFINFO {
if ifindex == 0 || ifindex == int(ifm.Index) {
- sdl := (*rawSockaddrDatalink)(unsafe.Pointer(&tab[syscall.SizeofIfMsghdr]))
+ sdl := (*rawSockaddrDatalink)(unsafe.Pointer(&tab[unsafe.Sizeof(syscall.IfMsgHdr)]))
ifi := &Interface{Index: int(ifm.Index), Flags: linkFlags(ifm.Flags)}
ifi.Name = string(sdl.Data[:sdl.Nlen])
@@ -75,7 +77,7 @@ func interfaceTable(ifindex int) ([]Interface, error) {
if err != nil {
return nil, err
}
- err = unix.Ioctl(sock, syscall.SIOCGIFMTU, uintptr(unsafe.Pointer(ifr)))
+ err = unix.Ioctl(sock, _SIOCGIFMTU, uintptr(unsafe.Pointer(ifr)))
if err != nil {
return nil, err
}
@@ -131,7 +133,7 @@ func interfaceAddrTable(ifi *Interface) ([]Addr, error) {
if ifm.Type == syscall.RTM_NEWADDR {
if ifi == nil || ifi.Index == int(ifm.Index) {
mask := ifm.Addrs
- off := uint(syscall.SizeofIfMsghdr)
+ off := uint(unsafe.Sizeof(syscall.IfMsgHdr))
var iprsa, nmrsa *syscall.RawSockaddr
for i := uint(0); i < _RTAX_MAX; i++ {
diff --git a/libgo/go/net/interface_stub.go b/libgo/go/net/interface_stub.go
index 0b3580e..d8afd5e 100644
--- a/libgo/go/net/interface_stub.go
+++ b/libgo/go/net/interface_stub.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix nacl hurd js,wasm
+// +build nacl hurd js,wasm
package net
diff --git a/libgo/go/net/lookup.go b/libgo/go/net/lookup.go
index e108893..08e8d01 100644
--- a/libgo/go/net/lookup.go
+++ b/libgo/go/net/lookup.go
@@ -262,8 +262,9 @@ func (r *Resolver) lookupIPAddr(ctx context.Context, network, host string) ([]IP
// only the values in context. See Issue 28600.
lookupGroupCtx, lookupGroupCancel := context.WithCancel(withUnexpiredValuesPreserved(ctx))
+ lookupKey := network + "\000" + host
dnsWaitGroup.Add(1)
- ch, called := r.getLookupGroup().DoChan(host, func() (interface{}, error) {
+ ch, called := r.getLookupGroup().DoChan(lookupKey, func() (interface{}, error) {
defer dnsWaitGroup.Done()
return testHookLookupIP(lookupGroupCtx, resolverFunc, network, host)
})
@@ -280,7 +281,7 @@ func (r *Resolver) lookupIPAddr(ctx context.Context, network, host string) ([]IP
// let the lookup continue uncanceled, and let later
// lookups with the same key share the result.
// See issues 8602, 20703, 22724.
- if r.getLookupGroup().ForgetUnshared(host) {
+ if r.getLookupGroup().ForgetUnshared(lookupKey) {
lookupGroupCancel()
} else {
go func() {
diff --git a/libgo/go/net/lookup_test.go b/libgo/go/net/lookup_test.go
index 85bcb2b..28a895e 100644
--- a/libgo/go/net/lookup_test.go
+++ b/libgo/go/net/lookup_test.go
@@ -16,6 +16,7 @@ import (
"sort"
"strings"
"sync"
+ "sync/atomic"
"testing"
"time"
)
@@ -253,14 +254,11 @@ func TestLookupGmailTXT(t *testing.T) {
}
}
-var lookupGooglePublicDNSAddrTests = []struct {
- addr, name string
-}{
- {"8.8.8.8", ".google.com."},
- {"8.8.4.4", ".google.com."},
-
- {"2001:4860:4860::8888", ".google.com."},
- {"2001:4860:4860::8844", ".google.com."},
+var lookupGooglePublicDNSAddrTests = []string{
+ "8.8.8.8",
+ "8.8.4.4",
+ "2001:4860:4860::8888",
+ "2001:4860:4860::8844",
}
func TestLookupGooglePublicDNSAddr(t *testing.T) {
@@ -272,8 +270,8 @@ func TestLookupGooglePublicDNSAddr(t *testing.T) {
defer dnsWaitGroup.Wait()
- for _, tt := range lookupGooglePublicDNSAddrTests {
- names, err := LookupAddr(tt.addr)
+ for _, ip := range lookupGooglePublicDNSAddrTests {
+ names, err := LookupAddr(ip)
if err != nil {
t.Fatal(err)
}
@@ -281,8 +279,8 @@ func TestLookupGooglePublicDNSAddr(t *testing.T) {
t.Error("got no record")
}
for _, name := range names {
- if !strings.HasSuffix(name, tt.name) {
- t.Errorf("got %s; want a record containing %s", name, tt.name)
+ if !strings.HasSuffix(name, ".google.com.") && !strings.HasSuffix(name, ".google.") {
+ t.Errorf("got %q; want a record ending in .google.com. or .google.", name)
}
}
}
@@ -658,8 +656,8 @@ func testDots(t *testing.T, mode string) {
t.Errorf("LookupAddr(8.8.8.8): %v (mode=%v)", err, mode)
} else {
for _, name := range names {
- if !strings.HasSuffix(name, ".google.com.") {
- t.Errorf("LookupAddr(8.8.8.8) = %v, want names ending in .google.com. with trailing dot (mode=%v)", names, mode)
+ if !strings.HasSuffix(name, ".google.com.") && !strings.HasSuffix(name, ".google.") {
+ t.Errorf("LookupAddr(8.8.8.8) = %v, want names ending in .google.com or .google with trailing dot (mode=%v)", names, mode)
break
}
}
@@ -1096,6 +1094,69 @@ func TestLookupIPAddrPreservesContextValues(t *testing.T) {
}
}
+// Issue 30521: The lookup group should call the resolver for each network.
+func TestLookupIPAddrConcurrentCallsForNetworks(t *testing.T) {
+ origTestHookLookupIP := testHookLookupIP
+ defer func() { testHookLookupIP = origTestHookLookupIP }()
+
+ queries := [][]string{
+ {"udp", "golang.org"},
+ {"udp4", "golang.org"},
+ {"udp6", "golang.org"},
+ {"udp", "golang.org"},
+ {"udp", "golang.org"},
+ }
+ results := map[[2]string][]IPAddr{
+ {"udp", "golang.org"}: {
+ {IP: IPv4(127, 0, 0, 1)},
+ {IP: IPv6loopback},
+ },
+ {"udp4", "golang.org"}: {
+ {IP: IPv4(127, 0, 0, 1)},
+ },
+ {"udp6", "golang.org"}: {
+ {IP: IPv6loopback},
+ },
+ }
+ calls := int32(0)
+ waitCh := make(chan struct{})
+ testHookLookupIP = func(ctx context.Context, fn func(context.Context, string, string) ([]IPAddr, error), network, host string) ([]IPAddr, error) {
+ // We'll block until this is called one time for each different
+ // expected result. This will ensure that the lookup group would wait
+ // for the existing call if it was to be reused.
+ if atomic.AddInt32(&calls, 1) == int32(len(results)) {
+ close(waitCh)
+ }
+ select {
+ case <-waitCh:
+ case <-ctx.Done():
+ return nil, ctx.Err()
+ }
+ return results[[2]string{network, host}], nil
+ }
+
+ ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ wg := sync.WaitGroup{}
+ for _, q := range queries {
+ network := q[0]
+ host := q[1]
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ gotIPs, err := DefaultResolver.lookupIPAddr(ctx, network, host)
+ if err != nil {
+ t.Errorf("lookupIPAddr(%v, %v): unexpected error: %v", network, host, err)
+ }
+ wantIPs := results[[2]string{network, host}]
+ if !reflect.DeepEqual(gotIPs, wantIPs) {
+ t.Errorf("lookupIPAddr(%v, %v): mismatched IPAddr results\n\tGot: %v\n\tWant: %v", network, host, gotIPs, wantIPs)
+ }
+ }()
+ }
+ wg.Wait()
+}
+
func TestWithUnexpiredValuesPreserved(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
diff --git a/libgo/go/net/sockoptip_aix.go b/libgo/go/net/sockoptip_aix.go
deleted file mode 100644
index 1e28fe6..0000000
--- a/libgo/go/net/sockoptip_aix.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package net
-
-import "syscall"
-
-func setIPv4MulticastInterface(fd *netFD, ifi *Interface) error {
- return syscall.ENOPROTOOPT
-}
-
-func setIPv4MulticastLoopback(fd *netFD, v bool) error {
- return syscall.ENOPROTOOPT
-}