// Package forward implements a forwarding proxy. It caches an upstream net.Conn for some time, so if the same // client returns the upstream's Conn will be precached. Depending on how you benchmark this looks to be // 50% faster than just opening a new connection for every client. It works with UDP and TCP and uses // inband healthchecking. package forward import ( "context" "crypto/tls" "errors" "time" "github.com/coredns/coredns/plugin" "github.com/coredns/coredns/plugin/debug" "github.com/coredns/coredns/request" "github.com/miekg/dns" ot "github.com/opentracing/opentracing-go" ) // Forward represents a plugin instance that can proxy requests to another (DNS) server. It has a list // of proxies each representing one upstream proxy. type Forward struct { proxies []*Proxy p Policy hcInterval time.Duration from string ignored []string tlsConfig *tls.Config tlsServerName string maxfails uint32 expire time.Duration opts options // also here for testing Next plugin.Handler } // New returns a new Forward. func New() *Forward { f := &Forward{maxfails: 2, tlsConfig: new(tls.Config), expire: defaultExpire, p: new(random), from: ".", hcInterval: hcInterval} return f } // SetProxy appends p to the proxy list and starts healthchecking. func (f *Forward) SetProxy(p *Proxy) { f.proxies = append(f.proxies, p) p.start(f.hcInterval) } // Len returns the number of configured proxies. func (f *Forward) Len() int { return len(f.proxies) } // Name implements plugin.Handler. func (f *Forward) Name() string { return "forward" } // ServeDNS implements plugin.Handler. func (f *Forward) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { state := request.Request{W: w, Req: r} if !f.match(state) { return plugin.NextOrFailure(f.Name(), f.Next, ctx, w, r) } fails := 0 var span, child ot.Span var upstreamErr error span = ot.SpanFromContext(ctx) i := 0 list := f.List() deadline := time.Now().Add(defaultTimeout) for time.Now().Before(deadline) { if i >= len(list) { // reached the end of list, reset to begin i = 0 fails = 0 } proxy := list[i] i++ if proxy.Down(f.maxfails) { fails++ if fails < len(f.proxies) { continue } // All upstream proxies are dead, assume healtcheck is completely broken and randomly // select an upstream to connect to. r := new(random) proxy = r.List(f.proxies)[0] HealthcheckBrokenCount.Add(1) } if span != nil { child = span.Tracer().StartSpan("connect", ot.ChildOf(span.Context())) ctx = ot.ContextWithSpan(ctx, child) } var ( ret *dns.Msg err error ) opts := f.opts for { ret, err = proxy.Connect(ctx, state, opts) if err == nil { break } if err == ErrCachedClosed { // Remote side closed conn, can only happen with TCP. continue } // Retry with TCP if truncated and prefer_udp configured. if err == dns.ErrTruncated && !opts.forceTCP && f.opts.preferUDP { opts.forceTCP = true continue } break } if child != nil { child.Finish() } ret, err = truncated(state, ret, err) upstreamErr = err if err != nil { // Kick off health check to see if *our* upstream is broken. if f.maxfails != 0 { proxy.Healthcheck() } if fails < len(f.proxies) { continue } break } // Check if the reply is correct; if not return FormErr. if !state.Match(ret) { debug.Hexdumpf(ret, "Wrong reply for id: %d, %s/%d", state.QName(), state.QType()) formerr := state.ErrorMessage(dns.RcodeFormatError) w.WriteMsg(formerr) return 0, nil } w.WriteMsg(ret) return 0, nil } if upstreamErr != nil { return dns.RcodeServerFailure, upstreamErr } return dns.RcodeServerFailure, ErrNoHealthy } func (f *Forward) match(state request.Request) bool { if !plugin.Name(f.from).Matches(state.Name()) || !f.isAllowedDomain(state.Name()) { return false } return true } func (f *Forward) isAllowedDomain(name string) bool { if dns.Name(name) == dns.Name(f.from) { return true } for _, ignore := range f.ignored { if plugin.Name(ignore).Matches(name) { return false } } return true } // ForceTCP returns if TCP is forced to be used even when the request comes in over UDP. func (f *Forward) ForceTCP() bool { return f.opts.forceTCP } // PreferUDP returns if UDP is preferred to be used even when the request comes in over TCP. func (f *Forward) PreferUDP() bool { return f.opts.preferUDP } // List returns a set of proxies to be used for this client depending on the policy in f. func (f *Forward) List() []*Proxy { return f.p.List(f.proxies) } var ( // ErrNoHealthy means no healthy proxies left. ErrNoHealthy = errors.New("no healthy proxies") // ErrNoForward means no forwarder defined. ErrNoForward = errors.New("no forwarder defined") // ErrCachedClosed means cached connection was closed by peer. ErrCachedClosed = errors.New("cached connection was closed by peer") ) // policy tells forward what policy for selecting upstream it uses. type policy int const ( randomPolicy policy = iota roundRobinPolicy sequentialPolicy ) // options holds various options that can be set. type options struct { forceTCP bool preferUDP bool } const defaultTimeout = 5 * time.Second -names Unnamed repository; edit this file 'description' to name the repository.
aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/builtins/cpp/ReadableStreamBYOBRequestBuiltins.h (unfollow)
AgeCommit message (Expand)AuthorFilesLines
2022-11-15Update ZigGlobalObject.cppGravatar Jarred Sumner 1-3/+1
2022-11-15Add a test with decently large headersGravatar Jarred Sumner 1-0/+61
2022-11-15Update test types a littleGravatar Jarred Sumner 1-2/+2
2022-11-15Add missing typeGravatar Jarred Sumner 1-0/+5
2022-11-14switch default encoding order (#1510)Gravatar Dylan Conway 1-1/+1
2022-11-14Fix spawn macOS issueGravatar Jarred Sumner 1-7/+11
2022-11-14Fix crash in web crypto. caused by refptrGravatar Jarred Sumner 3-2/+15
2022-11-14Fix crashiness with `process.env`Gravatar Jarred Sumner 2-27/+66
2022-11-14Fix string encoding issue in JSC C API usagesGravatar Jarred Sumner 3-139/+74
2022-11-14Prevent double-frees in log msgsGravatar Jarred Sumner 1-4/+15
2022-11-14Fix build errorGravatar Jarred SUmner 2-6/+1
2022-11-14Bugfixes and perf improvements to child_processGravatar Jarred SUmner 15-192/+416
2022-11-13use `write$NOCANCEL`, more loggingGravatar Jarred Sumner 3-12/+42
2022-11-13Add an e2e testGravatar Jarred Sumner 3-0/+52
2022-11-13Add missing `rmdir` exportGravatar Jarred Sumner 1-1/+2
2022-11-13Make node streams faster (#1502)Gravatar Jarred Sumner 23-406/+836
2022-11-13Fix incorrect exit status messageGravatar Jarred Sumner 1-3/+6
2022-11-12Fix syntax errorGravatar Jarred Sumner 1-2/+2
2022-11-12Set linker script to Bun 0.2Gravatar Jarred SUmner 1-1/+1
2022-11-12Fix infinite write loop on LinuxGravatar Jarred SUmner 3-44/+185
2022-11-12Add missing typeGravatar Jarred SUmner 1-1/+1
2022-11-12Add linker script to remove unwanted exports (#1499)Gravatar Tom Birch 2-1/+9
2022-11-12Fix memory leak in gzip pool + add test for gzip'd dataGravatar Jarred SUmner 7-62/+1530
2022-11-12Redo how we poll pipes (#1496)Gravatar Jarred Sumner 22-707/+1251
2022-11-11Add test that fails on linuxGravatar Jarred Sumner 7-21/+42
2022-11-112 framesGravatar Jarred Sumner 1-1/+1
2022-11-11Revert "Omit frame pointer"Gravatar Jarred Sumner 1-0/+1
2022-11-11Don't rm cachedGravatar Jarred Sumner 4-4/+0
2022-11-11try thisGravatar Jarred Sumner 4-0/+4
2022-11-11Update bun-linux-build.ymlGravatar Jarred Sumner 1-1/+0
2022-11-11try using git actionGravatar Jarred Sumner 4-7/+8
2022-11-11Remove with `git rm`Gravatar Jarred Sumner 2-8/+0