Browse Source
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.0.0-20180921000356-2f5d2388922f to 0.7.0. - [Release notes](https://github.com/golang/net/releases) - [Commits](https://github.com/golang/net/commits/v0.7.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com>dependabot/go_modules/golang.org/x/net-0.7.0
dependabot[bot]
1 year ago
committed by
GitHub
432 changed files with 167421 additions and 114712 deletions
@ -0,0 +1,438 @@ |
|||
// Copyright 2019 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 acme |
|||
|
|||
import ( |
|||
"context" |
|||
"crypto" |
|||
"encoding/base64" |
|||
"encoding/json" |
|||
"encoding/pem" |
|||
"errors" |
|||
"fmt" |
|||
"io" |
|||
"io/ioutil" |
|||
"net/http" |
|||
"time" |
|||
) |
|||
|
|||
// DeactivateReg permanently disables an existing account associated with c.Key.
|
|||
// A deactivated account can no longer request certificate issuance or access
|
|||
// resources related to the account, such as orders or authorizations.
|
|||
//
|
|||
// It only works with CAs implementing RFC 8555.
|
|||
func (c *Client) DeactivateReg(ctx context.Context) error { |
|||
url := string(c.accountKID(ctx)) |
|||
if url == "" { |
|||
return ErrNoAccount |
|||
} |
|||
req := json.RawMessage(`{"status": "deactivated"}`) |
|||
res, err := c.post(ctx, nil, url, req, wantStatus(http.StatusOK)) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
res.Body.Close() |
|||
return nil |
|||
} |
|||
|
|||
// registerRFC is equivalent to c.Register but for CAs implementing RFC 8555.
|
|||
// It expects c.Discover to have already been called.
|
|||
func (c *Client) registerRFC(ctx context.Context, acct *Account, prompt func(tosURL string) bool) (*Account, error) { |
|||
c.cacheMu.Lock() // guard c.kid access
|
|||
defer c.cacheMu.Unlock() |
|||
|
|||
req := struct { |
|||
TermsAgreed bool `json:"termsOfServiceAgreed,omitempty"` |
|||
Contact []string `json:"contact,omitempty"` |
|||
ExternalAccountBinding *jsonWebSignature `json:"externalAccountBinding,omitempty"` |
|||
}{ |
|||
Contact: acct.Contact, |
|||
} |
|||
if c.dir.Terms != "" { |
|||
req.TermsAgreed = prompt(c.dir.Terms) |
|||
} |
|||
|
|||
// set 'externalAccountBinding' field if requested
|
|||
if acct.ExternalAccountBinding != nil { |
|||
eabJWS, err := c.encodeExternalAccountBinding(acct.ExternalAccountBinding) |
|||
if err != nil { |
|||
return nil, fmt.Errorf("acme: failed to encode external account binding: %v", err) |
|||
} |
|||
req.ExternalAccountBinding = eabJWS |
|||
} |
|||
|
|||
res, err := c.post(ctx, c.Key, c.dir.RegURL, req, wantStatus( |
|||
http.StatusOK, // account with this key already registered
|
|||
http.StatusCreated, // new account created
|
|||
)) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
defer res.Body.Close() |
|||
a, err := responseAccount(res) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
// Cache Account URL even if we return an error to the caller.
|
|||
// It is by all means a valid and usable "kid" value for future requests.
|
|||
c.kid = keyID(a.URI) |
|||
if res.StatusCode == http.StatusOK { |
|||
return nil, ErrAccountAlreadyExists |
|||
} |
|||
return a, nil |
|||
} |
|||
|
|||
// encodeExternalAccountBinding will encode an external account binding stanza
|
|||
// as described in https://tools.ietf.org/html/rfc8555#section-7.3.4.
|
|||
func (c *Client) encodeExternalAccountBinding(eab *ExternalAccountBinding) (*jsonWebSignature, error) { |
|||
jwk, err := jwkEncode(c.Key.Public()) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
return jwsWithMAC(eab.Key, eab.KID, c.dir.RegURL, []byte(jwk)) |
|||
} |
|||
|
|||
// updateRegRFC is equivalent to c.UpdateReg but for CAs implementing RFC 8555.
|
|||
// It expects c.Discover to have already been called.
|
|||
func (c *Client) updateRegRFC(ctx context.Context, a *Account) (*Account, error) { |
|||
url := string(c.accountKID(ctx)) |
|||
if url == "" { |
|||
return nil, ErrNoAccount |
|||
} |
|||
req := struct { |
|||
Contact []string `json:"contact,omitempty"` |
|||
}{ |
|||
Contact: a.Contact, |
|||
} |
|||
res, err := c.post(ctx, nil, url, req, wantStatus(http.StatusOK)) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
defer res.Body.Close() |
|||
return responseAccount(res) |
|||
} |
|||
|
|||
// getGegRFC is equivalent to c.GetReg but for CAs implementing RFC 8555.
|
|||
// It expects c.Discover to have already been called.
|
|||
func (c *Client) getRegRFC(ctx context.Context) (*Account, error) { |
|||
req := json.RawMessage(`{"onlyReturnExisting": true}`) |
|||
res, err := c.post(ctx, c.Key, c.dir.RegURL, req, wantStatus(http.StatusOK)) |
|||
if e, ok := err.(*Error); ok && e.ProblemType == "urn:ietf:params:acme:error:accountDoesNotExist" { |
|||
return nil, ErrNoAccount |
|||
} |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
defer res.Body.Close() |
|||
return responseAccount(res) |
|||
} |
|||
|
|||
func responseAccount(res *http.Response) (*Account, error) { |
|||
var v struct { |
|||
Status string |
|||
Contact []string |
|||
Orders string |
|||
} |
|||
if err := json.NewDecoder(res.Body).Decode(&v); err != nil { |
|||
return nil, fmt.Errorf("acme: invalid account response: %v", err) |
|||
} |
|||
return &Account{ |
|||
URI: res.Header.Get("Location"), |
|||
Status: v.Status, |
|||
Contact: v.Contact, |
|||
OrdersURL: v.Orders, |
|||
}, nil |
|||
} |
|||
|
|||
// AuthorizeOrder initiates the order-based application for certificate issuance,
|
|||
// as opposed to pre-authorization in Authorize.
|
|||
// It is only supported by CAs implementing RFC 8555.
|
|||
//
|
|||
// The caller then needs to fetch each authorization with GetAuthorization,
|
|||
// identify those with StatusPending status and fulfill a challenge using Accept.
|
|||
// Once all authorizations are satisfied, the caller will typically want to poll
|
|||
// order status using WaitOrder until it's in StatusReady state.
|
|||
// To finalize the order and obtain a certificate, the caller submits a CSR with CreateOrderCert.
|
|||
func (c *Client) AuthorizeOrder(ctx context.Context, id []AuthzID, opt ...OrderOption) (*Order, error) { |
|||
dir, err := c.Discover(ctx) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
req := struct { |
|||
Identifiers []wireAuthzID `json:"identifiers"` |
|||
NotBefore string `json:"notBefore,omitempty"` |
|||
NotAfter string `json:"notAfter,omitempty"` |
|||
}{} |
|||
for _, v := range id { |
|||
req.Identifiers = append(req.Identifiers, wireAuthzID{ |
|||
Type: v.Type, |
|||
Value: v.Value, |
|||
}) |
|||
} |
|||
for _, o := range opt { |
|||
switch o := o.(type) { |
|||
case orderNotBeforeOpt: |
|||
req.NotBefore = time.Time(o).Format(time.RFC3339) |
|||
case orderNotAfterOpt: |
|||
req.NotAfter = time.Time(o).Format(time.RFC3339) |
|||
default: |
|||
// Package's fault if we let this happen.
|
|||
panic(fmt.Sprintf("unsupported order option type %T", o)) |
|||
} |
|||
} |
|||
|
|||
res, err := c.post(ctx, nil, dir.OrderURL, req, wantStatus(http.StatusCreated)) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
defer res.Body.Close() |
|||
return responseOrder(res) |
|||
} |
|||
|
|||
// GetOrder retrives an order identified by the given URL.
|
|||
// For orders created with AuthorizeOrder, the url value is Order.URI.
|
|||
//
|
|||
// If a caller needs to poll an order until its status is final,
|
|||
// see the WaitOrder method.
|
|||
func (c *Client) GetOrder(ctx context.Context, url string) (*Order, error) { |
|||
if _, err := c.Discover(ctx); err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
res, err := c.postAsGet(ctx, url, wantStatus(http.StatusOK)) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
defer res.Body.Close() |
|||
return responseOrder(res) |
|||
} |
|||
|
|||
// WaitOrder polls an order from the given URL until it is in one of the final states,
|
|||
// StatusReady, StatusValid or StatusInvalid, the CA responded with a non-retryable error
|
|||
// or the context is done.
|
|||
//
|
|||
// It returns a non-nil Order only if its Status is StatusReady or StatusValid.
|
|||
// In all other cases WaitOrder returns an error.
|
|||
// If the Status is StatusInvalid, the returned error is of type *OrderError.
|
|||
func (c *Client) WaitOrder(ctx context.Context, url string) (*Order, error) { |
|||
if _, err := c.Discover(ctx); err != nil { |
|||
return nil, err |
|||
} |
|||
for { |
|||
res, err := c.postAsGet(ctx, url, wantStatus(http.StatusOK)) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
o, err := responseOrder(res) |
|||
res.Body.Close() |
|||
switch { |
|||
case err != nil: |
|||
// Skip and retry.
|
|||
case o.Status == StatusInvalid: |
|||
return nil, &OrderError{OrderURL: o.URI, Status: o.Status} |
|||
case o.Status == StatusReady || o.Status == StatusValid: |
|||
return o, nil |
|||
} |
|||
|
|||
d := retryAfter(res.Header.Get("Retry-After")) |
|||
if d == 0 { |
|||
// Default retry-after.
|
|||
// Same reasoning as in WaitAuthorization.
|
|||
d = time.Second |
|||
} |
|||
t := time.NewTimer(d) |
|||
select { |
|||
case <-ctx.Done(): |
|||
t.Stop() |
|||
return nil, ctx.Err() |
|||
case <-t.C: |
|||
// Retry.
|
|||
} |
|||
} |
|||
} |
|||
|
|||
func responseOrder(res *http.Response) (*Order, error) { |
|||
var v struct { |
|||
Status string |
|||
Expires time.Time |
|||
Identifiers []wireAuthzID |
|||
NotBefore time.Time |
|||
NotAfter time.Time |
|||
Error *wireError |
|||
Authorizations []string |
|||
Finalize string |
|||
Certificate string |
|||
} |
|||
if err := json.NewDecoder(res.Body).Decode(&v); err != nil { |
|||
return nil, fmt.Errorf("acme: error reading order: %v", err) |
|||
} |
|||
o := &Order{ |
|||
URI: res.Header.Get("Location"), |
|||
Status: v.Status, |
|||
Expires: v.Expires, |
|||
NotBefore: v.NotBefore, |
|||
NotAfter: v.NotAfter, |
|||
AuthzURLs: v.Authorizations, |
|||
FinalizeURL: v.Finalize, |
|||
CertURL: v.Certificate, |
|||
} |
|||
for _, id := range v.Identifiers { |
|||
o.Identifiers = append(o.Identifiers, AuthzID{Type: id.Type, Value: id.Value}) |
|||
} |
|||
if v.Error != nil { |
|||
o.Error = v.Error.error(nil /* headers */) |
|||
} |
|||
return o, nil |
|||
} |
|||
|
|||
// CreateOrderCert submits the CSR (Certificate Signing Request) to a CA at the specified URL.
|
|||
// The URL is the FinalizeURL field of an Order created with AuthorizeOrder.
|
|||
//
|
|||
// If the bundle argument is true, the returned value also contain the CA (issuer)
|
|||
// certificate chain. Otherwise, only a leaf certificate is returned.
|
|||
// The returned URL can be used to re-fetch the certificate using FetchCert.
|
|||
//
|
|||
// This method is only supported by CAs implementing RFC 8555. See CreateCert for pre-RFC CAs.
|
|||
//
|
|||
// CreateOrderCert returns an error if the CA's response is unreasonably large.
|
|||
// Callers are encouraged to parse the returned value to ensure the certificate is valid and has the expected features.
|
|||
func (c *Client) CreateOrderCert(ctx context.Context, url string, csr []byte, bundle bool) (der [][]byte, certURL string, err error) { |
|||
if _, err := c.Discover(ctx); err != nil { // required by c.accountKID
|
|||
return nil, "", err |
|||
} |
|||
|
|||
// RFC describes this as "finalize order" request.
|
|||
req := struct { |
|||
CSR string `json:"csr"` |
|||
}{ |
|||
CSR: base64.RawURLEncoding.EncodeToString(csr), |
|||
} |
|||
res, err := c.post(ctx, nil, url, req, wantStatus(http.StatusOK)) |
|||
if err != nil { |
|||
return nil, "", err |
|||
} |
|||
defer res.Body.Close() |
|||
o, err := responseOrder(res) |
|||
if err != nil { |
|||
return nil, "", err |
|||
} |
|||
|
|||
// Wait for CA to issue the cert if they haven't.
|
|||
if o.Status != StatusValid { |
|||
o, err = c.WaitOrder(ctx, o.URI) |
|||
} |
|||
if err != nil { |
|||
return nil, "", err |
|||
} |
|||
// The only acceptable status post finalize and WaitOrder is "valid".
|
|||
if o.Status != StatusValid { |
|||
return nil, "", &OrderError{OrderURL: o.URI, Status: o.Status} |
|||
} |
|||
crt, err := c.fetchCertRFC(ctx, o.CertURL, bundle) |
|||
return crt, o.CertURL, err |
|||
} |
|||
|
|||
// fetchCertRFC downloads issued certificate from the given URL.
|
|||
// It expects the CA to respond with PEM-encoded certificate chain.
|
|||
//
|
|||
// The URL argument is the CertURL field of Order.
|
|||
func (c *Client) fetchCertRFC(ctx context.Context, url string, bundle bool) ([][]byte, error) { |
|||
res, err := c.postAsGet(ctx, url, wantStatus(http.StatusOK)) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
defer res.Body.Close() |
|||
|
|||
// Get all the bytes up to a sane maximum.
|
|||
// Account very roughly for base64 overhead.
|
|||
const max = maxCertChainSize + maxCertChainSize/33 |
|||
b, err := ioutil.ReadAll(io.LimitReader(res.Body, max+1)) |
|||
if err != nil { |
|||
return nil, fmt.Errorf("acme: fetch cert response stream: %v", err) |
|||
} |
|||
if len(b) > max { |
|||
return nil, errors.New("acme: certificate chain is too big") |
|||
} |
|||
|
|||
// Decode PEM chain.
|
|||
var chain [][]byte |
|||
for { |
|||
var p *pem.Block |
|||
p, b = pem.Decode(b) |
|||
if p == nil { |
|||
break |
|||
} |
|||
if p.Type != "CERTIFICATE" { |
|||
return nil, fmt.Errorf("acme: invalid PEM cert type %q", p.Type) |
|||
} |
|||
|
|||
chain = append(chain, p.Bytes) |
|||
if !bundle { |
|||
return chain, nil |
|||
} |
|||
if len(chain) > maxChainLen { |
|||
return nil, errors.New("acme: certificate chain is too long") |
|||
} |
|||
} |
|||
if len(chain) == 0 { |
|||
return nil, errors.New("acme: certificate chain is empty") |
|||
} |
|||
return chain, nil |
|||
} |
|||
|
|||
// sends a cert revocation request in either JWK form when key is non-nil or KID form otherwise.
|
|||
func (c *Client) revokeCertRFC(ctx context.Context, key crypto.Signer, cert []byte, reason CRLReasonCode) error { |
|||
req := &struct { |
|||
Cert string `json:"certificate"` |
|||
Reason int `json:"reason"` |
|||
}{ |
|||
Cert: base64.RawURLEncoding.EncodeToString(cert), |
|||
Reason: int(reason), |
|||
} |
|||
res, err := c.post(ctx, key, c.dir.RevokeURL, req, wantStatus(http.StatusOK)) |
|||
if err != nil { |
|||
if isAlreadyRevoked(err) { |
|||
// Assume it is not an error to revoke an already revoked cert.
|
|||
return nil |
|||
} |
|||
return err |
|||
} |
|||
defer res.Body.Close() |
|||
return nil |
|||
} |
|||
|
|||
func isAlreadyRevoked(err error) bool { |
|||
e, ok := err.(*Error) |
|||
return ok && e.ProblemType == "urn:ietf:params:acme:error:alreadyRevoked" |
|||
} |
|||
|
|||
// ListCertAlternates retrieves any alternate certificate chain URLs for the
|
|||
// given certificate chain URL. These alternate URLs can be passed to FetchCert
|
|||
// in order to retrieve the alternate certificate chains.
|
|||
//
|
|||
// If there are no alternate issuer certificate chains, a nil slice will be
|
|||
// returned.
|
|||
func (c *Client) ListCertAlternates(ctx context.Context, url string) ([]string, error) { |
|||
if _, err := c.Discover(ctx); err != nil { // required by c.accountKID
|
|||
return nil, err |
|||
} |
|||
|
|||
res, err := c.postAsGet(ctx, url, wantStatus(http.StatusOK)) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
defer res.Body.Close() |
|||
|
|||
// We don't need the body but we need to discard it so we don't end up
|
|||
// preventing keep-alive
|
|||
if _, err := io.Copy(ioutil.Discard, res.Body); err != nil { |
|||
return nil, fmt.Errorf("acme: cert alternates response stream: %v", err) |
|||
} |
|||
alts := linkHeader(res.Header, "alternate") |
|||
return alts, nil |
|||
} |
@ -0,0 +1,28 @@ |
|||
// Copyright 2019 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.
|
|||
|
|||
//go:build go1.12
|
|||
// +build go1.12
|
|||
|
|||
package acme |
|||
|
|||
import "runtime/debug" |
|||
|
|||
func init() { |
|||
// Set packageVersion if the binary was built in modules mode and x/crypto
|
|||
// was not replaced with a different module.
|
|||
info, ok := debug.ReadBuildInfo() |
|||
if !ok { |
|||
return |
|||
} |
|||
for _, m := range info.Deps { |
|||
if m.Path != "golang.org/x/crypto" { |
|||
continue |
|||
} |
|||
if m.Replace == nil { |
|||
packageVersion = m.Version |
|||
} |
|||
break |
|||
} |
|||
} |
@ -1,3 +0,0 @@ |
|||
# This source code refers to The Go Authors for copyright purposes. |
|||
# The master list of authors is in the main Go distribution, |
|||
# visible at http://tip.golang.org/AUTHORS. |
@ -1,3 +0,0 @@ |
|||
# This source code was written by the Go contributors. |
|||
# The master list of contributors is in the main Go distribution, |
|||
# visible at http://tip.golang.org/CONTRIBUTORS. |
@ -1,56 +0,0 @@ |
|||
// Copyright 2014 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 context defines the Context type, which carries deadlines,
|
|||
// cancelation signals, and other request-scoped values across API boundaries
|
|||
// and between processes.
|
|||
// As of Go 1.7 this package is available in the standard library under the
|
|||
// name context. https://golang.org/pkg/context.
|
|||
//
|
|||
// Incoming requests to a server should create a Context, and outgoing calls to
|
|||
// servers should accept a Context. The chain of function calls between must
|
|||
// propagate the Context, optionally replacing it with a modified copy created
|
|||
// using WithDeadline, WithTimeout, WithCancel, or WithValue.
|
|||
//
|
|||
// Programs that use Contexts should follow these rules to keep interfaces
|
|||
// consistent across packages and enable static analysis tools to check context
|
|||
// propagation:
|
|||
//
|
|||
// Do not store Contexts inside a struct type; instead, pass a Context
|
|||
// explicitly to each function that needs it. The Context should be the first
|
|||
// parameter, typically named ctx:
|
|||
//
|
|||
// func DoSomething(ctx context.Context, arg Arg) error {
|
|||
// // ... use ctx ...
|
|||
// }
|
|||
//
|
|||
// Do not pass a nil Context, even if a function permits it. Pass context.TODO
|
|||
// if you are unsure about which Context to use.
|
|||
//
|
|||
// Use context Values only for request-scoped data that transits processes and
|
|||
// APIs, not for passing optional parameters to functions.
|
|||
//
|
|||
// The same Context may be passed to functions running in different goroutines;
|
|||
// Contexts are safe for simultaneous use by multiple goroutines.
|
|||
//
|
|||
// See http://blog.golang.org/context for example code for a server that uses
|
|||
// Contexts.
|
|||
package context // import "golang.org/x/net/context"
|
|||
|
|||
// Background returns a non-nil, empty Context. It is never canceled, has no
|
|||
// values, and has no deadline. It is typically used by the main function,
|
|||
// initialization, and tests, and as the top-level Context for incoming
|
|||
// requests.
|
|||
func Background() Context { |
|||
return background |
|||
} |
|||
|
|||
// TODO returns a non-nil, empty Context. Code should use context.TODO when
|
|||
// it's unclear which Context to use or it is not yet available (because the
|
|||
// surrounding function has not yet been extended to accept a Context
|
|||
// parameter). TODO is recognized by static analysis tools that determine
|
|||
// whether Contexts are propagated correctly in a program.
|
|||
func TODO() Context { |
|||
return todo |
|||
} |
@ -1,72 +0,0 @@ |
|||
// Copyright 2016 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.
|
|||
|
|||
// +build go1.7
|
|||
|
|||
package context |
|||
|
|||
import ( |
|||
"context" // standard library's context, as of Go 1.7
|
|||
"time" |
|||
) |
|||
|
|||
var ( |
|||
todo = context.TODO() |
|||
background = context.Background() |
|||
) |
|||
|
|||
// Canceled is the error returned by Context.Err when the context is canceled.
|
|||
var Canceled = context.Canceled |
|||
|
|||
// DeadlineExceeded is the error returned by Context.Err when the context's
|
|||
// deadline passes.
|
|||
var DeadlineExceeded = context.DeadlineExceeded |
|||
|
|||
// WithCancel returns a copy of parent with a new Done channel. The returned
|
|||
// context's Done channel is closed when the returned cancel function is called
|
|||
// or when the parent context's Done channel is closed, whichever happens first.
|
|||
//
|
|||
// Canceling this context releases resources associated with it, so code should
|
|||
// call cancel as soon as the operations running in this Context complete.
|
|||
func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { |
|||
ctx, f := context.WithCancel(parent) |
|||
return ctx, CancelFunc(f) |
|||
} |
|||
|
|||
// WithDeadline returns a copy of the parent context with the deadline adjusted
|
|||
// to be no later than d. If the parent's deadline is already earlier than d,
|
|||
// WithDeadline(parent, d) is semantically equivalent to parent. The returned
|
|||
// context's Done channel is closed when the deadline expires, when the returned
|
|||
// cancel function is called, or when the parent context's Done channel is
|
|||
// closed, whichever happens first.
|
|||
//
|
|||
// Canceling this context releases resources associated with it, so code should
|
|||
// call cancel as soon as the operations running in this Context complete.
|
|||
func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) { |
|||
ctx, f := context.WithDeadline(parent, deadline) |
|||
return ctx, CancelFunc(f) |
|||
} |
|||
|
|||
// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
|
|||
//
|
|||
// Canceling this context releases resources associated with it, so code should
|
|||
// call cancel as soon as the operations running in this Context complete:
|
|||
//
|
|||
// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
|
|||
// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
|
|||
// defer cancel() // releases resources if slowOperation completes before timeout elapses
|
|||
// return slowOperation(ctx)
|
|||
// }
|
|||
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { |
|||
return WithDeadline(parent, time.Now().Add(timeout)) |
|||
} |
|||
|
|||
// WithValue returns a copy of parent in which the value associated with key is
|
|||
// val.
|
|||
//
|
|||
// Use context Values only for request-scoped data that transits processes and
|
|||
// APIs, not for passing optional parameters to functions.
|
|||
func WithValue(parent Context, key interface{}, val interface{}) Context { |
|||
return context.WithValue(parent, key, val) |
|||
} |
@ -1,20 +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.
|
|||
|
|||
// +build go1.9
|
|||
|
|||
package context |
|||
|
|||
import "context" // standard library's context, as of Go 1.7
|
|||
|
|||
// A Context carries a deadline, a cancelation signal, and other values across
|
|||
// API boundaries.
|
|||
//
|
|||
// Context's methods may be called by multiple goroutines simultaneously.
|
|||
type Context = context.Context |
|||
|
|||
// A CancelFunc tells an operation to abandon its work.
|
|||
// A CancelFunc does not wait for the work to stop.
|
|||
// After the first call, subsequent calls to a CancelFunc do nothing.
|
|||
type CancelFunc = context.CancelFunc |
@ -1,300 +0,0 @@ |
|||
// Copyright 2014 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.
|
|||
|
|||
// +build !go1.7
|
|||
|
|||
package context |
|||
|
|||
import ( |
|||
"errors" |
|||
"fmt" |
|||
"sync" |
|||
"time" |
|||
) |
|||
|
|||
// An emptyCtx is never canceled, has no values, and has no deadline. It is not
|
|||
// struct{}, since vars of this type must have distinct addresses.
|
|||
type emptyCtx int |
|||
|
|||
func (*emptyCtx) Deadline() (deadline time.Time, ok bool) { |
|||
return |
|||
} |
|||
|
|||
func (*emptyCtx) Done() <-chan struct{} { |
|||
return nil |
|||
} |
|||
|
|||
func (*emptyCtx) Err() error { |
|||
return nil |
|||
} |
|||
|
|||
func (*emptyCtx) Value(key interface{}) interface{} { |
|||
return nil |
|||
} |
|||
|
|||
func (e *emptyCtx) String() string { |
|||
switch e { |
|||
case background: |
|||
return "context.Background" |
|||
case todo: |
|||
return "context.TODO" |
|||
} |
|||
return "unknown empty Context" |
|||
} |
|||
|
|||
var ( |
|||
background = new(emptyCtx) |
|||
todo = new(emptyCtx) |
|||
) |
|||
|
|||
// Canceled is the error returned by Context.Err when the context is canceled.
|
|||
var Canceled = errors.New("context canceled") |
|||
|
|||
// DeadlineExceeded is the error returned by Context.Err when the context's
|
|||
// deadline passes.
|
|||
var DeadlineExceeded = errors.New("context deadline exceeded") |
|||
|
|||
// WithCancel returns a copy of parent with a new Done channel. The returned
|
|||
// context's Done channel is closed when the returned cancel function is called
|
|||
// or when the parent context's Done channel is closed, whichever happens first.
|
|||
//
|
|||
// Canceling this context releases resources associated with it, so code should
|
|||
// call cancel as soon as the operations running in this Context complete.
|
|||
func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { |
|||
c := newCancelCtx(parent) |
|||
propagateCancel(parent, c) |
|||
return c, func() { c.cancel(true, Canceled) } |
|||
} |
|||
|
|||
// newCancelCtx returns an initialized cancelCtx.
|
|||
func newCancelCtx(parent Context) *cancelCtx { |
|||
return &cancelCtx{ |
|||
Context: parent, |
|||
done: make(chan struct{}), |
|||
} |
|||
} |
|||
|
|||
// propagateCancel arranges for child to be canceled when parent is.
|
|||
func propagateCancel(parent Context, child canceler) { |
|||
if parent.Done() == nil { |
|||
return // parent is never canceled
|
|||
} |
|||
if p, ok := parentCancelCtx(parent); ok { |
|||
p.mu.Lock() |
|||
if p.err != nil { |
|||
// parent has already been canceled
|
|||
child.cancel(false, p.err) |
|||
} else { |
|||
if p.children == nil { |
|||
p.children = make(map[canceler]bool) |
|||
} |
|||
p.children[child] = true |
|||
} |
|||
p.mu.Unlock() |
|||
} else { |
|||
go func() { |
|||
select { |
|||
case <-parent.Done(): |
|||
child.cancel(false, parent.Err()) |
|||
case <-child.Done(): |
|||
} |
|||
}() |
|||
} |
|||
} |
|||
|
|||
// parentCancelCtx follows a chain of parent references until it finds a
|
|||
// *cancelCtx. This function understands how each of the concrete types in this
|
|||
// package represents its parent.
|
|||
func parentCancelCtx(parent Context) (*cancelCtx, bool) { |
|||
for { |
|||
switch c := parent.(type) { |
|||
case *cancelCtx: |
|||
return c, true |
|||
case *timerCtx: |
|||
return c.cancelCtx, true |
|||
case *valueCtx: |
|||
parent = c.Context |
|||
default: |
|||
return nil, false |
|||
} |
|||
} |
|||
} |
|||
|
|||
// removeChild removes a context from its parent.
|
|||
func removeChild(parent Context, child canceler) { |
|||
p, ok := parentCancelCtx(parent) |
|||
if !ok { |
|||
return |
|||
} |
|||
p.mu.Lock() |
|||
if p.children != nil { |
|||
delete(p.children, child) |
|||
} |
|||
p.mu.Unlock() |
|||
} |
|||
|
|||
// A canceler is a context type that can be canceled directly. The
|
|||
// implementations are *cancelCtx and *timerCtx.
|
|||
type canceler interface { |
|||
cancel(removeFromParent bool, err error) |
|||
Done() <-chan struct{} |
|||
} |
|||
|
|||
// A cancelCtx can be canceled. When canceled, it also cancels any children
|
|||
// that implement canceler.
|
|||
type cancelCtx struct { |
|||
Context |
|||
|
|||
done chan struct{} // closed by the first cancel call.
|
|||
|
|||
mu sync.Mutex |
|||
children map[canceler]bool // set to nil by the first cancel call
|
|||
err error // set to non-nil by the first cancel call
|
|||
} |
|||
|
|||
func (c *cancelCtx) Done() <-chan struct{} { |
|||
return c.done |
|||
} |
|||
|
|||
func (c *cancelCtx) Err() error { |
|||
c.mu.Lock() |
|||
defer c.mu.Unlock() |
|||
return c.err |
|||
} |
|||
|
|||
func (c *cancelCtx) String() string { |
|||
return fmt.Sprintf("%v.WithCancel", c.Context) |
|||
} |
|||
|
|||
// cancel closes c.done, cancels each of c's children, and, if
|
|||
// removeFromParent is true, removes c from its parent's children.
|
|||
func (c *cancelCtx) cancel(removeFromParent bool, err error) { |
|||
if err == nil { |
|||
panic("context: internal error: missing cancel error") |
|||
} |
|||
c.mu.Lock() |
|||
if c.err != nil { |
|||
c.mu.Unlock() |
|||
return // already canceled
|
|||
} |
|||
c.err = err |
|||
close(c.done) |
|||
for child := range c.children { |
|||
// NOTE: acquiring the child's lock while holding parent's lock.
|
|||
child.cancel(false, err) |
|||
} |
|||
c.children = nil |
|||
c.mu.Unlock() |
|||
|
|||
if removeFromParent { |
|||
removeChild(c.Context, c) |
|||
} |
|||
} |
|||
|
|||
// WithDeadline returns a copy of the parent context with the deadline adjusted
|
|||
// to be no later than d. If the parent's deadline is already earlier than d,
|
|||
// WithDeadline(parent, d) is semantically equivalent to parent. The returned
|
|||
// context's Done channel is closed when the deadline expires, when the returned
|
|||
// cancel function is called, or when the parent context's Done channel is
|
|||
// closed, whichever happens first.
|
|||
//
|
|||
// Canceling this context releases resources associated with it, so code should
|
|||
// call cancel as soon as the operations running in this Context complete.
|
|||
func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) { |
|||
if cur, ok := parent.Deadline(); ok && cur.Before(deadline) { |
|||
// The current deadline is already sooner than the new one.
|
|||
return WithCancel(parent) |
|||
} |
|||
c := &timerCtx{ |
|||
cancelCtx: newCancelCtx(parent), |
|||
deadline: deadline, |
|||
} |
|||
propagateCancel(parent, c) |
|||
d := deadline.Sub(time.Now()) |
|||
if d <= 0 { |
|||
c.cancel(true, DeadlineExceeded) // deadline has already passed
|
|||
return c, func() { c.cancel(true, Canceled) } |
|||
} |
|||
c.mu.Lock() |
|||
defer c.mu.Unlock() |
|||
if c.err == nil { |
|||
c.timer = time.AfterFunc(d, func() { |
|||
c.cancel(true, DeadlineExceeded) |
|||
}) |
|||
} |
|||
return c, func() { c.cancel(true, Canceled) } |
|||
} |
|||
|
|||
// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to
|
|||
// implement Done and Err. It implements cancel by stopping its timer then
|
|||
// delegating to cancelCtx.cancel.
|
|||
type timerCtx struct { |
|||
*cancelCtx |
|||
timer *time.Timer // Under cancelCtx.mu.
|
|||
|
|||
deadline time.Time |
|||
} |
|||
|
|||
func (c *timerCtx) Deadline() (deadline time.Time, ok bool) { |
|||
return c.deadline, true |
|||
} |
|||
|
|||
func (c *timerCtx) String() string { |
|||
return fmt.Sprintf("%v.WithDeadline(%s [%s])", c.cancelCtx.Context, c.deadline, c.deadline.Sub(time.Now())) |
|||
} |
|||
|
|||
func (c *timerCtx) cancel(removeFromParent bool, err error) { |
|||
c.cancelCtx.cancel(false, err) |
|||
if removeFromParent { |
|||
// Remove this timerCtx from its parent cancelCtx's children.
|
|||
removeChild(c.cancelCtx.Context, c) |
|||
} |
|||
c.mu.Lock() |
|||
if c.timer != nil { |
|||
c.timer.Stop() |
|||
c.timer = nil |
|||
} |
|||
c.mu.Unlock() |
|||
} |
|||
|
|||
// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
|
|||
//
|
|||
// Canceling this context releases resources associated with it, so code should
|
|||
// call cancel as soon as the operations running in this Context complete:
|
|||
//
|
|||
// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
|
|||
// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
|
|||
// defer cancel() // releases resources if slowOperation completes before timeout elapses
|
|||
// return slowOperation(ctx)
|
|||
// }
|
|||
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { |
|||
return WithDeadline(parent, time.Now().Add(timeout)) |
|||
} |
|||
|
|||
// WithValue returns a copy of parent in which the value associated with key is
|
|||
// val.
|
|||
//
|
|||
// Use context Values only for request-scoped data that transits processes and
|
|||
// APIs, not for passing optional parameters to functions.
|
|||
func WithValue(parent Context, key interface{}, val interface{}) Context { |
|||
return &valueCtx{parent, key, val} |
|||
} |
|||
|
|||
// A valueCtx carries a key-value pair. It implements Value for that key and
|
|||
// delegates all other calls to the embedded Context.
|
|||
type valueCtx struct { |
|||
Context |
|||
key, val interface{} |
|||
} |
|||
|
|||
func (c *valueCtx) String() string { |
|||
return fmt.Sprintf("%v.WithValue(%#v, %#v)", c.Context, c.key, c.val) |
|||
} |
|||
|
|||
func (c *valueCtx) Value(key interface{}) interface{} { |
|||
if c.key == key { |
|||
return c.val |
|||
} |
|||
return c.Context.Value(key) |
|||
} |
@ -1,109 +0,0 @@ |
|||
// Copyright 2014 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.
|
|||
|
|||
// +build !go1.9
|
|||
|
|||
package context |
|||
|
|||
import "time" |
|||
|
|||
// A Context carries a deadline, a cancelation signal, and other values across
|
|||
// API boundaries.
|
|||
//
|
|||
// Context's methods may be called by multiple goroutines simultaneously.
|
|||
type Context interface { |
|||
// Deadline returns the time when work done on behalf of this context
|
|||
// should be canceled. Deadline returns ok==false when no deadline is
|
|||
// set. Successive calls to Deadline return the same results.
|
|||
Deadline() (deadline time.Time, ok bool) |
|||
|
|||
// Done returns a channel that's closed when work done on behalf of this
|
|||
// context should be canceled. Done may return nil if this context can
|
|||
// never be canceled. Successive calls to Done return the same value.
|
|||
//
|
|||
// WithCancel arranges for Done to be closed when cancel is called;
|
|||
// WithDeadline arranges for Done to be closed when the deadline
|
|||
// expires; WithTimeout arranges for Done to be closed when the timeout
|
|||
// elapses.
|
|||
//
|
|||
// Done is provided for use in select statements:
|
|||
//
|
|||
// // Stream generates values with DoSomething and sends them to out
|
|||
// // until DoSomething returns an error or ctx.Done is closed.
|
|||
// func Stream(ctx context.Context, out chan<- Value) error {
|
|||
// for {
|
|||
// v, err := DoSomething(ctx)
|
|||
// if err != nil {
|
|||
// return err
|
|||
// }
|
|||
// select {
|
|||
// case <-ctx.Done():
|
|||
// return ctx.Err()
|
|||
// case out <- v:
|
|||
// }
|
|||
// }
|
|||
// }
|
|||
//
|
|||
// See http://blog.golang.org/pipelines for more examples of how to use
|
|||
// a Done channel for cancelation.
|
|||
Done() <-chan struct{} |
|||
|
|||
// Err returns a non-nil error value after Done is closed. Err returns
|
|||
// Canceled if the context was canceled or DeadlineExceeded if the
|
|||
// context's deadline passed. No other values for Err are defined.
|
|||
// After Done is closed, successive calls to Err return the same value.
|
|||
Err() error |
|||
|
|||
// Value returns the value associated with this context for key, or nil
|
|||
// if no value is associated with key. Successive calls to Value with
|
|||
// the same key returns the same result.
|
|||
//
|
|||
// Use context values only for request-scoped data that transits
|
|||
// processes and API boundaries, not for passing optional parameters to
|
|||
// functions.
|
|||
//
|
|||
// A key identifies a specific value in a Context. Functions that wish
|
|||
// to store values in Context typically allocate a key in a global
|
|||
// variable then use that key as the argument to context.WithValue and
|
|||
// Context.Value. A key can be any type that supports equality;
|
|||
// packages should define keys as an unexported type to avoid
|
|||
// collisions.
|
|||
//
|
|||
// Packages that define a Context key should provide type-safe accessors
|
|||
// for the values stores using that key:
|
|||
//
|
|||
// // Package user defines a User type that's stored in Contexts.
|
|||
// package user
|
|||
//
|
|||
// import "golang.org/x/net/context"
|
|||
//
|
|||
// // User is the type of value stored in the Contexts.
|
|||
// type User struct {...}
|
|||
//
|
|||
// // key is an unexported type for keys defined in this package.
|
|||
// // This prevents collisions with keys defined in other packages.
|
|||
// type key int
|
|||
//
|
|||
// // userKey is the key for user.User values in Contexts. It is
|
|||
// // unexported; clients use user.NewContext and user.FromContext
|
|||
// // instead of using this key directly.
|
|||
// var userKey key = 0
|
|||
//
|
|||
// // NewContext returns a new Context that carries value u.
|
|||
// func NewContext(ctx context.Context, u *User) context.Context {
|
|||
// return context.WithValue(ctx, userKey, u)
|
|||
// }
|
|||
//
|
|||
// // FromContext returns the User value stored in ctx, if any.
|
|||
// func FromContext(ctx context.Context) (*User, bool) {
|
|||
// u, ok := ctx.Value(userKey).(*User)
|
|||
// return u, ok
|
|||
// }
|
|||
Value(key interface{}) interface{} |
|||
} |
|||
|
|||
// A CancelFunc tells an operation to abandon its work.
|
|||
// A CancelFunc does not wait for the work to stop.
|
|||
// After the first call, subsequent calls to a CancelFunc do nothing.
|
|||
type CancelFunc func() |
@ -0,0 +1,14 @@ |
|||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
|||
|
|||
// Copyright 2021 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.
|
|||
|
|||
//go:build go1.18
|
|||
// +build go1.18
|
|||
|
|||
package idna |
|||
|
|||
// Transitional processing is disabled by default in Go 1.18.
|
|||
// https://golang.org/issue/47510
|
|||
const transitionalLookup = false |
@ -0,0 +1,770 @@ |
|||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
|||
|
|||
// Copyright 2016 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.
|
|||
|
|||
//go:build go1.10
|
|||
// +build go1.10
|
|||
|
|||
// Package idna implements IDNA2008 using the compatibility processing
|
|||
// defined by UTS (Unicode Technical Standard) #46, which defines a standard to
|
|||
// deal with the transition from IDNA2003.
|
|||
//
|
|||
// IDNA2008 (Internationalized Domain Names for Applications), is defined in RFC
|
|||
// 5890, RFC 5891, RFC 5892, RFC 5893 and RFC 5894.
|
|||
// UTS #46 is defined in https://www.unicode.org/reports/tr46.
|
|||
// See https://unicode.org/cldr/utility/idna.jsp for a visualization of the
|
|||
// differences between these two standards.
|
|||
package idna // import "golang.org/x/net/idna"
|
|||
|
|||
import ( |
|||
"fmt" |
|||
"strings" |
|||
"unicode/utf8" |
|||
|
|||
"golang.org/x/text/secure/bidirule" |
|||
"golang.org/x/text/unicode/bidi" |
|||
"golang.org/x/text/unicode/norm" |
|||
) |
|||
|
|||
// NOTE: Unlike common practice in Go APIs, the functions will return a
|
|||
// sanitized domain name in case of errors. Browsers sometimes use a partially
|
|||
// evaluated string as lookup.
|
|||
// TODO: the current error handling is, in my opinion, the least opinionated.
|
|||
// Other strategies are also viable, though:
|
|||
// Option 1) Return an empty string in case of error, but allow the user to
|
|||
// specify explicitly which errors to ignore.
|
|||
// Option 2) Return the partially evaluated string if it is itself a valid
|
|||
// string, otherwise return the empty string in case of error.
|
|||
// Option 3) Option 1 and 2.
|
|||
// Option 4) Always return an empty string for now and implement Option 1 as
|
|||
// needed, and document that the return string may not be empty in case of
|
|||
// error in the future.
|
|||
// I think Option 1 is best, but it is quite opinionated.
|
|||
|
|||
// ToASCII is a wrapper for Punycode.ToASCII.
|
|||
func ToASCII(s string) (string, error) { |
|||
return Punycode.process(s, true) |
|||
} |
|||
|
|||
// ToUnicode is a wrapper for Punycode.ToUnicode.
|
|||
func ToUnicode(s string) (string, error) { |
|||
return Punycode.process(s, false) |
|||
} |
|||
|
|||
// An Option configures a Profile at creation time.
|
|||
type Option func(*options) |
|||
|
|||
// Transitional sets a Profile to use the Transitional mapping as defined in UTS
|
|||
// #46. This will cause, for example, "ß" to be mapped to "ss". Using the
|
|||
// transitional mapping provides a compromise between IDNA2003 and IDNA2008
|
|||
// compatibility. It is used by some browsers when resolving domain names. This
|
|||
// option is only meaningful if combined with MapForLookup.
|
|||
func Transitional(transitional bool) Option { |
|||
return func(o *options) { o.transitional = transitional } |
|||
} |
|||
|
|||
// VerifyDNSLength sets whether a Profile should fail if any of the IDN parts
|
|||
// are longer than allowed by the RFC.
|
|||
//
|
|||
// This option corresponds to the VerifyDnsLength flag in UTS #46.
|
|||
func VerifyDNSLength(verify bool) Option { |
|||
return func(o *options) { o.verifyDNSLength = verify } |
|||
} |
|||
|
|||
// RemoveLeadingDots removes leading label separators. Leading runes that map to
|
|||
// dots, such as U+3002 IDEOGRAPHIC FULL STOP, are removed as well.
|
|||
func RemoveLeadingDots(remove bool) Option { |
|||
return func(o *options) { o.removeLeadingDots = remove } |
|||
} |
|||
|
|||
// ValidateLabels sets whether to check the mandatory label validation criteria
|
|||
// as defined in Section 5.4 of RFC 5891. This includes testing for correct use
|
|||
// of hyphens ('-'), normalization, validity of runes, and the context rules.
|
|||
// In particular, ValidateLabels also sets the CheckHyphens and CheckJoiners flags
|
|||
// in UTS #46.
|
|||
func ValidateLabels(enable bool) Option { |
|||
return func(o *options) { |
|||
// Don't override existing mappings, but set one that at least checks
|
|||
// normalization if it is not set.
|
|||
if o.mapping == nil && enable { |
|||
o.mapping = normalize |
|||
} |
|||
o.trie = trie |
|||
o.checkJoiners = enable |
|||
o.checkHyphens = enable |
|||
if enable { |
|||
o.fromPuny = validateFromPunycode |
|||
} else { |
|||
o.fromPuny = nil |
|||
} |
|||
} |
|||
} |
|||
|
|||
// CheckHyphens sets whether to check for correct use of hyphens ('-') in
|
|||
// labels. Most web browsers do not have this option set, since labels such as
|
|||
// "r3---sn-apo3qvuoxuxbt-j5pe" are in common use.
|
|||
//
|
|||
// This option corresponds to the CheckHyphens flag in UTS #46.
|
|||
func CheckHyphens(enable bool) Option { |
|||
return func(o *options) { o.checkHyphens = enable } |
|||
} |
|||
|
|||
// CheckJoiners sets whether to check the ContextJ rules as defined in Appendix
|
|||
// A of RFC 5892, concerning the use of joiner runes.
|
|||
//
|
|||
// This option corresponds to the CheckJoiners flag in UTS #46.
|
|||
func CheckJoiners(enable bool) Option { |
|||
return func(o *options) { |
|||
o.trie = trie |
|||
o.checkJoiners = enable |
|||
} |
|||
} |
|||
|
|||
// StrictDomainName limits the set of permissible ASCII characters to those
|
|||
// allowed in domain names as defined in RFC 1034 (A-Z, a-z, 0-9 and the
|
|||
// hyphen). This is set by default for MapForLookup and ValidateForRegistration,
|
|||
// but is only useful if ValidateLabels is set.
|
|||
//
|
|||
// This option is useful, for instance, for browsers that allow characters
|
|||
// outside this range, for example a '_' (U+005F LOW LINE). See
|
|||
// http://www.rfc-editor.org/std/std3.txt for more details.
|
|||
//
|
|||
// This option corresponds to the UseSTD3ASCIIRules flag in UTS #46.
|
|||
func StrictDomainName(use bool) Option { |
|||
return func(o *options) { o.useSTD3Rules = use } |
|||
} |
|||
|
|||
// NOTE: the following options pull in tables. The tables should not be linked
|
|||
// in as long as the options are not used.
|
|||
|
|||
// BidiRule enables the Bidi rule as defined in RFC 5893. Any application
|
|||
// that relies on proper validation of labels should include this rule.
|
|||
//
|
|||
// This option corresponds to the CheckBidi flag in UTS #46.
|
|||
func BidiRule() Option { |
|||
return func(o *options) { o.bidirule = bidirule.ValidString } |
|||
} |
|||
|
|||
// ValidateForRegistration sets validation options to verify that a given IDN is
|
|||
// properly formatted for registration as defined by Section 4 of RFC 5891.
|
|||
func ValidateForRegistration() Option { |
|||
return func(o *options) { |
|||
o.mapping = validateRegistration |
|||
StrictDomainName(true)(o) |
|||
ValidateLabels(true)(o) |
|||
VerifyDNSLength(true)(o) |
|||
BidiRule()(o) |
|||
} |
|||
} |
|||
|
|||
// MapForLookup sets validation and mapping options such that a given IDN is
|
|||
// transformed for domain name lookup according to the requirements set out in
|
|||
// Section 5 of RFC 5891. The mappings follow the recommendations of RFC 5894,
|
|||
// RFC 5895 and UTS 46. It does not add the Bidi Rule. Use the BidiRule option
|
|||
// to add this check.
|
|||
//
|
|||
// The mappings include normalization and mapping case, width and other
|
|||
// compatibility mappings.
|
|||
func MapForLookup() Option { |
|||
return func(o *options) { |
|||
o.mapping = validateAndMap |
|||
StrictDomainName(true)(o) |
|||
ValidateLabels(true)(o) |
|||
} |
|||
} |
|||
|
|||
type options struct { |
|||
transitional bool |
|||
useSTD3Rules bool |
|||
checkHyphens bool |
|||
checkJoiners bool |
|||
verifyDNSLength bool |
|||
removeLeadingDots bool |
|||
|
|||
trie *idnaTrie |
|||
|
|||
// fromPuny calls validation rules when converting A-labels to U-labels.
|
|||
fromPuny func(p *Profile, s string) error |
|||
|
|||
// mapping implements a validation and mapping step as defined in RFC 5895
|
|||
// or UTS 46, tailored to, for example, domain registration or lookup.
|
|||
mapping func(p *Profile, s string) (mapped string, isBidi bool, err error) |
|||
|
|||
// bidirule, if specified, checks whether s conforms to the Bidi Rule
|
|||
// defined in RFC 5893.
|
|||
bidirule func(s string) bool |
|||
} |
|||
|
|||
// A Profile defines the configuration of an IDNA mapper.
|
|||
type Profile struct { |
|||
options |
|||
} |
|||
|
|||
func apply(o *options, opts []Option) { |
|||
for _, f := range opts { |
|||
f(o) |
|||
} |
|||
} |
|||
|
|||
// New creates a new Profile.
|
|||
//
|
|||
// With no options, the returned Profile is the most permissive and equals the
|
|||
// Punycode Profile. Options can be passed to further restrict the Profile. The
|
|||
// MapForLookup and ValidateForRegistration options set a collection of options,
|
|||
// for lookup and registration purposes respectively, which can be tailored by
|
|||
// adding more fine-grained options, where later options override earlier
|
|||
// options.
|
|||
func New(o ...Option) *Profile { |
|||
p := &Profile{} |
|||
apply(&p.options, o) |
|||
return p |
|||
} |
|||
|
|||
// ToASCII converts a domain or domain label to its ASCII form. For example,
|
|||
// ToASCII("bücher.example.com") is "xn--bcher-kva.example.com", and
|
|||
// ToASCII("golang") is "golang". If an error is encountered it will return
|
|||
// an error and a (partially) processed result.
|
|||
func (p *Profile) ToASCII(s string) (string, error) { |
|||
return p.process(s, true) |
|||
} |
|||
|
|||
// ToUnicode converts a domain or domain label to its Unicode form. For example,
|
|||
// ToUnicode("xn--bcher-kva.example.com") is "bücher.example.com", and
|
|||
// ToUnicode("golang") is "golang". If an error is encountered it will return
|
|||
// an error and a (partially) processed result.
|
|||
func (p *Profile) ToUnicode(s string) (string, error) { |
|||
pp := *p |
|||
pp.transitional = false |
|||
return pp.process(s, false) |
|||
} |
|||
|
|||
// String reports a string with a description of the profile for debugging
|
|||
// purposes. The string format may change with different versions.
|
|||
func (p *Profile) String() string { |
|||
s := "" |
|||
if p.transitional { |
|||
s = "Transitional" |
|||
} else { |
|||
s = "NonTransitional" |
|||
} |
|||
if p.useSTD3Rules { |
|||
s += ":UseSTD3Rules" |
|||
} |
|||
if p.checkHyphens { |
|||
s += ":CheckHyphens" |
|||
} |
|||
if p.checkJoiners { |
|||
s += ":CheckJoiners" |
|||
} |
|||
if p.verifyDNSLength { |
|||
s += ":VerifyDNSLength" |
|||
} |
|||
return s |
|||
} |
|||
|
|||
var ( |
|||
// Punycode is a Profile that does raw punycode processing with a minimum
|
|||
// of validation.
|
|||
Punycode *Profile = punycode |
|||
|
|||
// Lookup is the recommended profile for looking up domain names, according
|
|||
// to Section 5 of RFC 5891. The exact configuration of this profile may
|
|||
// change over time.
|
|||
Lookup *Profile = lookup |
|||
|
|||
// Display is the recommended profile for displaying domain names.
|
|||
// The configuration of this profile may change over time.
|
|||
Display *Profile = display |
|||
|
|||
// Registration is the recommended profile for checking whether a given
|
|||
// IDN is valid for registration, according to Section 4 of RFC 5891.
|
|||
Registration *Profile = registration |
|||
|
|||
punycode = &Profile{} |
|||
lookup = &Profile{options{ |
|||
transitional: transitionalLookup, |
|||
useSTD3Rules: true, |
|||
checkHyphens: true, |
|||
checkJoiners: true, |
|||
trie: trie, |
|||
fromPuny: validateFromPunycode, |
|||
mapping: validateAndMap, |
|||
bidirule: bidirule.ValidString, |
|||
}} |
|||
display = &Profile{options{ |
|||
useSTD3Rules: true, |
|||
checkHyphens: true, |
|||
checkJoiners: true, |
|||
trie: trie, |
|||
fromPuny: validateFromPunycode, |
|||
mapping: validateAndMap, |
|||
bidirule: bidirule.ValidString, |
|||
}} |
|||
registration = &Profile{options{ |
|||
useSTD3Rules: true, |
|||
verifyDNSLength: true, |
|||
checkHyphens: true, |
|||
checkJoiners: true, |
|||
trie: trie, |
|||
fromPuny: validateFromPunycode, |
|||
mapping: validateRegistration, |
|||
bidirule: bidirule.ValidString, |
|||
}} |
|||
|
|||
// TODO: profiles
|
|||
// Register: recommended for approving domain names: don't do any mappings
|
|||
// but rather reject on invalid input. Bundle or block deviation characters.
|
|||
) |
|||
|
|||
type labelError struct{ label, code_ string } |
|||
|
|||
func (e labelError) code() string { return e.code_ } |
|||
func (e labelError) Error() string { |
|||
return fmt.Sprintf("idna: invalid label %q", e.label) |
|||
} |
|||
|
|||
type runeError rune |
|||
|
|||
func (e runeError) code() string { return "P1" } |
|||
func (e runeError) Error() string { |
|||
return fmt.Sprintf("idna: disallowed rune %U", e) |
|||
} |
|||
|
|||
// process implements the algorithm described in section 4 of UTS #46,
|
|||
// see https://www.unicode.org/reports/tr46.
|
|||
func (p *Profile) process(s string, toASCII bool) (string, error) { |
|||
var err error |
|||
var isBidi bool |
|||
if p.mapping != nil { |
|||
s, isBidi, err = p.mapping(p, s) |
|||
} |
|||
// Remove leading empty labels.
|
|||
if p.removeLeadingDots { |
|||
for ; len(s) > 0 && s[0] == '.'; s = s[1:] { |
|||
} |
|||
} |
|||
// TODO: allow for a quick check of the tables data.
|
|||
// It seems like we should only create this error on ToASCII, but the
|
|||
// UTS 46 conformance tests suggests we should always check this.
|
|||
if err == nil && p.verifyDNSLength && s == "" { |
|||
err = &labelError{s, "A4"} |
|||
} |
|||
labels := labelIter{orig: s} |
|||
for ; !labels.done(); labels.next() { |
|||
label := labels.label() |
|||
if label == "" { |
|||
// Empty labels are not okay. The label iterator skips the last
|
|||
// label if it is empty.
|
|||
if err == nil && p.verifyDNSLength { |
|||
err = &labelError{s, "A4"} |
|||
} |
|||
continue |
|||
} |
|||
if strings.HasPrefix(label, acePrefix) { |
|||
u, err2 := decode(label[len(acePrefix):]) |
|||
if err2 != nil { |
|||
if err == nil { |
|||
err = err2 |
|||
} |
|||
// Spec says keep the old label.
|
|||
continue |
|||
} |
|||
isBidi = isBidi || bidirule.DirectionString(u) != bidi.LeftToRight |
|||
labels.set(u) |
|||
if err == nil && p.fromPuny != nil { |
|||
err = p.fromPuny(p, u) |
|||
} |
|||
if err == nil { |
|||
// This should be called on NonTransitional, according to the
|
|||
// spec, but that currently does not have any effect. Use the
|
|||
// original profile to preserve options.
|
|||
err = p.validateLabel(u) |
|||
} |
|||
} else if err == nil { |
|||
err = p.validateLabel(label) |
|||
} |
|||
} |
|||
if isBidi && p.bidirule != nil && err == nil { |
|||
for labels.reset(); !labels.done(); labels.next() { |
|||
if !p.bidirule(labels.label()) { |
|||
err = &labelError{s, "B"} |
|||
break |
|||
} |
|||
} |
|||
} |
|||
if toASCII { |
|||
for labels.reset(); !labels.done(); labels.next() { |
|||
label := labels.label() |
|||
if !ascii(label) { |
|||
a, err2 := encode(acePrefix, label) |
|||
if err == nil { |
|||
err = err2 |
|||
} |
|||
label = a |
|||
labels.set(a) |
|||
} |
|||
n := len(label) |
|||
if p.verifyDNSLength && err == nil && (n == 0 || n > 63) { |
|||
err = &labelError{label, "A4"} |
|||
} |
|||
} |
|||
} |
|||
s = labels.result() |
|||
if toASCII && p.verifyDNSLength && err == nil { |
|||
// Compute the length of the domain name minus the root label and its dot.
|
|||
n := len(s) |
|||
if n > 0 && s[n-1] == '.' { |
|||
n-- |
|||
} |
|||
if len(s) < 1 || n > 253 { |
|||
err = &labelError{s, "A4"} |
|||
} |
|||
} |
|||
return s, err |
|||
} |
|||
|
|||
func normalize(p *Profile, s string) (mapped string, isBidi bool, err error) { |
|||
// TODO: consider first doing a quick check to see if any of these checks
|
|||
// need to be done. This will make it slower in the general case, but
|
|||
// faster in the common case.
|
|||
mapped = norm.NFC.String(s) |
|||
isBidi = bidirule.DirectionString(mapped) == bidi.RightToLeft |
|||
return mapped, isBidi, nil |
|||
} |
|||
|
|||
func validateRegistration(p *Profile, s string) (idem string, bidi bool, err error) { |
|||
// TODO: filter need for normalization in loop below.
|
|||
if !norm.NFC.IsNormalString(s) { |
|||
return s, false, &labelError{s, "V1"} |
|||
} |
|||
for i := 0; i < len(s); { |
|||
v, sz := trie.lookupString(s[i:]) |
|||
if sz == 0 { |
|||
return s, bidi, runeError(utf8.RuneError) |
|||
} |
|||
bidi = bidi || info(v).isBidi(s[i:]) |
|||
// Copy bytes not copied so far.
|
|||
switch p.simplify(info(v).category()) { |
|||
// TODO: handle the NV8 defined in the Unicode idna data set to allow
|
|||
// for strict conformance to IDNA2008.
|
|||
case valid, deviation: |
|||
case disallowed, mapped, unknown, ignored: |
|||
r, _ := utf8.DecodeRuneInString(s[i:]) |
|||
return s, bidi, runeError(r) |
|||
} |
|||
i += sz |
|||
} |
|||
return s, bidi, nil |
|||
} |
|||
|
|||
func (c info) isBidi(s string) bool { |
|||
if !c.isMapped() { |
|||
return c&attributesMask == rtl |
|||
} |
|||
// TODO: also store bidi info for mapped data. This is possible, but a bit
|
|||
// cumbersome and not for the common case.
|
|||
p, _ := bidi.LookupString(s) |
|||
switch p.Class() { |
|||
case bidi.R, bidi.AL, bidi.AN: |
|||
return true |
|||
} |
|||
return false |
|||
} |
|||
|
|||
func validateAndMap(p *Profile, s string) (vm string, bidi bool, err error) { |
|||
var ( |
|||
b []byte |
|||
k int |
|||
) |
|||
// combinedInfoBits contains the or-ed bits of all runes. We use this
|
|||
// to derive the mayNeedNorm bit later. This may trigger normalization
|
|||
// overeagerly, but it will not do so in the common case. The end result
|
|||
// is another 10% saving on BenchmarkProfile for the common case.
|
|||
var combinedInfoBits info |
|||
for i := 0; i < len(s); { |
|||
v, sz := trie.lookupString(s[i:]) |
|||
if sz == 0 { |
|||
b = append(b, s[k:i]...) |
|||
b = append(b, "\ufffd"...) |
|||
k = len(s) |
|||
if err == nil { |
|||
err = runeError(utf8.RuneError) |
|||
} |
|||
break |
|||
} |
|||
combinedInfoBits |= info(v) |
|||
bidi = bidi || info(v).isBidi(s[i:]) |
|||
start := i |
|||
i += sz |
|||
// Copy bytes not copied so far.
|
|||
switch p.simplify(info(v).category()) { |
|||
case valid: |
|||
continue |
|||
case disallowed: |
|||
if err == nil { |
|||
r, _ := utf8.DecodeRuneInString(s[start:]) |
|||
err = runeError(r) |
|||
} |
|||
continue |
|||
case mapped, deviation: |
|||
b = append(b, s[k:start]...) |
|||
b = info(v).appendMapping(b, s[start:i]) |
|||
case ignored: |
|||
b = append(b, s[k:start]...) |
|||
// drop the rune
|
|||
case unknown: |
|||
b = append(b, s[k:start]...) |
|||
b = append(b, "\ufffd"...) |
|||
} |
|||
k = i |
|||
} |
|||
if k == 0 { |
|||
// No changes so far.
|
|||
if combinedInfoBits&mayNeedNorm != 0 { |
|||
s = norm.NFC.String(s) |
|||
} |
|||
} else { |
|||
b = append(b, s[k:]...) |
|||
if norm.NFC.QuickSpan(b) != len(b) { |
|||
b = norm.NFC.Bytes(b) |
|||
} |
|||
// TODO: the punycode converters require strings as input.
|
|||
s = string(b) |
|||
} |
|||
return s, bidi, err |
|||
} |
|||
|
|||
// A labelIter allows iterating over domain name labels.
|
|||
type labelIter struct { |
|||
orig string |
|||
slice []string |
|||
curStart int |
|||
curEnd int |
|||
i int |
|||
} |
|||
|
|||
func (l *labelIter) reset() { |
|||
l.curStart = 0 |
|||
l.curEnd = 0 |
|||
l.i = 0 |
|||
} |
|||
|
|||
func (l *labelIter) done() bool { |
|||
return l.curStart >= len(l.orig) |
|||
} |
|||
|
|||
func (l *labelIter) result() string { |
|||
if l.slice != nil { |
|||
return strings.Join(l.slice, ".") |
|||
} |
|||
return l.orig |
|||
} |
|||
|
|||
func (l *labelIter) label() string { |
|||
if l.slice != nil { |
|||
return l.slice[l.i] |
|||
} |
|||
p := strings.IndexByte(l.orig[l.curStart:], '.') |
|||
l.curEnd = l.curStart + p |
|||
if p == -1 { |
|||
l.curEnd = len(l.orig) |
|||
} |
|||
return l.orig[l.curStart:l.curEnd] |
|||
} |
|||
|
|||
// next sets the value to the next label. It skips the last label if it is empty.
|
|||
func (l *labelIter) next() { |
|||
l.i++ |
|||
if l.slice != nil { |
|||
if l.i >= len(l.slice) || l.i == len(l.slice)-1 && l.slice[l.i] == "" { |
|||
l.curStart = len(l.orig) |
|||
} |
|||
} else { |
|||
l.curStart = l.curEnd + 1 |
|||
if l.curStart == len(l.orig)-1 && l.orig[l.curStart] == '.' { |
|||
l.curStart = len(l.orig) |
|||
} |
|||
} |
|||
} |
|||
|
|||
func (l *labelIter) set(s string) { |
|||
if l.slice == nil { |
|||
l.slice = strings.Split(l.orig, ".") |
|||
} |
|||
l.slice[l.i] = s |
|||
} |
|||
|
|||
// acePrefix is the ASCII Compatible Encoding prefix.
|
|||
const acePrefix = "xn--" |
|||
|
|||
func (p *Profile) simplify(cat category) category { |
|||
switch cat { |
|||
case disallowedSTD3Mapped: |
|||
if p.useSTD3Rules { |
|||
cat = disallowed |
|||
} else { |
|||
cat = mapped |
|||
} |
|||
case disallowedSTD3Valid: |
|||
if p.useSTD3Rules { |
|||
cat = disallowed |
|||
} else { |
|||
cat = valid |
|||
} |
|||
case deviation: |
|||
if !p.transitional { |
|||
cat = valid |
|||
} |
|||
case validNV8, validXV8: |
|||
// TODO: handle V2008
|
|||
cat = valid |
|||
} |
|||
return cat |
|||
} |
|||
|
|||
func validateFromPunycode(p *Profile, s string) error { |
|||
if !norm.NFC.IsNormalString(s) { |
|||
return &labelError{s, "V1"} |
|||
} |
|||
// TODO: detect whether string may have to be normalized in the following
|
|||
// loop.
|
|||
for i := 0; i < len(s); { |
|||
v, sz := trie.lookupString(s[i:]) |
|||
if sz == 0 { |
|||
return runeError(utf8.RuneError) |
|||
} |
|||
if c := p.simplify(info(v).category()); c != valid && c != deviation { |
|||
return &labelError{s, "V6"} |
|||
} |
|||
i += sz |
|||
} |
|||
return nil |
|||
} |
|||
|
|||
const ( |
|||
zwnj = "\u200c" |
|||
zwj = "\u200d" |
|||
) |
|||
|
|||
type joinState int8 |
|||
|
|||
const ( |
|||
stateStart joinState = iota |
|||
stateVirama |
|||
stateBefore |
|||
stateBeforeVirama |
|||
stateAfter |
|||
stateFAIL |
|||
) |
|||
|
|||
var joinStates = [][numJoinTypes]joinState{ |
|||
stateStart: { |
|||
joiningL: stateBefore, |
|||
joiningD: stateBefore, |
|||
joinZWNJ: stateFAIL, |
|||
joinZWJ: stateFAIL, |
|||
joinVirama: stateVirama, |
|||
}, |
|||
stateVirama: { |
|||
joiningL: stateBefore, |
|||
joiningD: stateBefore, |
|||
}, |
|||
stateBefore: { |
|||
joiningL: stateBefore, |
|||
joiningD: stateBefore, |
|||
joiningT: stateBefore, |
|||
joinZWNJ: stateAfter, |
|||
joinZWJ: stateFAIL, |
|||
joinVirama: stateBeforeVirama, |
|||
}, |
|||
stateBeforeVirama: { |
|||
joiningL: stateBefore, |
|||
joiningD: stateBefore, |
|||
joiningT: stateBefore, |
|||
}, |
|||
stateAfter: { |
|||
joiningL: stateFAIL, |
|||
joiningD: stateBefore, |
|||
joiningT: stateAfter, |
|||
joiningR: stateStart, |
|||
joinZWNJ: stateFAIL, |
|||
joinZWJ: stateFAIL, |
|||
joinVirama: stateAfter, // no-op as we can't accept joiners here
|
|||
}, |
|||
stateFAIL: { |
|||
0: stateFAIL, |
|||
joiningL: stateFAIL, |
|||
joiningD: stateFAIL, |
|||
joiningT: stateFAIL, |
|||
joiningR: stateFAIL, |
|||
joinZWNJ: stateFAIL, |
|||
joinZWJ: stateFAIL, |
|||
joinVirama: stateFAIL, |
|||
}, |
|||
} |
|||
|
|||
// validateLabel validates the criteria from Section 4.1. Item 1, 4, and 6 are
|
|||
// already implicitly satisfied by the overall implementation.
|
|||
func (p *Profile) validateLabel(s string) (err error) { |
|||
if s == "" { |
|||
if p.verifyDNSLength { |
|||
return &labelError{s, "A4"} |
|||
} |
|||
return nil |
|||
} |
|||
if p.checkHyphens { |
|||
if len(s) > 4 && s[2] == '-' && s[3] == '-' { |
|||
return &labelError{s, "V2"} |
|||
} |
|||
if s[0] == '-' || s[len(s)-1] == '-' { |
|||
return &labelError{s, "V3"} |
|||
} |
|||
} |
|||
if !p.checkJoiners { |
|||
return nil |
|||
} |
|||
trie := p.trie // p.checkJoiners is only set if trie is set.
|
|||
// TODO: merge the use of this in the trie.
|
|||
v, sz := trie.lookupString(s) |
|||
x := info(v) |
|||
if x.isModifier() { |
|||
return &labelError{s, "V5"} |
|||
} |
|||
// Quickly return in the absence of zero-width (non) joiners.
|
|||
if strings.Index(s, zwj) == -1 && strings.Index(s, zwnj) == -1 { |
|||
return nil |
|||
} |
|||
st := stateStart |
|||
for i := 0; ; { |
|||
jt := x.joinType() |
|||
if s[i:i+sz] == zwj { |
|||
jt = joinZWJ |
|||
} else if s[i:i+sz] == zwnj { |
|||
jt = joinZWNJ |
|||
} |
|||
st = joinStates[st][jt] |
|||
if x.isViramaModifier() { |
|||
st = joinStates[st][joinVirama] |
|||
} |
|||
if i += sz; i == len(s) { |
|||
break |
|||
} |
|||
v, sz = trie.lookupString(s[i:]) |
|||
x = info(v) |
|||
} |
|||
if st == stateFAIL || st == stateAfter { |
|||
return &labelError{s, "C"} |
|||
} |
|||
return nil |
|||
} |
|||
|
|||
func ascii(s string) bool { |
|||
for i := 0; i < len(s); i++ { |
|||
if s[i] >= utf8.RuneSelf { |
|||
return false |
|||
} |
|||
} |
|||
return true |
|||
} |
@ -0,0 +1,718 @@ |
|||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
|||
|
|||
// Copyright 2016 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.
|
|||
|
|||
//go:build !go1.10
|
|||
// +build !go1.10
|
|||
|
|||
// Package idna implements IDNA2008 using the compatibility processing
|
|||
// defined by UTS (Unicode Technical Standard) #46, which defines a standard to
|
|||
// deal with the transition from IDNA2003.
|
|||
//
|
|||
// IDNA2008 (Internationalized Domain Names for Applications), is defined in RFC
|
|||
// 5890, RFC 5891, RFC 5892, RFC 5893 and RFC 5894.
|
|||
// UTS #46 is defined in https://www.unicode.org/reports/tr46.
|
|||
// See https://unicode.org/cldr/utility/idna.jsp for a visualization of the
|
|||
// differences between these two standards.
|
|||
package idna // import "golang.org/x/net/idna"
|
|||
|
|||
import ( |
|||
"fmt" |
|||
"strings" |
|||
"unicode/utf8" |
|||
|
|||
"golang.org/x/text/secure/bidirule" |
|||
"golang.org/x/text/unicode/norm" |
|||
) |
|||
|
|||
// NOTE: Unlike common practice in Go APIs, the functions will return a
|
|||
// sanitized domain name in case of errors. Browsers sometimes use a partially
|
|||
// evaluated string as lookup.
|
|||
// TODO: the current error handling is, in my opinion, the least opinionated.
|
|||
// Other strategies are also viable, though:
|
|||
// Option 1) Return an empty string in case of error, but allow the user to
|
|||
// specify explicitly which errors to ignore.
|
|||
// Option 2) Return the partially evaluated string if it is itself a valid
|
|||
// string, otherwise return the empty string in case of error.
|
|||
// Option 3) Option 1 and 2.
|
|||
// Option 4) Always return an empty string for now and implement Option 1 as
|
|||
// needed, and document that the return string may not be empty in case of
|
|||
// error in the future.
|
|||
// I think Option 1 is best, but it is quite opinionated.
|
|||
|
|||
// ToASCII is a wrapper for Punycode.ToASCII.
|
|||
func ToASCII(s string) (string, error) { |
|||
return Punycode.process(s, true) |
|||
} |
|||
|
|||
// ToUnicode is a wrapper for Punycode.ToUnicode.
|
|||
func ToUnicode(s string) (string, error) { |
|||
return Punycode.process(s, false) |
|||
} |
|||
|
|||
// An Option configures a Profile at creation time.
|
|||
type Option func(*options) |
|||
|
|||
// Transitional sets a Profile to use the Transitional mapping as defined in UTS
|
|||
// #46. This will cause, for example, "ß" to be mapped to "ss". Using the
|
|||
// transitional mapping provides a compromise between IDNA2003 and IDNA2008
|
|||
// compatibility. It is used by some browsers when resolving domain names. This
|
|||
// option is only meaningful if combined with MapForLookup.
|
|||
func Transitional(transitional bool) Option { |
|||
return func(o *options) { o.transitional = transitional } |
|||
} |
|||
|
|||
// VerifyDNSLength sets whether a Profile should fail if any of the IDN parts
|
|||
// are longer than allowed by the RFC.
|
|||
//
|
|||
// This option corresponds to the VerifyDnsLength flag in UTS #46.
|
|||
func VerifyDNSLength(verify bool) Option { |
|||
return func(o *options) { o.verifyDNSLength = verify } |
|||
} |
|||
|
|||
// RemoveLeadingDots removes leading label separators. Leading runes that map to
|
|||
// dots, such as U+3002 IDEOGRAPHIC FULL STOP, are removed as well.
|
|||
func RemoveLeadingDots(remove bool) Option { |
|||
return func(o *options) { o.removeLeadingDots = remove } |
|||
} |
|||
|
|||
// ValidateLabels sets whether to check the mandatory label validation criteria
|
|||
// as defined in Section 5.4 of RFC 5891. This includes testing for correct use
|
|||
// of hyphens ('-'), normalization, validity of runes, and the context rules.
|
|||
// In particular, ValidateLabels also sets the CheckHyphens and CheckJoiners flags
|
|||
// in UTS #46.
|
|||
func ValidateLabels(enable bool) Option { |
|||
return func(o *options) { |
|||
// Don't override existing mappings, but set one that at least checks
|
|||
// normalization if it is not set.
|
|||
if o.mapping == nil && enable { |
|||
o.mapping = normalize |
|||
} |
|||
o.trie = trie |
|||
o.checkJoiners = enable |
|||
o.checkHyphens = enable |
|||
if enable { |
|||
o.fromPuny = validateFromPunycode |
|||
} else { |
|||
o.fromPuny = nil |
|||
} |
|||
} |
|||
} |
|||
|
|||
// CheckHyphens sets whether to check for correct use of hyphens ('-') in
|
|||
// labels. Most web browsers do not have this option set, since labels such as
|
|||
// "r3---sn-apo3qvuoxuxbt-j5pe" are in common use.
|
|||
//
|
|||
// This option corresponds to the CheckHyphens flag in UTS #46.
|
|||
func CheckHyphens(enable bool) Option { |
|||
return func(o *options) { o.checkHyphens = enable } |
|||
} |
|||
|
|||
// CheckJoiners sets whether to check the ContextJ rules as defined in Appendix
|
|||
// A of RFC 5892, concerning the use of joiner runes.
|
|||
//
|
|||
// This option corresponds to the CheckJoiners flag in UTS #46.
|
|||
func CheckJoiners(enable bool) Option { |
|||
return func(o *options) { |
|||
o.trie = trie |
|||
o.checkJoiners = enable |
|||
} |
|||
} |
|||
|
|||
// StrictDomainName limits the set of permissable ASCII characters to those
|
|||
// allowed in domain names as defined in RFC 1034 (A-Z, a-z, 0-9 and the
|
|||
// hyphen). This is set by default for MapForLookup and ValidateForRegistration,
|
|||
// but is only useful if ValidateLabels is set.
|
|||
//
|
|||
// This option is useful, for instance, for browsers that allow characters
|
|||
// outside this range, for example a '_' (U+005F LOW LINE). See
|
|||
// http://www.rfc-editor.org/std/std3.txt for more details.
|
|||
//
|
|||
// This option corresponds to the UseSTD3ASCIIRules flag in UTS #46.
|
|||
func StrictDomainName(use bool) Option { |
|||
return func(o *options) { o.useSTD3Rules = use } |
|||
} |
|||
|
|||
// NOTE: the following options pull in tables. The tables should not be linked
|
|||
// in as long as the options are not used.
|
|||
|
|||
// BidiRule enables the Bidi rule as defined in RFC 5893. Any application
|
|||
// that relies on proper validation of labels should include this rule.
|
|||
//
|
|||
// This option corresponds to the CheckBidi flag in UTS #46.
|
|||
func BidiRule() Option { |
|||
return func(o *options) { o.bidirule = bidirule.ValidString } |
|||
} |
|||
|
|||
// ValidateForRegistration sets validation options to verify that a given IDN is
|
|||
// properly formatted for registration as defined by Section 4 of RFC 5891.
|
|||
func ValidateForRegistration() Option { |
|||
return func(o *options) { |
|||
o.mapping = validateRegistration |
|||
StrictDomainName(true)(o) |
|||
ValidateLabels(true)(o) |
|||
VerifyDNSLength(true)(o) |
|||
BidiRule()(o) |
|||
} |
|||
} |
|||
|
|||
// MapForLookup sets validation and mapping options such that a given IDN is
|
|||
// transformed for domain name lookup according to the requirements set out in
|
|||
// Section 5 of RFC 5891. The mappings follow the recommendations of RFC 5894,
|
|||
// RFC 5895 and UTS 46. It does not add the Bidi Rule. Use the BidiRule option
|
|||
// to add this check.
|
|||
//
|
|||
// The mappings include normalization and mapping case, width and other
|
|||
// compatibility mappings.
|
|||
func MapForLookup() Option { |
|||
return func(o *options) { |
|||
o.mapping = validateAndMap |
|||
StrictDomainName(true)(o) |
|||
ValidateLabels(true)(o) |
|||
RemoveLeadingDots(true)(o) |
|||
} |
|||
} |
|||
|
|||
type options struct { |
|||
transitional bool |
|||
useSTD3Rules bool |
|||
checkHyphens bool |
|||
checkJoiners bool |
|||
verifyDNSLength bool |
|||
removeLeadingDots bool |
|||
|
|||
trie *idnaTrie |
|||
|
|||
// fromPuny calls validation rules when converting A-labels to U-labels.
|
|||
fromPuny func(p *Profile, s string) error |
|||
|
|||
// mapping implements a validation and mapping step as defined in RFC 5895
|
|||
// or UTS 46, tailored to, for example, domain registration or lookup.
|
|||
mapping func(p *Profile, s string) (string, error) |
|||
|
|||
// bidirule, if specified, checks whether s conforms to the Bidi Rule
|
|||
// defined in RFC 5893.
|
|||
bidirule func(s string) bool |
|||
} |
|||
|
|||
// A Profile defines the configuration of a IDNA mapper.
|
|||
type Profile struct { |
|||
options |
|||
} |
|||
|
|||
func apply(o *options, opts []Option) { |
|||
for _, f := range opts { |
|||
f(o) |
|||
} |
|||
} |
|||
|
|||
// New creates a new Profile.
|
|||
//
|
|||
// With no options, the returned Profile is the most permissive and equals the
|
|||
// Punycode Profile. Options can be passed to further restrict the Profile. The
|
|||
// MapForLookup and ValidateForRegistration options set a collection of options,
|
|||
// for lookup and registration purposes respectively, which can be tailored by
|
|||
// adding more fine-grained options, where later options override earlier
|
|||
// options.
|
|||
func New(o ...Option) *Profile { |
|||
p := &Profile{} |
|||
apply(&p.options, o) |
|||
return p |
|||
} |
|||
|
|||
// ToASCII converts a domain or domain label to its ASCII form. For example,
|
|||
// ToASCII("bücher.example.com") is "xn--bcher-kva.example.com", and
|
|||
// ToASCII("golang") is "golang". If an error is encountered it will return
|
|||
// an error and a (partially) processed result.
|
|||
func (p *Profile) ToASCII(s string) (string, error) { |
|||
return p.process(s, true) |
|||
} |
|||
|
|||
// ToUnicode converts a domain or domain label to its Unicode form. For example,
|
|||
// ToUnicode("xn--bcher-kva.example.com") is "bücher.example.com", and
|
|||
// ToUnicode("golang") is "golang". If an error is encountered it will return
|
|||
// an error and a (partially) processed result.
|
|||
func (p *Profile) ToUnicode(s string) (string, error) { |
|||
pp := *p |
|||
pp.transitional = false |
|||
return pp.process(s, false) |
|||
} |
|||
|
|||
// String reports a string with a description of the profile for debugging
|
|||
// purposes. The string format may change with different versions.
|
|||
func (p *Profile) String() string { |
|||
s := "" |
|||
if p.transitional { |
|||
s = "Transitional" |
|||
} else { |
|||
s = "NonTransitional" |
|||
} |
|||
if p.useSTD3Rules { |
|||
s += ":UseSTD3Rules" |
|||
} |
|||
if p.checkHyphens { |
|||
s += ":CheckHyphens" |
|||
} |
|||
if p.checkJoiners { |
|||
s += ":CheckJoiners" |
|||
} |
|||
if p.verifyDNSLength { |
|||
s += ":VerifyDNSLength" |
|||
} |
|||
return s |
|||
} |
|||
|
|||
var ( |
|||
// Punycode is a Profile that does raw punycode processing with a minimum
|
|||
// of validation.
|
|||
Punycode *Profile = punycode |
|||
|
|||
// Lookup is the recommended profile for looking up domain names, according
|
|||
// to Section 5 of RFC 5891. The exact configuration of this profile may
|
|||
// change over time.
|
|||
Lookup *Profile = lookup |
|||
|
|||
// Display is the recommended profile for displaying domain names.
|
|||
// The configuration of this profile may change over time.
|
|||
Display *Profile = display |
|||
|
|||
// Registration is the recommended profile for checking whether a given
|
|||
// IDN is valid for registration, according to Section 4 of RFC 5891.
|
|||
Registration *Profile = registration |
|||
|
|||
punycode = &Profile{} |
|||
lookup = &Profile{options{ |
|||
transitional: true, |
|||
removeLeadingDots: true, |
|||
useSTD3Rules: true, |
|||
checkHyphens: true, |
|||
checkJoiners: true, |
|||
trie: trie, |
|||
fromPuny: validateFromPunycode, |
|||
mapping: validateAndMap, |
|||
bidirule: bidirule.ValidString, |
|||
}} |
|||
display = &Profile{options{ |
|||
useSTD3Rules: true, |
|||
removeLeadingDots: true, |
|||
checkHyphens: true, |
|||
checkJoiners: true, |
|||
trie: trie, |
|||
fromPuny: validateFromPunycode, |
|||
mapping: validateAndMap, |
|||
bidirule: bidirule.ValidString, |
|||
}} |
|||
registration = &Profile{options{ |
|||
useSTD3Rules: true, |
|||
verifyDNSLength: true, |
|||
checkHyphens: true, |
|||
checkJoiners: true, |
|||
trie: trie, |
|||
fromPuny: validateFromPunycode, |
|||
mapping: validateRegistration, |
|||
bidirule: bidirule.ValidString, |
|||
}} |
|||
|
|||
// TODO: profiles
|
|||
// Register: recommended for approving domain names: don't do any mappings
|
|||
// but rather reject on invalid input. Bundle or block deviation characters.
|
|||
) |
|||
|
|||
type labelError struct{ label, code_ string } |
|||
|
|||
func (e labelError) code() string { return e.code_ } |
|||
func (e labelError) Error() string { |
|||
return fmt.Sprintf("idna: invalid label %q", e.label) |
|||
} |
|||
|
|||
type runeError rune |
|||
|
|||
func (e runeError) code() string { return "P1" } |
|||
func (e runeError) Error() string { |
|||
return fmt.Sprintf("idna: disallowed rune %U", e) |
|||
} |
|||
|
|||
// process implements the algorithm described in section 4 of UTS #46,
|
|||
// see https://www.unicode.org/reports/tr46.
|
|||
func (p *Profile) process(s string, toASCII bool) (string, error) { |
|||
var err error |
|||
if p.mapping != nil { |
|||
s, err = p.mapping(p, s) |
|||
} |
|||
// Remove leading empty labels.
|
|||
if p.removeLeadingDots { |
|||
for ; len(s) > 0 && s[0] == '.'; s = s[1:] { |
|||
} |
|||
} |
|||
// It seems like we should only create this error on ToASCII, but the
|
|||
// UTS 46 conformance tests suggests we should always check this.
|
|||
if err == nil && p.verifyDNSLength && s == "" { |
|||
err = &labelError{s, "A4"} |
|||
} |
|||
labels := labelIter{orig: s} |
|||
for ; !labels.done(); labels.next() { |
|||
label := labels.label() |
|||
if label == "" { |
|||
// Empty labels are not okay. The label iterator skips the last
|
|||
// label if it is empty.
|
|||
if err == nil && p.verifyDNSLength { |
|||
err = &labelError{s, "A4"} |
|||
} |
|||
continue |
|||
} |
|||
if strings.HasPrefix(label, acePrefix) { |
|||
u, err2 := decode(label[len(acePrefix):]) |
|||
if err2 != nil { |
|||
if err == nil { |
|||
err = err2 |
|||
} |
|||
// Spec says keep the old label.
|
|||
continue |
|||
} |
|||
labels.set(u) |
|||
if err == nil && p.fromPuny != nil { |
|||
err = p.fromPuny(p, u) |
|||
} |
|||
if err == nil { |
|||
// This should be called on NonTransitional, according to the
|
|||
// spec, but that currently does not have any effect. Use the
|
|||
// original profile to preserve options.
|
|||
err = p.validateLabel(u) |
|||
} |
|||
} else if err == nil { |
|||
err = p.validateLabel(label) |
|||
} |
|||
} |
|||
if toASCII { |
|||
for labels.reset(); !labels.done(); labels.next() { |
|||
label := labels.label() |
|||
if !ascii(label) { |
|||
a, err2 := encode(acePrefix, label) |
|||
if err == nil { |
|||
err = err2 |
|||
} |
|||
label = a |
|||
labels.set(a) |
|||
} |
|||
n := len(label) |
|||
if p.verifyDNSLength && err == nil && (n == 0 || n > 63) { |
|||
err = &labelError{label, "A4"} |
|||
} |
|||
} |
|||
} |
|||
s = labels.result() |
|||
if toASCII && p.verifyDNSLength && err == nil { |
|||
// Compute the length of the domain name minus the root label and its dot.
|
|||
n := len(s) |
|||
if n > 0 && s[n-1] == '.' { |
|||
n-- |
|||
} |
|||
if len(s) < 1 || n > 253 { |
|||
err = &labelError{s, "A4"} |
|||
} |
|||
} |
|||
return s, err |
|||
} |
|||
|
|||
func normalize(p *Profile, s string) (string, error) { |
|||
return norm.NFC.String(s), nil |
|||
} |
|||
|
|||
func validateRegistration(p *Profile, s string) (string, error) { |
|||
if !norm.NFC.IsNormalString(s) { |
|||
return s, &labelError{s, "V1"} |
|||
} |
|||
for i := 0; i < len(s); { |
|||
v, sz := trie.lookupString(s[i:]) |
|||
// Copy bytes not copied so far.
|
|||
switch p.simplify(info(v).category()) { |
|||
// TODO: handle the NV8 defined in the Unicode idna data set to allow
|
|||
// for strict conformance to IDNA2008.
|
|||
case valid, deviation: |
|||
case disallowed, mapped, unknown, ignored: |
|||
r, _ := utf8.DecodeRuneInString(s[i:]) |
|||
return s, runeError(r) |
|||
} |
|||
i += sz |
|||
} |
|||
return s, nil |
|||
} |
|||
|
|||
func validateAndMap(p *Profile, s string) (string, error) { |
|||
var ( |
|||
err error |
|||
b []byte |
|||
k int |
|||
) |
|||
for i := 0; i < len(s); { |
|||
v, sz := trie.lookupString(s[i:]) |
|||
start := i |
|||
i += sz |
|||
// Copy bytes not copied so far.
|
|||
switch p.simplify(info(v).category()) { |
|||
case valid: |
|||
continue |
|||
case disallowed: |
|||
if err == nil { |
|||
r, _ := utf8.DecodeRuneInString(s[start:]) |
|||
err = runeError(r) |
|||
} |
|||
continue |
|||
case mapped, deviation: |
|||
b = append(b, s[k:start]...) |
|||
b = info(v).appendMapping(b, s[start:i]) |
|||
case ignored: |
|||
b = append(b, s[k:start]...) |
|||
// drop the rune
|
|||
case unknown: |
|||
b = append(b, s[k:start]...) |
|||
b = append(b, "\ufffd"...) |
|||
} |
|||
k = i |
|||
} |
|||
if k == 0 { |
|||
// No changes so far.
|
|||
s = norm.NFC.String(s) |
|||
} else { |
|||
b = append(b, s[k:]...) |
|||
if norm.NFC.QuickSpan(b) != len(b) { |
|||
b = norm.NFC.Bytes(b) |
|||
} |
|||
// TODO: the punycode converters require strings as input.
|
|||
s = string(b) |
|||
} |
|||
return s, err |
|||
} |
|||
|
|||
// A labelIter allows iterating over domain name labels.
|
|||
type labelIter struct { |
|||
orig string |
|||
slice []string |
|||
curStart int |
|||
curEnd int |
|||
i int |
|||
} |
|||
|
|||
func (l *labelIter) reset() { |
|||
l.curStart = 0 |
|||
l.curEnd = 0 |
|||
l.i = 0 |
|||
} |
|||
|
|||
func (l *labelIter) done() bool { |
|||
return l.curStart >= len(l.orig) |
|||
} |
|||
|
|||
func (l *labelIter) result() string { |
|||
if l.slice != nil { |
|||
return strings.Join(l.slice, ".") |
|||
} |
|||
return l.orig |
|||
} |
|||
|
|||
func (l *labelIter) label() string { |
|||
if l.slice != nil { |
|||
return l.slice[l.i] |
|||
} |
|||
p := strings.IndexByte(l.orig[l.curStart:], '.') |
|||
l.curEnd = l.curStart + p |
|||
if p == -1 { |
|||
l.curEnd = len(l.orig) |
|||
} |
|||
return l.orig[l.curStart:l.curEnd] |
|||
} |
|||
|
|||
// next sets the value to the next label. It skips the last label if it is empty.
|
|||
func (l *labelIter) next() { |
|||
l.i++ |
|||
if l.slice != nil { |
|||
if l.i >= len(l.slice) || l.i == len(l.slice)-1 && l.slice[l.i] == "" { |
|||
l.curStart = len(l.orig) |
|||
} |
|||
} else { |
|||
l.curStart = l.curEnd + 1 |
|||
if l.curStart == len(l.orig)-1 && l.orig[l.curStart] == '.' { |
|||
l.curStart = len(l.orig) |
|||
} |
|||
} |
|||
} |
|||
|
|||
func (l *labelIter) set(s string) { |
|||
if l.slice == nil { |
|||
l.slice = strings.Split(l.orig, ".") |
|||
} |
|||
l.slice[l.i] = s |
|||
} |
|||
|
|||
// acePrefix is the ASCII Compatible Encoding prefix.
|
|||
const acePrefix = "xn--" |
|||
|
|||
func (p *Profile) simplify(cat category) category { |
|||
switch cat { |
|||
case disallowedSTD3Mapped: |
|||
if p.useSTD3Rules { |
|||
cat = disallowed |
|||
} else { |
|||
cat = mapped |
|||
} |
|||
case disallowedSTD3Valid: |
|||
if p.useSTD3Rules { |
|||
cat = disallowed |
|||
} else { |
|||
cat = valid |
|||
} |
|||
case deviation: |
|||
if !p.transitional { |
|||
cat = valid |
|||
} |
|||
case validNV8, validXV8: |
|||
// TODO: handle V2008
|
|||
cat = valid |
|||
} |
|||
return cat |
|||
} |
|||
|
|||
func validateFromPunycode(p *Profile, s string) error { |
|||
if !norm.NFC.IsNormalString(s) { |
|||
return &labelError{s, "V1"} |
|||
} |
|||
for i := 0; i < len(s); { |
|||
v, sz := trie.lookupString(s[i:]) |
|||
if c := p.simplify(info(v).category()); c != valid && c != deviation { |
|||
return &labelError{s, "V6"} |
|||
} |
|||
i += sz |
|||
} |
|||
return nil |
|||
} |
|||
|
|||
const ( |
|||
zwnj = "\u200c" |
|||
zwj = "\u200d" |
|||
) |
|||
|
|||
type joinState int8 |
|||
|
|||
const ( |
|||
stateStart joinState = iota |
|||
stateVirama |
|||
stateBefore |
|||
stateBeforeVirama |
|||
stateAfter |
|||
stateFAIL |
|||
) |
|||
|
|||
var joinStates = [][numJoinTypes]joinState{ |
|||
stateStart: { |
|||
joiningL: stateBefore, |
|||
joiningD: stateBefore, |
|||
joinZWNJ: stateFAIL, |
|||
joinZWJ: stateFAIL, |
|||
joinVirama: stateVirama, |
|||
}, |
|||
stateVirama: { |
|||
joiningL: stateBefore, |
|||
joiningD: stateBefore, |
|||
}, |
|||
stateBefore: { |
|||
joiningL: stateBefore, |
|||
joiningD: stateBefore, |
|||
joiningT: stateBefore, |
|||
joinZWNJ: stateAfter, |
|||
joinZWJ: stateFAIL, |
|||
joinVirama: stateBeforeVirama, |
|||
}, |
|||
stateBeforeVirama: { |
|||
joiningL: stateBefore, |
|||
joiningD: stateBefore, |
|||
joiningT: stateBefore, |
|||
}, |
|||
stateAfter: { |
|||
joiningL: stateFAIL, |
|||
joiningD: stateBefore, |
|||
joiningT: stateAfter, |
|||
joiningR: stateStart, |
|||
joinZWNJ: stateFAIL, |
|||
joinZWJ: stateFAIL, |
|||
joinVirama: stateAfter, // no-op as we can't accept joiners here
|
|||
}, |
|||
stateFAIL: { |
|||
0: stateFAIL, |
|||
joiningL: stateFAIL, |
|||
joiningD: stateFAIL, |
|||
joiningT: stateFAIL, |
|||
joiningR: stateFAIL, |
|||
joinZWNJ: stateFAIL, |
|||
joinZWJ: stateFAIL, |
|||
joinVirama: stateFAIL, |
|||
}, |
|||
} |
|||
|
|||
// validateLabel validates the criteria from Section 4.1. Item 1, 4, and 6 are
|
|||
// already implicitly satisfied by the overall implementation.
|
|||
func (p *Profile) validateLabel(s string) error { |
|||
if s == "" { |
|||
if p.verifyDNSLength { |
|||
return &labelError{s, "A4"} |
|||
} |
|||
return nil |
|||
} |
|||
if p.bidirule != nil && !p.bidirule(s) { |
|||
return &labelError{s, "B"} |
|||
} |
|||
if p.checkHyphens { |
|||
if len(s) > 4 && s[2] == '-' && s[3] == '-' { |
|||
return &labelError{s, "V2"} |
|||
} |
|||
if s[0] == '-' || s[len(s)-1] == '-' { |
|||
return &labelError{s, "V3"} |
|||
} |
|||
} |
|||
if !p.checkJoiners { |
|||
return nil |
|||
} |
|||
trie := p.trie // p.checkJoiners is only set if trie is set.
|
|||
// TODO: merge the use of this in the trie.
|
|||
v, sz := trie.lookupString(s) |
|||
x := info(v) |
|||
if x.isModifier() { |
|||
return &labelError{s, "V5"} |
|||
} |
|||
// Quickly return in the absence of zero-width (non) joiners.
|
|||
if strings.Index(s, zwj) == -1 && strings.Index(s, zwnj) == -1 { |
|||
return nil |
|||
} |
|||
st := stateStart |
|||
for i := 0; ; { |
|||
jt := x.joinType() |
|||
if s[i:i+sz] == zwj { |
|||
jt = joinZWJ |
|||
} else if s[i:i+sz] == zwnj { |
|||
jt = joinZWNJ |
|||
} |
|||
st = joinStates[st][jt] |
|||
if x.isViramaModifier() { |
|||
st = joinStates[st][joinVirama] |
|||
} |
|||
if i += sz; i == len(s) { |
|||
break |
|||
} |
|||
v, sz = trie.lookupString(s[i:]) |
|||
x = info(v) |
|||
} |
|||
if st == stateFAIL || st == stateAfter { |
|||
return &labelError{s, "C"} |
|||
} |
|||
return nil |
|||
} |
|||
|
|||
func ascii(s string) bool { |
|||
for i := 0; i < len(s); i++ { |
|||
if s[i] >= utf8.RuneSelf { |
|||
return false |
|||
} |
|||
} |
|||
return true |
|||
} |
@ -0,0 +1,12 @@ |
|||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
|||
|
|||
// Copyright 2021 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.
|
|||
|
|||
//go:build !go1.18
|
|||
// +build !go1.18
|
|||
|
|||
package idna |
|||
|
|||
const transitionalLookup = true |
@ -0,0 +1,217 @@ |
|||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
|||
|
|||
// Copyright 2016 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 idna |
|||
|
|||
// This file implements the Punycode algorithm from RFC 3492.
|
|||
|
|||
import ( |
|||
"math" |
|||
"strings" |
|||
"unicode/utf8" |
|||
) |
|||
|
|||
// These parameter values are specified in section 5.
|
|||
//
|
|||
// All computation is done with int32s, so that overflow behavior is identical
|
|||
// regardless of whether int is 32-bit or 64-bit.
|
|||
const ( |
|||
base int32 = 36 |
|||
damp int32 = 700 |
|||
initialBias int32 = 72 |
|||
initialN int32 = 128 |
|||
skew int32 = 38 |
|||
tmax int32 = 26 |
|||
tmin int32 = 1 |
|||
) |
|||
|
|||
func punyError(s string) error { return &labelError{s, "A3"} } |
|||
|
|||
// decode decodes a string as specified in section 6.2.
|
|||
func decode(encoded string) (string, error) { |
|||
if encoded == "" { |
|||
return "", nil |
|||
} |
|||
pos := 1 + strings.LastIndex(encoded, "-") |
|||
if pos == 1 { |
|||
return "", punyError(encoded) |
|||
} |
|||
if pos == len(encoded) { |
|||
return encoded[:len(encoded)-1], nil |
|||
} |
|||
output := make([]rune, 0, len(encoded)) |
|||
if pos != 0 { |
|||
for _, r := range encoded[:pos-1] { |
|||
output = append(output, r) |
|||
} |
|||
} |
|||
i, n, bias := int32(0), initialN, initialBias |
|||
overflow := false |
|||
for pos < len(encoded) { |
|||
oldI, w := i, int32(1) |
|||
for k := base; ; k += base { |
|||
if pos == len(encoded) { |
|||
return "", punyError(encoded) |
|||
} |
|||
digit, ok := decodeDigit(encoded[pos]) |
|||
if !ok { |
|||
return "", punyError(encoded) |
|||
} |
|||
pos++ |
|||
i, overflow = madd(i, digit, w) |
|||
if overflow { |
|||
return "", punyError(encoded) |
|||
} |
|||
t := k - bias |
|||
if k <= bias { |
|||
t = tmin |
|||
} else if k >= bias+tmax { |
|||
t = tmax |
|||
} |
|||
if digit < t { |
|||
break |
|||
} |
|||
w, overflow = madd(0, w, base-t) |
|||
if overflow { |
|||
return "", punyError(encoded) |
|||
} |
|||
} |
|||
if len(output) >= 1024 { |
|||
return "", punyError(encoded) |
|||
} |
|||
x := int32(len(output) + 1) |
|||
bias = adapt(i-oldI, x, oldI == 0) |
|||
n += i / x |
|||
i %= x |
|||
if n < 0 || n > utf8.MaxRune { |
|||
return "", punyError(encoded) |
|||
} |
|||
output = append(output, 0) |
|||
copy(output[i+1:], output[i:]) |
|||
output[i] = n |
|||
i++ |
|||
} |
|||
return string(output), nil |
|||
} |
|||
|
|||
// encode encodes a string as specified in section 6.3 and prepends prefix to
|
|||
// the result.
|
|||
//
|
|||
// The "while h < length(input)" line in the specification becomes "for
|
|||
// remaining != 0" in the Go code, because len(s) in Go is in bytes, not runes.
|
|||
func encode(prefix, s string) (string, error) { |
|||
output := make([]byte, len(prefix), len(prefix)+1+2*len(s)) |
|||
copy(output, prefix) |
|||
delta, n, bias := int32(0), initialN, initialBias |
|||
b, remaining := int32(0), int32(0) |
|||
for _, r := range s { |
|||
if r < 0x80 { |
|||
b++ |
|||
output = append(output, byte(r)) |
|||
} else { |
|||
remaining++ |
|||
} |
|||
} |
|||
h := b |
|||
if b > 0 { |
|||
output = append(output, '-') |
|||
} |
|||
overflow := false |
|||
for remaining != 0 { |
|||
m := int32(0x7fffffff) |
|||
for _, r := range s { |
|||
if m > r && r >= n { |
|||
m = r |
|||
} |
|||
} |
|||
delta, overflow = madd(delta, m-n, h+1) |
|||
if overflow { |
|||
return "", punyError(s) |
|||
} |
|||
n = m |
|||
for _, r := range s { |
|||
if r < n { |
|||
delta++ |
|||
if delta < 0 { |
|||
return "", punyError(s) |
|||
} |
|||
continue |
|||
} |
|||
if r > n { |
|||
continue |
|||
} |
|||
q := delta |
|||
for k := base; ; k += base { |
|||
t := k - bias |
|||
if k <= bias { |
|||
t = tmin |
|||
} else if k >= bias+tmax { |
|||
t = tmax |
|||
} |
|||
if q < t { |
|||
break |
|||
} |
|||
output = append(output, encodeDigit(t+(q-t)%(base-t))) |
|||
q = (q - t) / (base - t) |
|||
} |
|||
output = append(output, encodeDigit(q)) |
|||
bias = adapt(delta, h+1, h == b) |
|||
delta = 0 |
|||
h++ |
|||
remaining-- |
|||
} |
|||
delta++ |
|||
n++ |
|||
} |
|||
return string(output), nil |
|||
} |
|||
|
|||
// madd computes a + (b * c), detecting overflow.
|
|||
func madd(a, b, c int32) (next int32, overflow bool) { |
|||
p := int64(b) * int64(c) |
|||
if p > math.MaxInt32-int64(a) { |
|||
return 0, true |
|||
} |
|||
return a + int32(p), false |
|||
} |
|||
|
|||
func decodeDigit(x byte) (digit int32, ok bool) { |
|||
switch { |
|||
case '0' <= x && x <= '9': |
|||
return int32(x - ('0' - 26)), true |
|||
case 'A' <= x && x <= 'Z': |
|||
return int32(x - 'A'), true |
|||
case 'a' <= x && x <= 'z': |
|||
return int32(x - 'a'), true |
|||
} |
|||
return 0, false |
|||
} |
|||
|
|||
func encodeDigit(digit int32) byte { |
|||
switch { |
|||
case 0 <= digit && digit < 26: |
|||
return byte(digit + 'a') |
|||
case 26 <= digit && digit < 36: |
|||
return byte(digit + ('0' - 26)) |
|||
} |
|||
panic("idna: internal error in punycode encoding") |
|||
} |
|||
|
|||
// adapt is the bias adaptation function specified in section 6.1.
|
|||
func adapt(delta, numPoints int32, firstTime bool) int32 { |
|||
if firstTime { |
|||
delta /= damp |
|||
} else { |
|||
delta /= 2 |
|||
} |
|||
delta += delta / numPoints |
|||
k := int32(0) |
|||
for delta > ((base-tmin)*tmax)/2 { |
|||
delta /= base - tmin |
|||
k += base |
|||
} |
|||
return k + (base-tmin+1)*delta/(delta+skew) |
|||
} |
File diff suppressed because it is too large
File diff suppressed because it is too large
File diff suppressed because it is too large
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -0,0 +1,72 @@ |
|||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
|||
|
|||
// Copyright 2016 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 idna |
|||
|
|||
// appendMapping appends the mapping for the respective rune. isMapped must be
|
|||
// true. A mapping is a categorization of a rune as defined in UTS #46.
|
|||
func (c info) appendMapping(b []byte, s string) []byte { |
|||
index := int(c >> indexShift) |
|||
if c&xorBit == 0 { |
|||
s := mappings[index:] |
|||
return append(b, s[1:s[0]+1]...) |
|||
} |
|||
b = append(b, s...) |
|||
if c&inlineXOR == inlineXOR { |
|||
// TODO: support and handle two-byte inline masks
|
|||
b[len(b)-1] ^= byte(index) |
|||
} else { |
|||
for p := len(b) - int(xorData[index]); p < len(b); p++ { |
|||
index++ |
|||
b[p] ^= xorData[index] |
|||
} |
|||
} |
|||
return b |
|||
} |
|||
|
|||
// Sparse block handling code.
|
|||
|
|||
type valueRange struct { |
|||
value uint16 // header: value:stride
|
|||
lo, hi byte // header: lo:n
|
|||
} |
|||
|
|||
type sparseBlocks struct { |
|||
values []valueRange |
|||
offset []uint16 |
|||
} |
|||
|
|||
var idnaSparse = sparseBlocks{ |
|||
values: idnaSparseValues[:], |
|||
offset: idnaSparseOffset[:], |
|||
} |
|||
|
|||
// Don't use newIdnaTrie to avoid unconditional linking in of the table.
|
|||
var trie = &idnaTrie{} |
|||
|
|||
// lookup determines the type of block n and looks up the value for b.
|
|||
// For n < t.cutoff, the block is a simple lookup table. Otherwise, the block
|
|||
// is a list of ranges with an accompanying value. Given a matching range r,
|
|||
// the value for b is by r.value + (b - r.lo) * stride.
|
|||
func (t *sparseBlocks) lookup(n uint32, b byte) uint16 { |
|||
offset := t.offset[n] |
|||
header := t.values[offset] |
|||
lo := offset + 1 |
|||
hi := lo + uint16(header.lo) |
|||
for lo < hi { |
|||
m := lo + (hi-lo)/2 |
|||
r := t.values[m] |
|||
if r.lo <= b && b <= r.hi { |
|||
return r.value + uint16(b-r.lo)*header.value |
|||
} |
|||
if b < r.lo { |
|||
hi = m |
|||
} else { |
|||
lo = m + 1 |
|||
} |
|||
} |
|||
return 0 |
|||
} |
@ -0,0 +1,119 @@ |
|||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
|||
|
|||
package idna |
|||
|
|||
// This file contains definitions for interpreting the trie value of the idna
|
|||
// trie generated by "go run gen*.go". It is shared by both the generator
|
|||
// program and the resultant package. Sharing is achieved by the generator
|
|||
// copying gen_trieval.go to trieval.go and changing what's above this comment.
|
|||
|
|||
// info holds information from the IDNA mapping table for a single rune. It is
|
|||
// the value returned by a trie lookup. In most cases, all information fits in
|
|||
// a 16-bit value. For mappings, this value may contain an index into a slice
|
|||
// with the mapped string. Such mappings can consist of the actual mapped value
|
|||
// or an XOR pattern to be applied to the bytes of the UTF8 encoding of the
|
|||
// input rune. This technique is used by the cases packages and reduces the
|
|||
// table size significantly.
|
|||
//
|
|||
// The per-rune values have the following format:
|
|||
//
|
|||
// if mapped {
|
|||
// if inlinedXOR {
|
|||
// 15..13 inline XOR marker
|
|||
// 12..11 unused
|
|||
// 10..3 inline XOR mask
|
|||
// } else {
|
|||
// 15..3 index into xor or mapping table
|
|||
// }
|
|||
// } else {
|
|||
// 15..14 unused
|
|||
// 13 mayNeedNorm
|
|||
// 12..11 attributes
|
|||
// 10..8 joining type
|
|||
// 7..3 category type
|
|||
// }
|
|||
// 2 use xor pattern
|
|||
// 1..0 mapped category
|
|||
//
|
|||
// See the definitions below for a more detailed description of the various
|
|||
// bits.
|
|||
type info uint16 |
|||
|
|||
const ( |
|||
catSmallMask = 0x3 |
|||
catBigMask = 0xF8 |
|||
indexShift = 3 |
|||
xorBit = 0x4 // interpret the index as an xor pattern
|
|||
inlineXOR = 0xE000 // These bits are set if the XOR pattern is inlined.
|
|||
|
|||
joinShift = 8 |
|||
joinMask = 0x07 |
|||
|
|||
// Attributes
|
|||
attributesMask = 0x1800 |
|||
viramaModifier = 0x1800 |
|||
modifier = 0x1000 |
|||
rtl = 0x0800 |
|||
|
|||
mayNeedNorm = 0x2000 |
|||
) |
|||
|
|||
// A category corresponds to a category defined in the IDNA mapping table.
|
|||
type category uint16 |
|||
|
|||
const ( |
|||
unknown category = 0 // not currently defined in unicode.
|
|||
mapped category = 1 |
|||
disallowedSTD3Mapped category = 2 |
|||
deviation category = 3 |
|||
) |
|||
|
|||
const ( |
|||
valid category = 0x08 |
|||
validNV8 category = 0x18 |
|||
validXV8 category = 0x28 |
|||
disallowed category = 0x40 |
|||
disallowedSTD3Valid category = 0x80 |
|||
ignored category = 0xC0 |
|||
) |
|||
|
|||
// join types and additional rune information
|
|||
const ( |
|||
joiningL = (iota + 1) |
|||
joiningD |
|||
joiningT |
|||
joiningR |
|||
|
|||
//the following types are derived during processing
|
|||
joinZWJ |
|||
joinZWNJ |
|||
joinVirama |
|||
numJoinTypes |
|||
) |
|||
|
|||
func (c info) isMapped() bool { |
|||
return c&0x3 != 0 |
|||
} |
|||
|
|||
func (c info) category() category { |
|||
small := c & catSmallMask |
|||
if small != 0 { |
|||
return category(small) |
|||
} |
|||
return category(c & catBigMask) |
|||
} |
|||
|
|||
func (c info) joinType() info { |
|||
if c.isMapped() { |
|||
return 0 |
|||
} |
|||
return (c >> joinShift) & joinMask |
|||
} |
|||
|
|||
func (c info) isModifier() bool { |
|||
return c&(modifier|catSmallMask) == modifier |
|||
} |
|||
|
|||
func (c info) isViramaModifier() bool { |
|||
return c&(attributesMask|catSmallMask) == viramaModifier |
|||
} |
@ -1,17 +0,0 @@ |
|||
// Copyright 2016 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.
|
|||
|
|||
// +build !go1.7
|
|||
|
|||
package webdav |
|||
|
|||
import ( |
|||
"net/http" |
|||
|
|||
"golang.org/x/net/context" |
|||
) |
|||
|
|||
func getContext(r *http.Request) context.Context { |
|||
return context.Background() |
|||
} |
@ -1,16 +0,0 @@ |
|||
// Copyright 2016 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.
|
|||
|
|||
// +build go1.7
|
|||
|
|||
package webdav |
|||
|
|||
import ( |
|||
"context" |
|||
"net/http" |
|||
) |
|||
|
|||
func getContext(r *http.Request) context.Context { |
|||
return r.Context() |
|||
} |
@ -1,3 +0,0 @@ |
|||
# This source code refers to The Go Authors for copyright purposes. |
|||
# The master list of authors is in the main Go distribution, |
|||
# visible at http://tip.golang.org/AUTHORS. |
@ -1,3 +0,0 @@ |
|||
# This source code was written by the Go contributors. |
|||
# The master list of contributors is in the main Go distribution, |
|||
# visible at http://tip.golang.org/CONTRIBUTORS. |
@ -0,0 +1,30 @@ |
|||
// Copyright 2020 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 unsafeheader contains header declarations for the Go runtime's
|
|||
// slice and string implementations.
|
|||
//
|
|||
// This package allows x/sys to use types equivalent to
|
|||
// reflect.SliceHeader and reflect.StringHeader without introducing
|
|||
// a dependency on the (relatively heavy) "reflect" package.
|
|||
package unsafeheader |
|||
|
|||
import ( |
|||
"unsafe" |
|||
) |
|||
|
|||
// Slice is the runtime representation of a slice.
|
|||
// It cannot be used safely or portably and its representation may change in a later release.
|
|||
type Slice struct { |
|||
Data unsafe.Pointer |
|||
Len int |
|||
Cap int |
|||
} |
|||
|
|||
// String is the runtime representation of a string.
|
|||
// It cannot be used safely or portably and its representation may change in a later release.
|
|||
type String struct { |
|||
Data unsafe.Pointer |
|||
Len int |
|||
} |
@ -0,0 +1,29 @@ |
|||
// Copyright 2021 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. |
|||
|
|||
//go:build (darwin || dragonfly || freebsd || netbsd || openbsd) && gc |
|||
// +build darwin dragonfly freebsd netbsd openbsd |
|||
// +build gc |
|||
|
|||
#include "textflag.h" |
|||
|
|||
// System call support for AMD64 BSD |
|||
|
|||
// Just jump to package syscall's implementation for all these functions. |
|||
// The runtime may know about them. |
|||
|
|||
TEXT ·Syscall(SB),NOSPLIT,$0-56 |
|||
JMP syscall·Syscall(SB) |
|||
|
|||
TEXT ·Syscall6(SB),NOSPLIT,$0-80 |
|||
JMP syscall·Syscall6(SB) |
|||
|
|||
TEXT ·Syscall9(SB),NOSPLIT,$0-104 |
|||
JMP syscall·Syscall9(SB) |
|||
|
|||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56 |
|||
JMP syscall·RawSyscall(SB) |
|||
|
|||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 |
|||
JMP syscall·RawSyscall6(SB) |
@ -1,14 +1,14 @@ |
|||
// Copyright 2012 The Go Authors. All rights reserved. |
|||
// Copyright 2021 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. |
|||
|
|||
// +build !gccgo |
|||
//go:build (freebsd || netbsd || openbsd) && gc |
|||
// +build freebsd netbsd openbsd |
|||
// +build gc |
|||
|
|||
#include "textflag.h" |
|||
|
|||
// |
|||
// System call support for ARM, FreeBSD |
|||
// |
|||
// System call support for ARM BSD |
|||
|
|||
// Just jump to package syscall's implementation for all these functions. |
|||
// The runtime may know about them. |
@ -1,14 +1,14 @@ |
|||
// Copyright 2009 The Go Authors. All rights reserved. |
|||
// Copyright 2021 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. |
|||
|
|||
// +build !gccgo |
|||
//go:build (darwin || freebsd || netbsd || openbsd) && gc |
|||
// +build darwin freebsd netbsd openbsd |
|||
// +build gc |
|||
|
|||
#include "textflag.h" |
|||
|
|||
// |
|||
// System call support for AMD64, OpenBSD |
|||
// |
|||
// System call support for ARM64 BSD |
|||
|
|||
// Just jump to package syscall's implementation for all these functions. |
|||
// The runtime may know about them. |
@ -1,13 +1,15 @@ |
|||
// Copyright 2009 The Go Authors. All rights reserved. |
|||
// Copyright 2022 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. |
|||
|
|||
// +build !gccgo |
|||
//go:build (darwin || freebsd || netbsd || openbsd) && gc |
|||
// +build darwin freebsd netbsd openbsd |
|||
// +build gc |
|||
|
|||
#include "textflag.h" |
|||
|
|||
// |
|||
// System call support for AMD64, NetBSD |
|||
// System call support for ppc64, BSD |
|||
// |
|||
|
|||
// Just jump to package syscall's implementation for all these functions. |
@ -1,14 +1,14 @@ |
|||
// Copyright 2009 The Go Authors. All rights reserved. |
|||
// Copyright 2021 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. |
|||
|
|||
// +build !gccgo |
|||
//go:build (darwin || freebsd || netbsd || openbsd) && gc |
|||
// +build darwin freebsd netbsd openbsd |
|||
// +build gc |
|||
|
|||
#include "textflag.h" |
|||
|
|||
// |
|||
// System call support for AMD64, Darwin |
|||
// |
|||
// System call support for RISCV64 BSD |
|||
|
|||
// Just jump to package syscall's implementation for all these functions. |
|||
// The runtime may know about them. |
@ -1,29 +0,0 @@ |
|||
// Copyright 2009 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. |
|||
|
|||
// +build !gccgo |
|||
|
|||
#include "textflag.h" |
|||
|
|||
// |
|||
// System call support for 386, Darwin |
|||
// |
|||
|
|||
// Just jump to package syscall's implementation for all these functions. |
|||
// The runtime may know about them. |
|||
|
|||
TEXT ·Syscall(SB),NOSPLIT,$0-28 |
|||
JMP syscall·Syscall(SB) |
|||
|
|||
TEXT ·Syscall6(SB),NOSPLIT,$0-40 |
|||
JMP syscall·Syscall6(SB) |
|||
|
|||
TEXT ·Syscall9(SB),NOSPLIT,$0-52 |
|||
JMP syscall·Syscall9(SB) |
|||
|
|||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28 |
|||
JMP syscall·RawSyscall(SB) |
|||
|
|||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 |
|||
JMP syscall·RawSyscall6(SB) |
@ -1,30 +0,0 @@ |
|||
// Copyright 2015 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. |
|||
|
|||
// +build !gccgo |
|||
// +build arm,darwin |
|||
|
|||
#include "textflag.h" |
|||
|
|||
// |
|||
// System call support for ARM, Darwin |
|||
// |
|||
|
|||
// Just jump to package syscall's implementation for all these functions. |
|||
// The runtime may know about them. |
|||
|
|||
TEXT ·Syscall(SB),NOSPLIT,$0-28 |
|||
B syscall·Syscall(SB) |
|||
|
|||
TEXT ·Syscall6(SB),NOSPLIT,$0-40 |
|||
B syscall·Syscall6(SB) |
|||
|
|||
TEXT ·Syscall9(SB),NOSPLIT,$0-52 |
|||
B syscall·Syscall9(SB) |
|||
|
|||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28 |
|||
B syscall·RawSyscall(SB) |
|||
|
|||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 |
|||
B syscall·RawSyscall6(SB) |
@ -1,30 +0,0 @@ |
|||
// Copyright 2015 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. |
|||
|
|||
// +build !gccgo |
|||
// +build arm64,darwin |
|||
|
|||
#include "textflag.h" |
|||
|
|||
// |
|||
// System call support for AMD64, Darwin |
|||
// |
|||
|
|||
// Just jump to package syscall's implementation for all these functions. |
|||
// The runtime may know about them. |
|||
|
|||
TEXT ·Syscall(SB),NOSPLIT,$0-56 |
|||
B syscall·Syscall(SB) |
|||
|
|||
TEXT ·Syscall6(SB),NOSPLIT,$0-80 |
|||
B syscall·Syscall6(SB) |
|||
|
|||
TEXT ·Syscall9(SB),NOSPLIT,$0-104 |
|||
B syscall·Syscall9(SB) |
|||
|
|||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56 |
|||
B syscall·RawSyscall(SB) |
|||
|
|||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 |
|||
B syscall·RawSyscall6(SB) |
@ -1,29 +0,0 @@ |
|||
// Copyright 2009 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. |
|||
|
|||
// +build !gccgo |
|||
|
|||
#include "textflag.h" |
|||
|
|||
// |
|||
// System call support for AMD64, DragonFly |
|||
// |
|||
|
|||
// Just jump to package syscall's implementation for all these functions. |
|||
// The runtime may know about them. |
|||
|
|||
TEXT ·Syscall(SB),NOSPLIT,$0-56 |
|||
JMP syscall·Syscall(SB) |
|||
|
|||
TEXT ·Syscall6(SB),NOSPLIT,$0-80 |
|||
JMP syscall·Syscall6(SB) |
|||
|
|||
TEXT ·Syscall9(SB),NOSPLIT,$0-104 |
|||
JMP syscall·Syscall9(SB) |
|||
|
|||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56 |
|||
JMP syscall·RawSyscall(SB) |
|||
|
|||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 |
|||
JMP syscall·RawSyscall6(SB) |
@ -1,29 +0,0 @@ |
|||
// Copyright 2009 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. |
|||
|
|||
// +build !gccgo |
|||
|
|||
#include "textflag.h" |
|||
|
|||
// |
|||
// System call support for AMD64, FreeBSD |
|||
// |
|||
|
|||
// Just jump to package syscall's implementation for all these functions. |
|||
// The runtime may know about them. |
|||
|
|||
TEXT ·Syscall(SB),NOSPLIT,$0-56 |
|||
JMP syscall·Syscall(SB) |
|||
|
|||
TEXT ·Syscall6(SB),NOSPLIT,$0-80 |
|||
JMP syscall·Syscall6(SB) |
|||
|
|||
TEXT ·Syscall9(SB),NOSPLIT,$0-104 |
|||
JMP syscall·Syscall9(SB) |
|||
|
|||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56 |
|||
JMP syscall·RawSyscall(SB) |
|||
|
|||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 |
|||
JMP syscall·RawSyscall6(SB) |
@ -1,29 +0,0 @@ |
|||
// Copyright 2018 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. |
|||
|
|||
// +build !gccgo |
|||
|
|||
#include "textflag.h" |
|||
|
|||
// |
|||
// System call support for ARM64, FreeBSD |
|||
// |
|||
|
|||
// Just jump to package syscall's implementation for all these functions. |
|||
// The runtime may know about them. |
|||
|
|||
TEXT ·Syscall(SB),NOSPLIT,$0-56 |
|||
JMP syscall·Syscall(SB) |
|||
|
|||
TEXT ·Syscall6(SB),NOSPLIT,$0-80 |
|||
JMP syscall·Syscall6(SB) |
|||
|
|||
TEXT ·Syscall9(SB),NOSPLIT,$0-104 |
|||
JMP syscall·Syscall9(SB) |
|||
|
|||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56 |
|||
JMP syscall·RawSyscall(SB) |
|||
|
|||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 |
|||
JMP syscall·RawSyscall6(SB) |
@ -0,0 +1,54 @@ |
|||
// Copyright 2022 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. |
|||
|
|||
//go:build linux && loong64 && gc |
|||
// +build linux |
|||
// +build loong64 |
|||
// +build gc |
|||
|
|||
#include "textflag.h" |
|||
|
|||
|
|||
// Just jump to package syscall's implementation for all these functions. |
|||
// The runtime may know about them. |
|||
|
|||
TEXT ·Syscall(SB),NOSPLIT,$0-56 |
|||
JMP syscall·Syscall(SB) |
|||
|
|||
TEXT ·Syscall6(SB),NOSPLIT,$0-80 |
|||
JMP syscall·Syscall6(SB) |
|||
|
|||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48 |
|||
JAL runtime·entersyscall(SB) |
|||
MOVV a1+8(FP), R4 |
|||
MOVV a2+16(FP), R5 |
|||
MOVV a3+24(FP), R6 |
|||
MOVV R0, R7 |
|||
MOVV R0, R8 |
|||
MOVV R0, R9 |
|||
MOVV trap+0(FP), R11 // syscall entry |
|||
SYSCALL |
|||
MOVV R4, r1+32(FP) |
|||
MOVV R0, r2+40(FP) // r2 is not used. Always set to 0 |
|||
JAL runtime·exitsyscall(SB) |
|||
RET |
|||
|
|||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56 |
|||
JMP syscall·RawSyscall(SB) |
|||
|
|||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 |
|||
JMP syscall·RawSyscall6(SB) |
|||
|
|||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48 |
|||
MOVV a1+8(FP), R4 |
|||
MOVV a2+16(FP), R5 |
|||
MOVV a3+24(FP), R6 |
|||
MOVV R0, R7 |
|||
MOVV R0, R8 |
|||
MOVV R0, R9 |
|||
MOVV trap+0(FP), R11 // syscall entry |
|||
SYSCALL |
|||
MOVV R4, r1+32(FP) |
|||
MOVV R0, r2+40(FP) // r2 is not used. Always set to 0 |
|||
RET |
@ -1,29 +0,0 @@ |
|||
// Copyright 2009 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. |
|||
|
|||
// +build !gccgo |
|||
|
|||
#include "textflag.h" |
|||
|
|||
// |
|||
// System call support for 386, NetBSD |
|||
// |
|||
|
|||
// Just jump to package syscall's implementation for all these functions. |
|||
// The runtime may know about them. |
|||
|
|||
TEXT ·Syscall(SB),NOSPLIT,$0-28 |
|||
JMP syscall·Syscall(SB) |
|||
|
|||
TEXT ·Syscall6(SB),NOSPLIT,$0-40 |
|||
JMP syscall·Syscall6(SB) |
|||
|
|||
TEXT ·Syscall9(SB),NOSPLIT,$0-52 |
|||
JMP syscall·Syscall9(SB) |
|||
|
|||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28 |
|||
JMP syscall·RawSyscall(SB) |
|||
|
|||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 |
|||
JMP syscall·RawSyscall6(SB) |
@ -1,29 +0,0 @@ |
|||
// Copyright 2013 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. |
|||
|
|||
// +build !gccgo |
|||
|
|||
#include "textflag.h" |
|||
|
|||
// |
|||
// System call support for ARM, NetBSD |
|||
// |
|||
|
|||
// Just jump to package syscall's implementation for all these functions. |
|||
// The runtime may know about them. |
|||
|
|||
TEXT ·Syscall(SB),NOSPLIT,$0-28 |
|||
B syscall·Syscall(SB) |
|||
|
|||
TEXT ·Syscall6(SB),NOSPLIT,$0-40 |
|||
B syscall·Syscall6(SB) |
|||
|
|||
TEXT ·Syscall9(SB),NOSPLIT,$0-52 |
|||
B syscall·Syscall9(SB) |
|||
|
|||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28 |
|||
B syscall·RawSyscall(SB) |
|||
|
|||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 |
|||
B syscall·RawSyscall6(SB) |
@ -1,29 +0,0 @@ |
|||
// Copyright 2019 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. |
|||
|
|||
// +build !gccgo |
|||
|
|||
#include "textflag.h" |
|||
|
|||
// |
|||
// System call support for ARM64, NetBSD |
|||
// |
|||
|
|||
// Just jump to package syscall's implementation for all these functions. |
|||
// The runtime may know about them. |
|||
|
|||
TEXT ·Syscall(SB),NOSPLIT,$0-56 |
|||
B syscall·Syscall(SB) |
|||
|
|||
TEXT ·Syscall6(SB),NOSPLIT,$0-80 |
|||
B syscall·Syscall6(SB) |
|||
|
|||
TEXT ·Syscall9(SB),NOSPLIT,$0-104 |
|||
B syscall·Syscall9(SB) |
|||
|
|||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56 |
|||
B syscall·RawSyscall(SB) |
|||
|
|||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 |
|||
B syscall·RawSyscall6(SB) |
@ -1,29 +0,0 @@ |
|||
// Copyright 2009 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. |
|||
|
|||
// +build !gccgo |
|||
|
|||
#include "textflag.h" |
|||
|
|||
// |
|||
// System call support for 386, OpenBSD |
|||
// |
|||
|
|||
// Just jump to package syscall's implementation for all these functions. |
|||
// The runtime may know about them. |
|||
|
|||
TEXT ·Syscall(SB),NOSPLIT,$0-28 |
|||
JMP syscall·Syscall(SB) |
|||
|
|||
TEXT ·Syscall6(SB),NOSPLIT,$0-40 |
|||
JMP syscall·Syscall6(SB) |
|||
|
|||
TEXT ·Syscall9(SB),NOSPLIT,$0-52 |
|||
JMP syscall·Syscall9(SB) |
|||
|
|||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28 |
|||
JMP syscall·RawSyscall(SB) |
|||
|
|||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 |
|||
JMP syscall·RawSyscall6(SB) |
@ -1,29 +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. |
|||
|
|||
// +build !gccgo |
|||
|
|||
#include "textflag.h" |
|||
|
|||
// |
|||
// System call support for ARM, OpenBSD |
|||
// |
|||
|
|||
// Just jump to package syscall's implementation for all these functions. |
|||
// The runtime may know about them. |
|||
|
|||
TEXT ·Syscall(SB),NOSPLIT,$0-28 |
|||
B syscall·Syscall(SB) |
|||
|
|||
TEXT ·Syscall6(SB),NOSPLIT,$0-40 |
|||
B syscall·Syscall6(SB) |
|||
|
|||
TEXT ·Syscall9(SB),NOSPLIT,$0-52 |
|||
B syscall·Syscall9(SB) |
|||
|
|||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28 |
|||
B syscall·RawSyscall(SB) |
|||
|
|||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 |
|||
B syscall·RawSyscall6(SB) |
@ -0,0 +1,426 @@ |
|||
// Copyright 2020 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. |
|||
|
|||
//go:build zos && s390x && gc |
|||
// +build zos |
|||
// +build s390x |
|||
// +build gc |
|||
|
|||
#include "textflag.h" |
|||
|
|||
#define PSALAA 1208(R0) |
|||
#define GTAB64(x) 80(x) |
|||
#define LCA64(x) 88(x) |
|||
#define CAA(x) 8(x) |
|||
#define EDCHPXV(x) 1016(x) // in the CAA |
|||
#define SAVSTACK_ASYNC(x) 336(x) // in the LCA |
|||
|
|||
// SS_*, where x=SAVSTACK_ASYNC |
|||
#define SS_LE(x) 0(x) |
|||
#define SS_GO(x) 8(x) |
|||
#define SS_ERRNO(x) 16(x) |
|||
#define SS_ERRNOJR(x) 20(x) |
|||
|
|||
#define LE_CALL BYTE $0x0D; BYTE $0x76; // BL R7, R6 |
|||
|
|||
TEXT ·clearErrno(SB),NOSPLIT,$0-0 |
|||
BL addrerrno<>(SB) |
|||
MOVD $0, 0(R3) |
|||
RET |
|||
|
|||
// Returns the address of errno in R3. |
|||
TEXT addrerrno<>(SB),NOSPLIT|NOFRAME,$0-0 |
|||
// Get library control area (LCA). |
|||
MOVW PSALAA, R8 |
|||
MOVD LCA64(R8), R8 |
|||
|
|||
// Get __errno FuncDesc. |
|||
MOVD CAA(R8), R9 |
|||
MOVD EDCHPXV(R9), R9 |
|||
ADD $(0x156*16), R9 |
|||
LMG 0(R9), R5, R6 |
|||
|
|||
// Switch to saved LE stack. |
|||
MOVD SAVSTACK_ASYNC(R8), R9 |
|||
MOVD 0(R9), R4 |
|||
MOVD $0, 0(R9) |
|||
|
|||
// Call __errno function. |
|||
LE_CALL |
|||
NOPH |
|||
|
|||
// Switch back to Go stack. |
|||
XOR R0, R0 // Restore R0 to $0. |
|||
MOVD R4, 0(R9) // Save stack pointer. |
|||
RET |
|||
|
|||
TEXT ·syscall_syscall(SB),NOSPLIT,$0-56 |
|||
BL runtime·entersyscall(SB) |
|||
MOVD a1+8(FP), R1 |
|||
MOVD a2+16(FP), R2 |
|||
MOVD a3+24(FP), R3 |
|||
|
|||
// Get library control area (LCA). |
|||
MOVW PSALAA, R8 |
|||
MOVD LCA64(R8), R8 |
|||
|
|||
// Get function. |
|||
MOVD CAA(R8), R9 |
|||
MOVD EDCHPXV(R9), R9 |
|||
MOVD trap+0(FP), R5 |
|||
SLD $4, R5 |
|||
ADD R5, R9 |
|||
LMG 0(R9), R5, R6 |
|||
|
|||
// Restore LE stack. |
|||
MOVD SAVSTACK_ASYNC(R8), R9 |
|||
MOVD 0(R9), R4 |
|||
MOVD $0, 0(R9) |
|||
|
|||
// Call function. |
|||
LE_CALL |
|||
NOPH |
|||
XOR R0, R0 // Restore R0 to $0. |
|||
MOVD R4, 0(R9) // Save stack pointer. |
|||
|
|||
MOVD R3, r1+32(FP) |
|||
MOVD R0, r2+40(FP) |
|||
MOVD R0, err+48(FP) |
|||
MOVW R3, R4 |
|||
CMP R4, $-1 |
|||
BNE done |
|||
BL addrerrno<>(SB) |
|||
MOVWZ 0(R3), R3 |
|||
MOVD R3, err+48(FP) |
|||
done: |
|||
BL runtime·exitsyscall(SB) |
|||
RET |
|||
|
|||
TEXT ·syscall_rawsyscall(SB),NOSPLIT,$0-56 |
|||
MOVD a1+8(FP), R1 |
|||
MOVD a2+16(FP), R2 |
|||
MOVD a3+24(FP), R3 |
|||
|
|||
// Get library control area (LCA). |
|||
MOVW PSALAA, R8 |
|||
MOVD LCA64(R8), R8 |
|||
|
|||
// Get function. |
|||
MOVD CAA(R8), R9 |
|||
MOVD EDCHPXV(R9), R9 |
|||
MOVD trap+0(FP), R5 |
|||
SLD $4, R5 |
|||
ADD R5, R9 |
|||
LMG 0(R9), R5, R6 |
|||
|
|||
// Restore LE stack. |
|||
MOVD SAVSTACK_ASYNC(R8), R9 |
|||
MOVD 0(R9), R4 |
|||
MOVD $0, 0(R9) |
|||
|
|||
// Call function. |
|||
LE_CALL |
|||
NOPH |
|||
XOR R0, R0 // Restore R0 to $0. |
|||
MOVD R4, 0(R9) // Save stack pointer. |
|||
|
|||
MOVD R3, r1+32(FP) |
|||
MOVD R0, r2+40(FP) |
|||
MOVD R0, err+48(FP) |
|||
MOVW R3, R4 |
|||
CMP R4, $-1 |
|||
BNE done |
|||
BL addrerrno<>(SB) |
|||
MOVWZ 0(R3), R3 |
|||
MOVD R3, err+48(FP) |
|||
done: |
|||
RET |
|||
|
|||
TEXT ·syscall_syscall6(SB),NOSPLIT,$0-80 |
|||
BL runtime·entersyscall(SB) |
|||
MOVD a1+8(FP), R1 |
|||
MOVD a2+16(FP), R2 |
|||
MOVD a3+24(FP), R3 |
|||
|
|||
// Get library control area (LCA). |
|||
MOVW PSALAA, R8 |
|||
MOVD LCA64(R8), R8 |
|||
|
|||
// Get function. |
|||
MOVD CAA(R8), R9 |
|||
MOVD EDCHPXV(R9), R9 |
|||
MOVD trap+0(FP), R5 |
|||
SLD $4, R5 |
|||
ADD R5, R9 |
|||
LMG 0(R9), R5, R6 |
|||
|
|||
// Restore LE stack. |
|||
MOVD SAVSTACK_ASYNC(R8), R9 |
|||
MOVD 0(R9), R4 |
|||
MOVD $0, 0(R9) |
|||
|
|||
// Fill in parameter list. |
|||
MOVD a4+32(FP), R12 |
|||
MOVD R12, (2176+24)(R4) |
|||
MOVD a5+40(FP), R12 |
|||
MOVD R12, (2176+32)(R4) |
|||
MOVD a6+48(FP), R12 |
|||
MOVD R12, (2176+40)(R4) |
|||
|
|||
// Call function. |
|||
LE_CALL |
|||
NOPH |
|||
XOR R0, R0 // Restore R0 to $0. |
|||
MOVD R4, 0(R9) // Save stack pointer. |
|||
|
|||
MOVD R3, r1+56(FP) |
|||
MOVD R0, r2+64(FP) |
|||
MOVD R0, err+72(FP) |
|||
MOVW R3, R4 |
|||
CMP R4, $-1 |
|||
BNE done |
|||
BL addrerrno<>(SB) |
|||
MOVWZ 0(R3), R3 |
|||
MOVD R3, err+72(FP) |
|||
done: |
|||
BL runtime·exitsyscall(SB) |
|||
RET |
|||
|
|||
TEXT ·syscall_rawsyscall6(SB),NOSPLIT,$0-80 |
|||
MOVD a1+8(FP), R1 |
|||
MOVD a2+16(FP), R2 |
|||
MOVD a3+24(FP), R3 |
|||
|
|||
// Get library control area (LCA). |
|||
MOVW PSALAA, R8 |
|||
MOVD LCA64(R8), R8 |
|||
|
|||
// Get function. |
|||
MOVD CAA(R8), R9 |
|||
MOVD EDCHPXV(R9), R9 |
|||
MOVD trap+0(FP), R5 |
|||
SLD $4, R5 |
|||
ADD R5, R9 |
|||
LMG 0(R9), R5, R6 |
|||
|
|||
// Restore LE stack. |
|||
MOVD SAVSTACK_ASYNC(R8), R9 |
|||
MOVD 0(R9), R4 |
|||
MOVD $0, 0(R9) |
|||
|
|||
// Fill in parameter list. |
|||
MOVD a4+32(FP), R12 |
|||
MOVD R12, (2176+24)(R4) |
|||
MOVD a5+40(FP), R12 |
|||
MOVD R12, (2176+32)(R4) |
|||
MOVD a6+48(FP), R12 |
|||
MOVD R12, (2176+40)(R4) |
|||
|
|||
// Call function. |
|||
LE_CALL |
|||
NOPH |
|||
XOR R0, R0 // Restore R0 to $0. |
|||
MOVD R4, 0(R9) // Save stack pointer. |
|||
|
|||
MOVD R3, r1+56(FP) |
|||
MOVD R0, r2+64(FP) |
|||
MOVD R0, err+72(FP) |
|||
MOVW R3, R4 |
|||
CMP R4, $-1 |
|||
BNE done |
|||
BL ·rrno<>(SB) |
|||
MOVWZ 0(R3), R3 |
|||
MOVD R3, err+72(FP) |
|||
done: |
|||
RET |
|||
|
|||
TEXT ·syscall_syscall9(SB),NOSPLIT,$0 |
|||
BL runtime·entersyscall(SB) |
|||
MOVD a1+8(FP), R1 |
|||
MOVD a2+16(FP), R2 |
|||
MOVD a3+24(FP), R3 |
|||
|
|||
// Get library control area (LCA). |
|||
MOVW PSALAA, R8 |
|||
MOVD LCA64(R8), R8 |
|||
|
|||
// Get function. |
|||
MOVD CAA(R8), R9 |
|||
MOVD EDCHPXV(R9), R9 |
|||
MOVD trap+0(FP), R5 |
|||
SLD $4, R5 |
|||
ADD R5, R9 |
|||
LMG 0(R9), R5, R6 |
|||
|
|||
// Restore LE stack. |
|||
MOVD SAVSTACK_ASYNC(R8), R9 |
|||
MOVD 0(R9), R4 |
|||
MOVD $0, 0(R9) |
|||
|
|||
// Fill in parameter list. |
|||
MOVD a4+32(FP), R12 |
|||
MOVD R12, (2176+24)(R4) |
|||
MOVD a5+40(FP), R12 |
|||
MOVD R12, (2176+32)(R4) |
|||
MOVD a6+48(FP), R12 |
|||
MOVD R12, (2176+40)(R4) |
|||
MOVD a7+56(FP), R12 |
|||
MOVD R12, (2176+48)(R4) |
|||
MOVD a8+64(FP), R12 |
|||
MOVD R12, (2176+56)(R4) |
|||
MOVD a9+72(FP), R12 |
|||
MOVD R12, (2176+64)(R4) |
|||
|
|||
// Call function. |
|||
LE_CALL |
|||
NOPH |
|||
XOR R0, R0 // Restore R0 to $0. |
|||
MOVD R4, 0(R9) // Save stack pointer. |
|||
|
|||
MOVD R3, r1+80(FP) |
|||
MOVD R0, r2+88(FP) |
|||
MOVD R0, err+96(FP) |
|||
MOVW R3, R4 |
|||
CMP R4, $-1 |
|||
BNE done |
|||
BL addrerrno<>(SB) |
|||
MOVWZ 0(R3), R3 |
|||
MOVD R3, err+96(FP) |
|||
done: |
|||
BL runtime·exitsyscall(SB) |
|||
RET |
|||
|
|||
TEXT ·syscall_rawsyscall9(SB),NOSPLIT,$0 |
|||
MOVD a1+8(FP), R1 |
|||
MOVD a2+16(FP), R2 |
|||
MOVD a3+24(FP), R3 |
|||
|
|||
// Get library control area (LCA). |
|||
MOVW PSALAA, R8 |
|||
MOVD LCA64(R8), R8 |
|||
|
|||
// Get function. |
|||
MOVD CAA(R8), R9 |
|||
MOVD EDCHPXV(R9), R9 |
|||
MOVD trap+0(FP), R5 |
|||
SLD $4, R5 |
|||
ADD R5, R9 |
|||
LMG 0(R9), R5, R6 |
|||
|
|||
// Restore LE stack. |
|||
MOVD SAVSTACK_ASYNC(R8), R9 |
|||
MOVD 0(R9), R4 |
|||
MOVD $0, 0(R9) |
|||
|
|||
// Fill in parameter list. |
|||
MOVD a4+32(FP), R12 |
|||
MOVD R12, (2176+24)(R4) |
|||
MOVD a5+40(FP), R12 |
|||
MOVD R12, (2176+32)(R4) |
|||
MOVD a6+48(FP), R12 |
|||
MOVD R12, (2176+40)(R4) |
|||
MOVD a7+56(FP), R12 |
|||
MOVD R12, (2176+48)(R4) |
|||
MOVD a8+64(FP), R12 |
|||
MOVD R12, (2176+56)(R4) |
|||
MOVD a9+72(FP), R12 |
|||
MOVD R12, (2176+64)(R4) |
|||
|
|||
// Call function. |
|||
LE_CALL |
|||
NOPH |
|||
XOR R0, R0 // Restore R0 to $0. |
|||
MOVD R4, 0(R9) // Save stack pointer. |
|||
|
|||
MOVD R3, r1+80(FP) |
|||
MOVD R0, r2+88(FP) |
|||
MOVD R0, err+96(FP) |
|||
MOVW R3, R4 |
|||
CMP R4, $-1 |
|||
BNE done |
|||
BL addrerrno<>(SB) |
|||
MOVWZ 0(R3), R3 |
|||
MOVD R3, err+96(FP) |
|||
done: |
|||
RET |
|||
|
|||
// func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64) |
|||
TEXT ·svcCall(SB),NOSPLIT,$0 |
|||
BL runtime·save_g(SB) // Save g and stack pointer |
|||
MOVW PSALAA, R8 |
|||
MOVD LCA64(R8), R8 |
|||
MOVD SAVSTACK_ASYNC(R8), R9 |
|||
MOVD R15, 0(R9) |
|||
|
|||
MOVD argv+8(FP), R1 // Move function arguments into registers |
|||
MOVD dsa+16(FP), g |
|||
MOVD fnptr+0(FP), R15 |
|||
|
|||
BYTE $0x0D // Branch to function |
|||
BYTE $0xEF |
|||
|
|||
BL runtime·load_g(SB) // Restore g and stack pointer |
|||
MOVW PSALAA, R8 |
|||
MOVD LCA64(R8), R8 |
|||
MOVD SAVSTACK_ASYNC(R8), R9 |
|||
MOVD 0(R9), R15 |
|||
|
|||
RET |
|||
|
|||
// func svcLoad(name *byte) unsafe.Pointer |
|||
TEXT ·svcLoad(SB),NOSPLIT,$0 |
|||
MOVD R15, R2 // Save go stack pointer |
|||
MOVD name+0(FP), R0 // Move SVC args into registers |
|||
MOVD $0x80000000, R1 |
|||
MOVD $0, R15 |
|||
BYTE $0x0A // SVC 08 LOAD |
|||
BYTE $0x08 |
|||
MOVW R15, R3 // Save return code from SVC |
|||
MOVD R2, R15 // Restore go stack pointer |
|||
CMP R3, $0 // Check SVC return code |
|||
BNE error |
|||
|
|||
MOVD $-2, R3 // Reset last bit of entry point to zero |
|||
AND R0, R3 |
|||
MOVD R3, addr+8(FP) // Return entry point returned by SVC |
|||
CMP R0, R3 // Check if last bit of entry point was set |
|||
BNE done |
|||
|
|||
MOVD R15, R2 // Save go stack pointer |
|||
MOVD $0, R15 // Move SVC args into registers (entry point still in r0 from SVC 08) |
|||
BYTE $0x0A // SVC 09 DELETE |
|||
BYTE $0x09 |
|||
MOVD R2, R15 // Restore go stack pointer |
|||
|
|||
error: |
|||
MOVD $0, addr+8(FP) // Return 0 on failure |
|||
done: |
|||
XOR R0, R0 // Reset r0 to 0 |
|||
RET |
|||
|
|||
// func svcUnload(name *byte, fnptr unsafe.Pointer) int64 |
|||
TEXT ·svcUnload(SB),NOSPLIT,$0 |
|||
MOVD R15, R2 // Save go stack pointer |
|||
MOVD name+0(FP), R0 // Move SVC args into registers |
|||
MOVD addr+8(FP), R15 |
|||
BYTE $0x0A // SVC 09 |
|||
BYTE $0x09 |
|||
XOR R0, R0 // Reset r0 to 0 |
|||
MOVD R15, R1 // Save SVC return code |
|||
MOVD R2, R15 // Restore go stack pointer |
|||
MOVD R1, rc+0(FP) // Return SVC return code |
|||
RET |
|||
|
|||
// func gettid() uint64 |
|||
TEXT ·gettid(SB), NOSPLIT, $0 |
|||
// Get library control area (LCA). |
|||
MOVW PSALAA, R8 |
|||
MOVD LCA64(R8), R8 |
|||
|
|||
// Get CEECAATHDID |
|||
MOVD CAA(R8), R9 |
|||
MOVD 0x3D0(R9), R9 |
|||
MOVD R9, ret+0(FP) |
|||
|
|||
RET |
@ -0,0 +1,29 @@ |
|||
// Copyright 2020 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.
|
|||
|
|||
//go:build zos && s390x
|
|||
// +build zos,s390x
|
|||
|
|||
// Functions to access/create device major and minor numbers matching the
|
|||
// encoding used by z/OS.
|
|||
//
|
|||
// The information below is extracted and adapted from <sys/stat.h> macros.
|
|||
|
|||
package unix |
|||
|
|||
// Major returns the major component of a z/OS device number.
|
|||
func Major(dev uint64) uint32 { |
|||
return uint32((dev >> 16) & 0x0000FFFF) |
|||
} |
|||
|
|||
// Minor returns the minor component of a z/OS device number.
|
|||
func Minor(dev uint64) uint32 { |
|||
return uint32(dev & 0x0000FFFF) |
|||
} |
|||
|
|||
// Mkdev returns a z/OS device number generated from the given major and minor
|
|||
// components.
|
|||
func Mkdev(major, minor uint32) uint64 { |
|||
return (uint64(major) << 16) | uint64(minor) |
|||
} |
@ -0,0 +1,221 @@ |
|||
// Copyright 2020 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.
|
|||
|
|||
//go:build zos && s390x
|
|||
// +build zos,s390x
|
|||
|
|||
package unix |
|||
|
|||
import ( |
|||
"sync" |
|||
) |
|||
|
|||
// This file simulates epoll on z/OS using poll.
|
|||
|
|||
// Analogous to epoll_event on Linux.
|
|||
// TODO(neeilan): Pad is because the Linux kernel expects a 96-bit struct. We never pass this to the kernel; remove?
|
|||
type EpollEvent struct { |
|||
Events uint32 |
|||
Fd int32 |
|||
Pad int32 |
|||
} |
|||
|
|||
const ( |
|||
EPOLLERR = 0x8 |
|||
EPOLLHUP = 0x10 |
|||
EPOLLIN = 0x1 |
|||
EPOLLMSG = 0x400 |
|||
EPOLLOUT = 0x4 |
|||
EPOLLPRI = 0x2 |
|||
EPOLLRDBAND = 0x80 |
|||
EPOLLRDNORM = 0x40 |
|||
EPOLLWRBAND = 0x200 |
|||
EPOLLWRNORM = 0x100 |
|||
EPOLL_CTL_ADD = 0x1 |
|||
EPOLL_CTL_DEL = 0x2 |
|||
EPOLL_CTL_MOD = 0x3 |
|||
// The following constants are part of the epoll API, but represent
|
|||
// currently unsupported functionality on z/OS.
|
|||
// EPOLL_CLOEXEC = 0x80000
|
|||
// EPOLLET = 0x80000000
|
|||
// EPOLLONESHOT = 0x40000000
|
|||
// EPOLLRDHUP = 0x2000 // Typically used with edge-triggered notis
|
|||
// EPOLLEXCLUSIVE = 0x10000000 // Exclusive wake-up mode
|
|||
// EPOLLWAKEUP = 0x20000000 // Relies on Linux's BLOCK_SUSPEND capability
|
|||
) |
|||
|
|||
// TODO(neeilan): We can eliminate these epToPoll / pToEpoll calls by using identical mask values for POLL/EPOLL
|
|||
// constants where possible The lower 16 bits of epoll events (uint32) can fit any system poll event (int16).
|
|||
|
|||
// epToPollEvt converts epoll event field to poll equivalent.
|
|||
// In epoll, Events is a 32-bit field, while poll uses 16 bits.
|
|||
func epToPollEvt(events uint32) int16 { |
|||
var ep2p = map[uint32]int16{ |
|||
EPOLLIN: POLLIN, |
|||
EPOLLOUT: POLLOUT, |
|||
EPOLLHUP: POLLHUP, |
|||
EPOLLPRI: POLLPRI, |
|||
EPOLLERR: POLLERR, |
|||
} |
|||
|
|||
var pollEvts int16 = 0 |
|||
for epEvt, pEvt := range ep2p { |
|||
if (events & epEvt) != 0 { |
|||
pollEvts |= pEvt |
|||
} |
|||
} |
|||
|
|||
return pollEvts |
|||
} |
|||
|
|||
// pToEpollEvt converts 16 bit poll event bitfields to 32-bit epoll event fields.
|
|||
func pToEpollEvt(revents int16) uint32 { |
|||
var p2ep = map[int16]uint32{ |
|||
POLLIN: EPOLLIN, |
|||
POLLOUT: EPOLLOUT, |
|||
POLLHUP: EPOLLHUP, |
|||
POLLPRI: EPOLLPRI, |
|||
POLLERR: EPOLLERR, |
|||
} |
|||
|
|||
var epollEvts uint32 = 0 |
|||
for pEvt, epEvt := range p2ep { |
|||
if (revents & pEvt) != 0 { |
|||
epollEvts |= epEvt |
|||
} |
|||
} |
|||
|
|||
return epollEvts |
|||
} |
|||
|
|||
// Per-process epoll implementation.
|
|||
type epollImpl struct { |
|||
mu sync.Mutex |
|||
epfd2ep map[int]*eventPoll |
|||
nextEpfd int |
|||
} |
|||
|
|||
// eventPoll holds a set of file descriptors being watched by the process. A process can have multiple epoll instances.
|
|||
// On Linux, this is an in-kernel data structure accessed through a fd.
|
|||
type eventPoll struct { |
|||
mu sync.Mutex |
|||
fds map[int]*EpollEvent |
|||
} |
|||
|
|||
// epoll impl for this process.
|
|||
var impl epollImpl = epollImpl{ |
|||
epfd2ep: make(map[int]*eventPoll), |
|||
nextEpfd: 0, |
|||
} |
|||
|
|||
func (e *epollImpl) epollcreate(size int) (epfd int, err error) { |
|||
e.mu.Lock() |
|||
defer e.mu.Unlock() |
|||
epfd = e.nextEpfd |
|||
e.nextEpfd++ |
|||
|
|||
e.epfd2ep[epfd] = &eventPoll{ |
|||
fds: make(map[int]*EpollEvent), |
|||
} |
|||
return epfd, nil |
|||
} |
|||
|
|||
func (e *epollImpl) epollcreate1(flag int) (fd int, err error) { |
|||
return e.epollcreate(4) |
|||
} |
|||
|
|||
func (e *epollImpl) epollctl(epfd int, op int, fd int, event *EpollEvent) (err error) { |
|||
e.mu.Lock() |
|||
defer e.mu.Unlock() |
|||
|
|||
ep, ok := e.epfd2ep[epfd] |
|||
if !ok { |
|||
|
|||
return EBADF |
|||
} |
|||
|
|||
switch op { |
|||
case EPOLL_CTL_ADD: |
|||
// TODO(neeilan): When we make epfds and fds disjoint, detect epoll
|
|||
// loops here (instances watching each other) and return ELOOP.
|
|||
if _, ok := ep.fds[fd]; ok { |
|||
return EEXIST |
|||
} |
|||
ep.fds[fd] = event |
|||
case EPOLL_CTL_MOD: |
|||
if _, ok := ep.fds[fd]; !ok { |
|||
return ENOENT |
|||
} |
|||
ep.fds[fd] = event |
|||
case EPOLL_CTL_DEL: |
|||
if _, ok := ep.fds[fd]; !ok { |
|||
return ENOENT |
|||
} |
|||
delete(ep.fds, fd) |
|||
|
|||
} |
|||
return nil |
|||
} |
|||
|
|||
// Must be called while holding ep.mu
|
|||
func (ep *eventPoll) getFds() []int { |
|||
fds := make([]int, len(ep.fds)) |
|||
for fd := range ep.fds { |
|||
fds = append(fds, fd) |
|||
} |
|||
return fds |
|||
} |
|||
|
|||
func (e *epollImpl) epollwait(epfd int, events []EpollEvent, msec int) (n int, err error) { |
|||
e.mu.Lock() // in [rare] case of concurrent epollcreate + epollwait
|
|||
ep, ok := e.epfd2ep[epfd] |
|||
|
|||
if !ok { |
|||
e.mu.Unlock() |
|||
return 0, EBADF |
|||
} |
|||
|
|||
pollfds := make([]PollFd, 4) |
|||
for fd, epollevt := range ep.fds { |
|||
pollfds = append(pollfds, PollFd{Fd: int32(fd), Events: epToPollEvt(epollevt.Events)}) |
|||
} |
|||
e.mu.Unlock() |
|||
|
|||
n, err = Poll(pollfds, msec) |
|||
if err != nil { |
|||
return n, err |
|||
} |
|||
|
|||
i := 0 |
|||
for _, pFd := range pollfds { |
|||
if pFd.Revents != 0 { |
|||
events[i] = EpollEvent{Fd: pFd.Fd, Events: pToEpollEvt(pFd.Revents)} |
|||
i++ |
|||
} |
|||
|
|||
if i == n { |
|||
break |
|||
} |
|||
} |
|||
|
|||
return n, nil |
|||
} |
|||
|
|||
func EpollCreate(size int) (fd int, err error) { |
|||
return impl.epollcreate(size) |
|||
} |
|||
|
|||
func EpollCreate1(flag int) (fd int, err error) { |
|||
return impl.epollcreate1(flag) |
|||
} |
|||
|
|||
func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) { |
|||
return impl.epollctl(epfd, op, fd, event) |
|||
} |
|||
|
|||
// Because EpollWait mutates events, the caller is expected to coordinate
|
|||
// concurrent access if calling with the same epfd from multiple goroutines.
|
|||
func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { |
|||
return impl.epollwait(epfd, events, msec) |
|||
} |
@ -1,227 +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.
|
|||
|
|||
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
|
|||
// them here for backwards compatibility.
|
|||
|
|||
package unix |
|||
|
|||
const ( |
|||
IFF_SMART = 0x20 |
|||
IFT_1822 = 0x2 |
|||
IFT_A12MPPSWITCH = 0x82 |
|||
IFT_AAL2 = 0xbb |
|||
IFT_AAL5 = 0x31 |
|||
IFT_ADSL = 0x5e |
|||
IFT_AFLANE8023 = 0x3b |
|||
IFT_AFLANE8025 = 0x3c |
|||
IFT_ARAP = 0x58 |
|||
IFT_ARCNET = 0x23 |
|||
IFT_ARCNETPLUS = 0x24 |
|||
IFT_ASYNC = 0x54 |
|||
IFT_ATM = 0x25 |
|||
IFT_ATMDXI = 0x69 |
|||
IFT_ATMFUNI = 0x6a |
|||
IFT_ATMIMA = 0x6b |
|||
IFT_ATMLOGICAL = 0x50 |
|||
IFT_ATMRADIO = 0xbd |
|||
IFT_ATMSUBINTERFACE = 0x86 |
|||
IFT_ATMVCIENDPT = 0xc2 |
|||
IFT_ATMVIRTUAL = 0x95 |
|||
IFT_BGPPOLICYACCOUNTING = 0xa2 |
|||
IFT_BSC = 0x53 |
|||
IFT_CCTEMUL = 0x3d |
|||
IFT_CEPT = 0x13 |
|||
IFT_CES = 0x85 |
|||
IFT_CHANNEL = 0x46 |
|||
IFT_CNR = 0x55 |
|||
IFT_COFFEE = 0x84 |
|||
IFT_COMPOSITELINK = 0x9b |
|||
IFT_DCN = 0x8d |
|||
IFT_DIGITALPOWERLINE = 0x8a |
|||
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba |
|||
IFT_DLSW = 0x4a |
|||
IFT_DOCSCABLEDOWNSTREAM = 0x80 |
|||
IFT_DOCSCABLEMACLAYER = 0x7f |
|||
IFT_DOCSCABLEUPSTREAM = 0x81 |
|||
IFT_DS0 = 0x51 |
|||
IFT_DS0BUNDLE = 0x52 |
|||
IFT_DS1FDL = 0xaa |
|||
IFT_DS3 = 0x1e |
|||
IFT_DTM = 0x8c |
|||
IFT_DVBASILN = 0xac |
|||
IFT_DVBASIOUT = 0xad |
|||
IFT_DVBRCCDOWNSTREAM = 0x93 |
|||
IFT_DVBRCCMACLAYER = 0x92 |
|||
IFT_DVBRCCUPSTREAM = 0x94 |
|||
IFT_ENC = 0xf4 |
|||
IFT_EON = 0x19 |
|||
IFT_EPLRS = 0x57 |
|||
IFT_ESCON = 0x49 |
|||
IFT_ETHER = 0x6 |
|||
IFT_FAITH = 0xf2 |
|||
IFT_FAST = 0x7d |
|||
IFT_FASTETHER = 0x3e |
|||
IFT_FASTETHERFX = 0x45 |
|||
IFT_FDDI = 0xf |
|||
IFT_FIBRECHANNEL = 0x38 |
|||
IFT_FRAMERELAYINTERCONNECT = 0x3a |
|||
IFT_FRAMERELAYMPI = 0x5c |
|||
IFT_FRDLCIENDPT = 0xc1 |
|||
IFT_FRELAY = 0x20 |
|||
IFT_FRELAYDCE = 0x2c |
|||
IFT_FRF16MFRBUNDLE = 0xa3 |
|||
IFT_FRFORWARD = 0x9e |
|||
IFT_G703AT2MB = 0x43 |
|||
IFT_G703AT64K = 0x42 |
|||
IFT_GIF = 0xf0 |
|||
IFT_GIGABITETHERNET = 0x75 |
|||
IFT_GR303IDT = 0xb2 |
|||
IFT_GR303RDT = 0xb1 |
|||
IFT_H323GATEKEEPER = 0xa4 |
|||
IFT_H323PROXY = 0xa5 |
|||
IFT_HDH1822 = 0x3 |
|||
IFT_HDLC = 0x76 |
|||
IFT_HDSL2 = 0xa8 |
|||
IFT_HIPERLAN2 = 0xb7 |
|||
IFT_HIPPI = 0x2f |
|||
IFT_HIPPIINTERFACE = 0x39 |
|||
IFT_HOSTPAD = 0x5a |
|||
IFT_HSSI = 0x2e |
|||
IFT_HY = 0xe |
|||
IFT_IBM370PARCHAN = 0x48 |
|||
IFT_IDSL = 0x9a |
|||
IFT_IEEE80211 = 0x47 |
|||
IFT_IEEE80212 = 0x37 |
|||
IFT_IEEE8023ADLAG = 0xa1 |
|||
IFT_IFGSN = 0x91 |
|||
IFT_IMT = 0xbe |
|||
IFT_INTERLEAVE = 0x7c |
|||
IFT_IP = 0x7e |
|||
IFT_IPFORWARD = 0x8e |
|||
IFT_IPOVERATM = 0x72 |
|||
IFT_IPOVERCDLC = 0x6d |
|||
IFT_IPOVERCLAW = 0x6e |
|||
IFT_IPSWITCH = 0x4e |
|||
IFT_IPXIP = 0xf9 |
|||
IFT_ISDN = 0x3f |
|||
IFT_ISDNBASIC = 0x14 |
|||
IFT_ISDNPRIMARY = 0x15 |
|||
IFT_ISDNS = 0x4b |
|||
IFT_ISDNU = 0x4c |
|||
IFT_ISO88022LLC = 0x29 |
|||
IFT_ISO88023 = 0x7 |
|||
IFT_ISO88024 = 0x8 |
|||
IFT_ISO88025 = 0x9 |
|||
IFT_ISO88025CRFPINT = 0x62 |
|||
IFT_ISO88025DTR = 0x56 |
|||
IFT_ISO88025FIBER = 0x73 |
|||
IFT_ISO88026 = 0xa |
|||
IFT_ISUP = 0xb3 |
|||
IFT_L3IPXVLAN = 0x89 |
|||
IFT_LAPB = 0x10 |
|||
IFT_LAPD = 0x4d |
|||
IFT_LAPF = 0x77 |
|||
IFT_LOCALTALK = 0x2a |
|||
IFT_LOOP = 0x18 |
|||
IFT_MEDIAMAILOVERIP = 0x8b |
|||
IFT_MFSIGLINK = 0xa7 |
|||
IFT_MIOX25 = 0x26 |
|||
IFT_MODEM = 0x30 |
|||
IFT_MPC = 0x71 |
|||
IFT_MPLS = 0xa6 |
|||
IFT_MPLSTUNNEL = 0x96 |
|||
IFT_MSDSL = 0x8f |
|||
IFT_MVL = 0xbf |
|||
IFT_MYRINET = 0x63 |
|||
IFT_NFAS = 0xaf |
|||
IFT_NSIP = 0x1b |
|||
IFT_OPTICALCHANNEL = 0xc3 |
|||
IFT_OPTICALTRANSPORT = 0xc4 |
|||
IFT_OTHER = 0x1 |
|||
IFT_P10 = 0xc |
|||
IFT_P80 = 0xd |
|||
IFT_PARA = 0x22 |
|||
IFT_PFLOG = 0xf6 |
|||
IFT_PFSYNC = 0xf7 |
|||
IFT_PLC = 0xae |
|||
IFT_POS = 0xab |
|||
IFT_PPPMULTILINKBUNDLE = 0x6c |
|||
IFT_PROPBWAP2MP = 0xb8 |
|||
IFT_PROPCNLS = 0x59 |
|||
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5 |
|||
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4 |
|||
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6 |
|||
IFT_PROPMUX = 0x36 |
|||
IFT_PROPWIRELESSP2P = 0x9d |
|||
IFT_PTPSERIAL = 0x16 |
|||
IFT_PVC = 0xf1 |
|||
IFT_QLLC = 0x44 |
|||
IFT_RADIOMAC = 0xbc |
|||
IFT_RADSL = 0x5f |
|||
IFT_REACHDSL = 0xc0 |
|||
IFT_RFC1483 = 0x9f |
|||
IFT_RS232 = 0x21 |
|||
IFT_RSRB = 0x4f |
|||
IFT_SDLC = 0x11 |
|||
IFT_SDSL = 0x60 |
|||
IFT_SHDSL = 0xa9 |
|||
IFT_SIP = 0x1f |
|||
IFT_SLIP = 0x1c |
|||
IFT_SMDSDXI = 0x2b |
|||
IFT_SMDSICIP = 0x34 |
|||
IFT_SONET = 0x27 |
|||
IFT_SONETOVERHEADCHANNEL = 0xb9 |
|||
IFT_SONETPATH = 0x32 |
|||
IFT_SONETVT = 0x33 |
|||
IFT_SRP = 0x97 |
|||
IFT_SS7SIGLINK = 0x9c |
|||
IFT_STACKTOSTACK = 0x6f |
|||
IFT_STARLAN = 0xb |
|||
IFT_STF = 0xd7 |
|||
IFT_T1 = 0x12 |
|||
IFT_TDLC = 0x74 |
|||
IFT_TERMPAD = 0x5b |
|||
IFT_TR008 = 0xb0 |
|||
IFT_TRANSPHDLC = 0x7b |
|||
IFT_TUNNEL = 0x83 |
|||
IFT_ULTRA = 0x1d |
|||
IFT_USB = 0xa0 |
|||
IFT_V11 = 0x40 |
|||
IFT_V35 = 0x2d |
|||
IFT_V36 = 0x41 |
|||
IFT_V37 = 0x78 |
|||
IFT_VDSL = 0x61 |
|||
IFT_VIRTUALIPADDRESS = 0x70 |
|||
IFT_VOICEEM = 0x64 |
|||
IFT_VOICEENCAP = 0x67 |
|||
IFT_VOICEFXO = 0x65 |
|||
IFT_VOICEFXS = 0x66 |
|||
IFT_VOICEOVERATM = 0x98 |
|||
IFT_VOICEOVERFRAMERELAY = 0x99 |
|||
IFT_VOICEOVERIP = 0x68 |
|||
IFT_X213 = 0x5d |
|||
IFT_X25 = 0x5 |
|||
IFT_X25DDN = 0x4 |
|||
IFT_X25HUNTGROUP = 0x7a |
|||
IFT_X25MLP = 0x79 |
|||
IFT_X25PLE = 0x28 |
|||
IFT_XETHER = 0x1a |
|||
IPPROTO_MAXID = 0x34 |
|||
IPV6_FAITH = 0x1d |
|||
IP_FAITH = 0x16 |
|||
MAP_NORESERVE = 0x40 |
|||
MAP_RENAME = 0x20 |
|||
NET_RT_MAXID = 0x6 |
|||
RTF_PRCLONING = 0x10000 |
|||
RTM_OLDADD = 0x9 |
|||
RTM_OLDDEL = 0xa |
|||
SIOCADDRT = 0x8030720a |
|||
SIOCALIFADDR = 0x8118691b |
|||
SIOCDELRT = 0x8030720b |
|||
SIOCDLIFADDR = 0x8118691d |
|||
SIOCGLIFADDR = 0xc118691c |
|||
SIOCGLIFPHYADDR = 0xc118694b |
|||
SIOCSLIFPHYADDR = 0x8118694a |
|||
) |
@ -1,227 +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.
|
|||
|
|||
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
|
|||
// them here for backwards compatibility.
|
|||
|
|||
package unix |
|||
|
|||
const ( |
|||
IFF_SMART = 0x20 |
|||
IFT_1822 = 0x2 |
|||
IFT_A12MPPSWITCH = 0x82 |
|||
IFT_AAL2 = 0xbb |
|||
IFT_AAL5 = 0x31 |
|||
IFT_ADSL = 0x5e |
|||
IFT_AFLANE8023 = 0x3b |
|||
IFT_AFLANE8025 = 0x3c |
|||
IFT_ARAP = 0x58 |
|||
IFT_ARCNET = 0x23 |
|||
IFT_ARCNETPLUS = 0x24 |
|||
IFT_ASYNC = 0x54 |
|||
IFT_ATM = 0x25 |
|||
IFT_ATMDXI = 0x69 |
|||
IFT_ATMFUNI = 0x6a |
|||
IFT_ATMIMA = 0x6b |
|||
IFT_ATMLOGICAL = 0x50 |
|||
IFT_ATMRADIO = 0xbd |
|||
IFT_ATMSUBINTERFACE = 0x86 |
|||
IFT_ATMVCIENDPT = 0xc2 |
|||
IFT_ATMVIRTUAL = 0x95 |
|||
IFT_BGPPOLICYACCOUNTING = 0xa2 |
|||
IFT_BSC = 0x53 |
|||
IFT_CCTEMUL = 0x3d |
|||
IFT_CEPT = 0x13 |
|||
IFT_CES = 0x85 |
|||
IFT_CHANNEL = 0x46 |
|||
IFT_CNR = 0x55 |
|||
IFT_COFFEE = 0x84 |
|||
IFT_COMPOSITELINK = 0x9b |
|||
IFT_DCN = 0x8d |
|||
IFT_DIGITALPOWERLINE = 0x8a |
|||
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba |
|||
IFT_DLSW = 0x4a |
|||
IFT_DOCSCABLEDOWNSTREAM = 0x80 |
|||
IFT_DOCSCABLEMACLAYER = 0x7f |
|||
IFT_DOCSCABLEUPSTREAM = 0x81 |
|||
IFT_DS0 = 0x51 |
|||
IFT_DS0BUNDLE = 0x52 |
|||
IFT_DS1FDL = 0xaa |
|||
IFT_DS3 = 0x1e |
|||
IFT_DTM = 0x8c |
|||
IFT_DVBASILN = 0xac |
|||
IFT_DVBASIOUT = 0xad |
|||
IFT_DVBRCCDOWNSTREAM = 0x93 |
|||
IFT_DVBRCCMACLAYER = 0x92 |
|||
IFT_DVBRCCUPSTREAM = 0x94 |
|||
IFT_ENC = 0xf4 |
|||
IFT_EON = 0x19 |
|||
IFT_EPLRS = 0x57 |
|||
IFT_ESCON = 0x49 |
|||
IFT_ETHER = 0x6 |
|||
IFT_FAITH = 0xf2 |
|||
IFT_FAST = 0x7d |
|||
IFT_FASTETHER = 0x3e |
|||
IFT_FASTETHERFX = 0x45 |
|||
IFT_FDDI = 0xf |
|||
IFT_FIBRECHANNEL = 0x38 |
|||
IFT_FRAMERELAYINTERCONNECT = 0x3a |
|||
IFT_FRAMERELAYMPI = 0x5c |
|||
IFT_FRDLCIENDPT = 0xc1 |
|||
IFT_FRELAY = 0x20 |
|||
IFT_FRELAYDCE = 0x2c |
|||
IFT_FRF16MFRBUNDLE = 0xa3 |
|||
IFT_FRFORWARD = 0x9e |
|||
IFT_G703AT2MB = 0x43 |
|||
IFT_G703AT64K = 0x42 |
|||
IFT_GIF = 0xf0 |
|||
IFT_GIGABITETHERNET = 0x75 |
|||
IFT_GR303IDT = 0xb2 |
|||
IFT_GR303RDT = 0xb1 |
|||
IFT_H323GATEKEEPER = 0xa4 |
|||
IFT_H323PROXY = 0xa5 |
|||
IFT_HDH1822 = 0x3 |
|||
IFT_HDLC = 0x76 |
|||
IFT_HDSL2 = 0xa8 |
|||
IFT_HIPERLAN2 = 0xb7 |
|||
IFT_HIPPI = 0x2f |
|||
IFT_HIPPIINTERFACE = 0x39 |
|||
IFT_HOSTPAD = 0x5a |
|||
IFT_HSSI = 0x2e |
|||
IFT_HY = 0xe |
|||
IFT_IBM370PARCHAN = 0x48 |
|||
IFT_IDSL = 0x9a |
|||
IFT_IEEE80211 = 0x47 |
|||
IFT_IEEE80212 = 0x37 |
|||
IFT_IEEE8023ADLAG = 0xa1 |
|||
IFT_IFGSN = 0x91 |
|||
IFT_IMT = 0xbe |
|||
IFT_INTERLEAVE = 0x7c |
|||
IFT_IP = 0x7e |
|||
IFT_IPFORWARD = 0x8e |
|||
IFT_IPOVERATM = 0x72 |
|||
IFT_IPOVERCDLC = 0x6d |
|||
IFT_IPOVERCLAW = 0x6e |
|||
IFT_IPSWITCH = 0x4e |
|||
IFT_IPXIP = 0xf9 |
|||
IFT_ISDN = 0x3f |
|||
IFT_ISDNBASIC = 0x14 |
|||
IFT_ISDNPRIMARY = 0x15 |
|||
IFT_ISDNS = 0x4b |
|||
IFT_ISDNU = 0x4c |
|||
IFT_ISO88022LLC = 0x29 |
|||
IFT_ISO88023 = 0x7 |
|||
IFT_ISO88024 = 0x8 |
|||
IFT_ISO88025 = 0x9 |
|||
IFT_ISO88025CRFPINT = 0x62 |
|||
IFT_ISO88025DTR = 0x56 |
|||
IFT_ISO88025FIBER = 0x73 |
|||
IFT_ISO88026 = 0xa |
|||
IFT_ISUP = 0xb3 |
|||
IFT_L3IPXVLAN = 0x89 |
|||
IFT_LAPB = 0x10 |
|||
IFT_LAPD = 0x4d |
|||
IFT_LAPF = 0x77 |
|||
IFT_LOCALTALK = 0x2a |
|||
IFT_LOOP = 0x18 |
|||
IFT_MEDIAMAILOVERIP = 0x8b |
|||
IFT_MFSIGLINK = 0xa7 |
|||
IFT_MIOX25 = 0x26 |
|||
IFT_MODEM = 0x30 |
|||
IFT_MPC = 0x71 |
|||
IFT_MPLS = 0xa6 |
|||
IFT_MPLSTUNNEL = 0x96 |
|||
IFT_MSDSL = 0x8f |
|||
IFT_MVL = 0xbf |
|||
IFT_MYRINET = 0x63 |
|||
IFT_NFAS = 0xaf |
|||
IFT_NSIP = 0x1b |
|||
IFT_OPTICALCHANNEL = 0xc3 |
|||
IFT_OPTICALTRANSPORT = 0xc4 |
|||
IFT_OTHER = 0x1 |
|||
IFT_P10 = 0xc |
|||
IFT_P80 = 0xd |
|||
IFT_PARA = 0x22 |
|||
IFT_PFLOG = 0xf6 |
|||
IFT_PFSYNC = 0xf7 |
|||
IFT_PLC = 0xae |
|||
IFT_POS = 0xab |
|||
IFT_PPPMULTILINKBUNDLE = 0x6c |
|||
IFT_PROPBWAP2MP = 0xb8 |
|||
IFT_PROPCNLS = 0x59 |
|||
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5 |
|||
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4 |
|||
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6 |
|||
IFT_PROPMUX = 0x36 |
|||
IFT_PROPWIRELESSP2P = 0x9d |
|||
IFT_PTPSERIAL = 0x16 |
|||
IFT_PVC = 0xf1 |
|||
IFT_QLLC = 0x44 |
|||
IFT_RADIOMAC = 0xbc |
|||
IFT_RADSL = 0x5f |
|||
IFT_REACHDSL = 0xc0 |
|||
IFT_RFC1483 = 0x9f |
|||
IFT_RS232 = 0x21 |
|||
IFT_RSRB = 0x4f |
|||
IFT_SDLC = 0x11 |
|||
IFT_SDSL = 0x60 |
|||
IFT_SHDSL = 0xa9 |
|||
IFT_SIP = 0x1f |
|||
IFT_SLIP = 0x1c |
|||
IFT_SMDSDXI = 0x2b |
|||
IFT_SMDSICIP = 0x34 |
|||
IFT_SONET = 0x27 |
|||
IFT_SONETOVERHEADCHANNEL = 0xb9 |
|||
IFT_SONETPATH = 0x32 |
|||
IFT_SONETVT = 0x33 |
|||
IFT_SRP = 0x97 |
|||
IFT_SS7SIGLINK = 0x9c |
|||
IFT_STACKTOSTACK = 0x6f |
|||
IFT_STARLAN = 0xb |
|||
IFT_STF = 0xd7 |
|||
IFT_T1 = 0x12 |
|||
IFT_TDLC = 0x74 |
|||
IFT_TERMPAD = 0x5b |
|||
IFT_TR008 = 0xb0 |
|||
IFT_TRANSPHDLC = 0x7b |
|||
IFT_TUNNEL = 0x83 |
|||
IFT_ULTRA = 0x1d |
|||
IFT_USB = 0xa0 |
|||
IFT_V11 = 0x40 |
|||
IFT_V35 = 0x2d |
|||
IFT_V36 = 0x41 |
|||
IFT_V37 = 0x78 |
|||
IFT_VDSL = 0x61 |
|||
IFT_VIRTUALIPADDRESS = 0x70 |
|||
IFT_VOICEEM = 0x64 |
|||
IFT_VOICEENCAP = 0x67 |
|||
IFT_VOICEFXO = 0x65 |
|||
IFT_VOICEFXS = 0x66 |
|||
IFT_VOICEOVERATM = 0x98 |
|||
IFT_VOICEOVERFRAMERELAY = 0x99 |
|||
IFT_VOICEOVERIP = 0x68 |
|||
IFT_X213 = 0x5d |
|||
IFT_X25 = 0x5 |
|||
IFT_X25DDN = 0x4 |
|||
IFT_X25HUNTGROUP = 0x7a |
|||
IFT_X25MLP = 0x79 |
|||
IFT_X25PLE = 0x28 |
|||
IFT_XETHER = 0x1a |
|||
IPPROTO_MAXID = 0x34 |
|||
IPV6_FAITH = 0x1d |
|||
IP_FAITH = 0x16 |
|||
MAP_NORESERVE = 0x40 |
|||
MAP_RENAME = 0x20 |
|||
NET_RT_MAXID = 0x6 |
|||
RTF_PRCLONING = 0x10000 |
|||
RTM_OLDADD = 0x9 |
|||
RTM_OLDDEL = 0xa |
|||
SIOCADDRT = 0x8040720a |
|||
SIOCALIFADDR = 0x8118691b |
|||
SIOCDELRT = 0x8040720b |
|||
SIOCDLIFADDR = 0x8118691d |
|||
SIOCGLIFADDR = 0xc118691c |
|||
SIOCGLIFPHYADDR = 0xc118694b |
|||
SIOCSLIFPHYADDR = 0x8118694a |
|||
) |
@ -1,226 +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 unix |
|||
|
|||
const ( |
|||
IFT_1822 = 0x2 |
|||
IFT_A12MPPSWITCH = 0x82 |
|||
IFT_AAL2 = 0xbb |
|||
IFT_AAL5 = 0x31 |
|||
IFT_ADSL = 0x5e |
|||
IFT_AFLANE8023 = 0x3b |
|||
IFT_AFLANE8025 = 0x3c |
|||
IFT_ARAP = 0x58 |
|||
IFT_ARCNET = 0x23 |
|||
IFT_ARCNETPLUS = 0x24 |
|||
IFT_ASYNC = 0x54 |
|||
IFT_ATM = 0x25 |
|||
IFT_ATMDXI = 0x69 |
|||
IFT_ATMFUNI = 0x6a |
|||
IFT_ATMIMA = 0x6b |
|||
IFT_ATMLOGICAL = 0x50 |
|||
IFT_ATMRADIO = 0xbd |
|||
IFT_ATMSUBINTERFACE = 0x86 |
|||
IFT_ATMVCIENDPT = 0xc2 |
|||
IFT_ATMVIRTUAL = 0x95 |
|||
IFT_BGPPOLICYACCOUNTING = 0xa2 |
|||
IFT_BSC = 0x53 |
|||
IFT_CCTEMUL = 0x3d |
|||
IFT_CEPT = 0x13 |
|||
IFT_CES = 0x85 |
|||
IFT_CHANNEL = 0x46 |
|||
IFT_CNR = 0x55 |
|||
IFT_COFFEE = 0x84 |
|||
IFT_COMPOSITELINK = 0x9b |
|||
IFT_DCN = 0x8d |
|||
IFT_DIGITALPOWERLINE = 0x8a |
|||
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba |
|||
IFT_DLSW = 0x4a |
|||
IFT_DOCSCABLEDOWNSTREAM = 0x80 |
|||
IFT_DOCSCABLEMACLAYER = 0x7f |
|||
IFT_DOCSCABLEUPSTREAM = 0x81 |
|||
IFT_DS0 = 0x51 |
|||
IFT_DS0BUNDLE = 0x52 |
|||
IFT_DS1FDL = 0xaa |
|||
IFT_DS3 = 0x1e |
|||
IFT_DTM = 0x8c |
|||
IFT_DVBASILN = 0xac |
|||
IFT_DVBASIOUT = 0xad |
|||
IFT_DVBRCCDOWNSTREAM = 0x93 |
|||
IFT_DVBRCCMACLAYER = 0x92 |
|||
IFT_DVBRCCUPSTREAM = 0x94 |
|||
IFT_ENC = 0xf4 |
|||
IFT_EON = 0x19 |
|||
IFT_EPLRS = 0x57 |
|||
IFT_ESCON = 0x49 |
|||
IFT_ETHER = 0x6 |
|||
IFT_FAST = 0x7d |
|||
IFT_FASTETHER = 0x3e |
|||
IFT_FASTETHERFX = 0x45 |
|||
IFT_FDDI = 0xf |
|||
IFT_FIBRECHANNEL = 0x38 |
|||
IFT_FRAMERELAYINTERCONNECT = 0x3a |
|||
IFT_FRAMERELAYMPI = 0x5c |
|||
IFT_FRDLCIENDPT = 0xc1 |
|||
IFT_FRELAY = 0x20 |
|||
IFT_FRELAYDCE = 0x2c |
|||
IFT_FRF16MFRBUNDLE = 0xa3 |
|||
IFT_FRFORWARD = 0x9e |
|||
IFT_G703AT2MB = 0x43 |
|||
IFT_G703AT64K = 0x42 |
|||
IFT_GIF = 0xf0 |
|||
IFT_GIGABITETHERNET = 0x75 |
|||
IFT_GR303IDT = 0xb2 |
|||
IFT_GR303RDT = 0xb1 |
|||
IFT_H323GATEKEEPER = 0xa4 |
|||
IFT_H323PROXY = 0xa5 |
|||
IFT_HDH1822 = 0x3 |
|||
IFT_HDLC = 0x76 |
|||
IFT_HDSL2 = 0xa8 |
|||
IFT_HIPERLAN2 = 0xb7 |
|||
IFT_HIPPI = 0x2f |
|||
IFT_HIPPIINTERFACE = 0x39 |
|||
IFT_HOSTPAD = 0x5a |
|||
IFT_HSSI = 0x2e |
|||
IFT_HY = 0xe |
|||
IFT_IBM370PARCHAN = 0x48 |
|||
IFT_IDSL = 0x9a |
|||
IFT_IEEE80211 = 0x47 |
|||
IFT_IEEE80212 = 0x37 |
|||
IFT_IEEE8023ADLAG = 0xa1 |
|||
IFT_IFGSN = 0x91 |
|||
IFT_IMT = 0xbe |
|||
IFT_INTERLEAVE = 0x7c |
|||
IFT_IP = 0x7e |
|||
IFT_IPFORWARD = 0x8e |
|||
IFT_IPOVERATM = 0x72 |
|||
IFT_IPOVERCDLC = 0x6d |
|||
IFT_IPOVERCLAW = 0x6e |
|||
IFT_IPSWITCH = 0x4e |
|||
IFT_ISDN = 0x3f |
|||
IFT_ISDNBASIC = 0x14 |
|||
IFT_ISDNPRIMARY = 0x15 |
|||
IFT_ISDNS = 0x4b |
|||
IFT_ISDNU = 0x4c |
|||
IFT_ISO88022LLC = 0x29 |
|||
IFT_ISO88023 = 0x7 |
|||
IFT_ISO88024 = 0x8 |
|||
IFT_ISO88025 = 0x9 |
|||
IFT_ISO88025CRFPINT = 0x62 |
|||
IFT_ISO88025DTR = 0x56 |
|||
IFT_ISO88025FIBER = 0x73 |
|||
IFT_ISO88026 = 0xa |
|||
IFT_ISUP = 0xb3 |
|||
IFT_L3IPXVLAN = 0x89 |
|||
IFT_LAPB = 0x10 |
|||
IFT_LAPD = 0x4d |
|||
IFT_LAPF = 0x77 |
|||
IFT_LOCALTALK = 0x2a |
|||
IFT_LOOP = 0x18 |
|||
IFT_MEDIAMAILOVERIP = 0x8b |
|||
IFT_MFSIGLINK = 0xa7 |
|||
IFT_MIOX25 = 0x26 |
|||
IFT_MODEM = 0x30 |
|||
IFT_MPC = 0x71 |
|||
IFT_MPLS = 0xa6 |
|||
IFT_MPLSTUNNEL = 0x96 |
|||
IFT_MSDSL = 0x8f |
|||
IFT_MVL = 0xbf |
|||
IFT_MYRINET = 0x63 |
|||
IFT_NFAS = 0xaf |
|||
IFT_NSIP = 0x1b |
|||
IFT_OPTICALCHANNEL = 0xc3 |
|||
IFT_OPTICALTRANSPORT = 0xc4 |
|||
IFT_OTHER = 0x1 |
|||
IFT_P10 = 0xc |
|||
IFT_P80 = 0xd |
|||
IFT_PARA = 0x22 |
|||
IFT_PFLOG = 0xf6 |
|||
IFT_PFSYNC = 0xf7 |
|||
IFT_PLC = 0xae |
|||
IFT_POS = 0xab |
|||
IFT_PPPMULTILINKBUNDLE = 0x6c |
|||
IFT_PROPBWAP2MP = 0xb8 |
|||
IFT_PROPCNLS = 0x59 |
|||
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5 |
|||
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4 |
|||
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6 |
|||
IFT_PROPMUX = 0x36 |
|||
IFT_PROPWIRELESSP2P = 0x9d |
|||
IFT_PTPSERIAL = 0x16 |
|||
IFT_PVC = 0xf1 |
|||
IFT_QLLC = 0x44 |
|||
IFT_RADIOMAC = 0xbc |
|||
IFT_RADSL = 0x5f |
|||
IFT_REACHDSL = 0xc0 |
|||
IFT_RFC1483 = 0x9f |
|||
IFT_RS232 = 0x21 |
|||
IFT_RSRB = 0x4f |
|||
IFT_SDLC = 0x11 |
|||
IFT_SDSL = 0x60 |
|||
IFT_SHDSL = 0xa9 |
|||
IFT_SIP = 0x1f |
|||
IFT_SLIP = 0x1c |
|||
IFT_SMDSDXI = 0x2b |
|||
IFT_SMDSICIP = 0x34 |
|||
IFT_SONET = 0x27 |
|||
IFT_SONETOVERHEADCHANNEL = 0xb9 |
|||
IFT_SONETPATH = 0x32 |
|||
IFT_SONETVT = 0x33 |
|||
IFT_SRP = 0x97 |
|||
IFT_SS7SIGLINK = 0x9c |
|||
IFT_STACKTOSTACK = 0x6f |
|||
IFT_STARLAN = 0xb |
|||
IFT_STF = 0xd7 |
|||
IFT_T1 = 0x12 |
|||
IFT_TDLC = 0x74 |
|||
IFT_TERMPAD = 0x5b |
|||
IFT_TR008 = 0xb0 |
|||
IFT_TRANSPHDLC = 0x7b |
|||
IFT_TUNNEL = 0x83 |
|||
IFT_ULTRA = 0x1d |
|||
IFT_USB = 0xa0 |
|||
IFT_V11 = 0x40 |
|||
IFT_V35 = 0x2d |
|||
IFT_V36 = 0x41 |
|||
IFT_V37 = 0x78 |
|||
IFT_VDSL = 0x61 |
|||
IFT_VIRTUALIPADDRESS = 0x70 |
|||
IFT_VOICEEM = 0x64 |
|||
IFT_VOICEENCAP = 0x67 |
|||
IFT_VOICEFXO = 0x65 |
|||
IFT_VOICEFXS = 0x66 |
|||
IFT_VOICEOVERATM = 0x98 |
|||
IFT_VOICEOVERFRAMERELAY = 0x99 |
|||
IFT_VOICEOVERIP = 0x68 |
|||
IFT_X213 = 0x5d |
|||
IFT_X25 = 0x5 |
|||
IFT_X25DDN = 0x4 |
|||
IFT_X25HUNTGROUP = 0x7a |
|||
IFT_X25MLP = 0x79 |
|||
IFT_X25PLE = 0x28 |
|||
IFT_XETHER = 0x1a |
|||
|
|||
// missing constants on FreeBSD-11.1-RELEASE, copied from old values in ztypes_freebsd_arm.go
|
|||
IFF_SMART = 0x20 |
|||
IFT_FAITH = 0xf2 |
|||
IFT_IPXIP = 0xf9 |
|||
IPPROTO_MAXID = 0x34 |
|||
IPV6_FAITH = 0x1d |
|||
IP_FAITH = 0x16 |
|||
MAP_NORESERVE = 0x40 |
|||
MAP_RENAME = 0x20 |
|||
NET_RT_MAXID = 0x6 |
|||
RTF_PRCLONING = 0x10000 |
|||
RTM_OLDADD = 0x9 |
|||
RTM_OLDDEL = 0xa |
|||
SIOCADDRT = 0x8030720a |
|||
SIOCALIFADDR = 0x8118691b |
|||
SIOCDELRT = 0x8030720b |
|||
SIOCDLIFADDR = 0x8118691d |
|||
SIOCGLIFADDR = 0xc118691c |
|||
SIOCGLIFPHYADDR = 0xc118694b |
|||
SIOCSLIFPHYADDR = 0x8118694a |
|||
) |
@ -0,0 +1,30 @@ |
|||
// Copyright 2019 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.
|
|||
|
|||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
|
|||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
|
|||
|
|||
package unix |
|||
|
|||
// Set adds fd to the set fds.
|
|||
func (fds *FdSet) Set(fd int) { |
|||
fds.Bits[fd/NFDBITS] |= (1 << (uintptr(fd) % NFDBITS)) |
|||
} |
|||
|
|||
// Clear removes fd from the set fds.
|
|||
func (fds *FdSet) Clear(fd int) { |
|||
fds.Bits[fd/NFDBITS] &^= (1 << (uintptr(fd) % NFDBITS)) |
|||
} |
|||
|
|||
// IsSet returns whether fd is in the set fds.
|
|||
func (fds *FdSet) IsSet(fd int) bool { |
|||
return fds.Bits[fd/NFDBITS]&(1<<(uintptr(fd)%NFDBITS)) != 0 |
|||
} |
|||
|
|||
// Zero clears the set fds.
|
|||
func (fds *FdSet) Zero() { |
|||
for i := range fds.Bits { |
|||
fds.Bits[i] = 0 |
|||
} |
|||
} |
@ -0,0 +1,164 @@ |
|||
// Copyright 2020 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.
|
|||
|
|||
//go:build zos && s390x
|
|||
// +build zos,s390x
|
|||
|
|||
package unix |
|||
|
|||
import ( |
|||
"unsafe" |
|||
) |
|||
|
|||
// This file simulates fstatfs on z/OS using fstatvfs and w_getmntent.
|
|||
|
|||
func Fstatfs(fd int, stat *Statfs_t) (err error) { |
|||
var stat_v Statvfs_t |
|||
err = Fstatvfs(fd, &stat_v) |
|||
if err == nil { |
|||
// populate stat
|
|||
stat.Type = 0 |
|||
stat.Bsize = stat_v.Bsize |
|||
stat.Blocks = stat_v.Blocks |
|||
stat.Bfree = stat_v.Bfree |
|||
stat.Bavail = stat_v.Bavail |
|||
stat.Files = stat_v.Files |
|||
stat.Ffree = stat_v.Ffree |
|||
stat.Fsid = stat_v.Fsid |
|||
stat.Namelen = stat_v.Namemax |
|||
stat.Frsize = stat_v.Frsize |
|||
stat.Flags = stat_v.Flag |
|||
for passn := 0; passn < 5; passn++ { |
|||
switch passn { |
|||
case 0: |
|||
err = tryGetmntent64(stat) |
|||
break |
|||
case 1: |
|||
err = tryGetmntent128(stat) |
|||
break |
|||
case 2: |
|||
err = tryGetmntent256(stat) |
|||
break |
|||
case 3: |
|||
err = tryGetmntent512(stat) |
|||
break |
|||
case 4: |
|||
err = tryGetmntent1024(stat) |
|||
break |
|||
default: |
|||
break |
|||
} |
|||
//proceed to return if: err is nil (found), err is nonnil but not ERANGE (another error occurred)
|
|||
if err == nil || err != nil && err != ERANGE { |
|||
break |
|||
} |
|||
} |
|||
} |
|||
return err |
|||
} |
|||
|
|||
func tryGetmntent64(stat *Statfs_t) (err error) { |
|||
var mnt_ent_buffer struct { |
|||
header W_Mnth |
|||
filesys_info [64]W_Mntent |
|||
} |
|||
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer)) |
|||
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
err = ERANGE //return ERANGE if no match is found in this batch
|
|||
for i := 0; i < fs_count; i++ { |
|||
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) { |
|||
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0]) |
|||
err = nil |
|||
break |
|||
} |
|||
} |
|||
return err |
|||
} |
|||
|
|||
func tryGetmntent128(stat *Statfs_t) (err error) { |
|||
var mnt_ent_buffer struct { |
|||
header W_Mnth |
|||
filesys_info [128]W_Mntent |
|||
} |
|||
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer)) |
|||
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
err = ERANGE //return ERANGE if no match is found in this batch
|
|||
for i := 0; i < fs_count; i++ { |
|||
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) { |
|||
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0]) |
|||
err = nil |
|||
break |
|||
} |
|||
} |
|||
return err |
|||
} |
|||
|
|||
func tryGetmntent256(stat *Statfs_t) (err error) { |
|||
var mnt_ent_buffer struct { |
|||
header W_Mnth |
|||
filesys_info [256]W_Mntent |
|||
} |
|||
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer)) |
|||
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
err = ERANGE //return ERANGE if no match is found in this batch
|
|||
for i := 0; i < fs_count; i++ { |
|||
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) { |
|||
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0]) |
|||
err = nil |
|||
break |
|||
} |
|||
} |
|||
return err |
|||
} |
|||
|
|||
func tryGetmntent512(stat *Statfs_t) (err error) { |
|||
var mnt_ent_buffer struct { |
|||
header W_Mnth |
|||
filesys_info [512]W_Mntent |
|||
} |
|||
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer)) |
|||
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
err = ERANGE //return ERANGE if no match is found in this batch
|
|||
for i := 0; i < fs_count; i++ { |
|||
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) { |
|||
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0]) |
|||
err = nil |
|||
break |
|||
} |
|||
} |
|||
return err |
|||
} |
|||
|
|||
func tryGetmntent1024(stat *Statfs_t) (err error) { |
|||
var mnt_ent_buffer struct { |
|||
header W_Mnth |
|||
filesys_info [1024]W_Mntent |
|||
} |
|||
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer)) |
|||
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
err = ERANGE //return ERANGE if no match is found in this batch
|
|||
for i := 0; i < fs_count; i++ { |
|||
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) { |
|||
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0]) |
|||
err = nil |
|||
break |
|||
} |
|||
} |
|||
return err |
|||
} |
@ -0,0 +1,142 @@ |
|||
// Copyright 2021 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.
|
|||
|
|||
//go:build linux
|
|||
// +build linux
|
|||
|
|||
package unix |
|||
|
|||
import ( |
|||
"unsafe" |
|||
) |
|||
|
|||
// Helpers for dealing with ifreq since it contains a union and thus requires a
|
|||
// lot of unsafe.Pointer casts to use properly.
|
|||
|
|||
// An Ifreq is a type-safe wrapper around the raw ifreq struct. An Ifreq
|
|||
// contains an interface name and a union of arbitrary data which can be
|
|||
// accessed using the Ifreq's methods. To create an Ifreq, use the NewIfreq
|
|||
// function.
|
|||
//
|
|||
// Use the Name method to access the stored interface name. The union data
|
|||
// fields can be get and set using the following methods:
|
|||
// - Uint16/SetUint16: flags
|
|||
// - Uint32/SetUint32: ifindex, metric, mtu
|
|||
type Ifreq struct{ raw ifreq } |
|||
|
|||
// NewIfreq creates an Ifreq with the input network interface name after
|
|||
// validating the name does not exceed IFNAMSIZ-1 (trailing NULL required)
|
|||
// bytes.
|
|||
func NewIfreq(name string) (*Ifreq, error) { |
|||
// Leave room for terminating NULL byte.
|
|||
if len(name) >= IFNAMSIZ { |
|||
return nil, EINVAL |
|||
} |
|||
|
|||
var ifr ifreq |
|||
copy(ifr.Ifrn[:], name) |
|||
|
|||
return &Ifreq{raw: ifr}, nil |
|||
} |
|||
|
|||
// TODO(mdlayher): get/set methods for hardware address sockaddr, char array, etc.
|
|||
|
|||
// Name returns the interface name associated with the Ifreq.
|
|||
func (ifr *Ifreq) Name() string { |
|||
return ByteSliceToString(ifr.raw.Ifrn[:]) |
|||
} |
|||
|
|||
// According to netdevice(7), only AF_INET addresses are returned for numerous
|
|||
// sockaddr ioctls. For convenience, we expose these as Inet4Addr since the Port
|
|||
// field and other data is always empty.
|
|||
|
|||
// Inet4Addr returns the Ifreq union data from an embedded sockaddr as a C
|
|||
// in_addr/Go []byte (4-byte IPv4 address) value. If the sockaddr family is not
|
|||
// AF_INET, an error is returned.
|
|||
func (ifr *Ifreq) Inet4Addr() ([]byte, error) { |
|||
raw := *(*RawSockaddrInet4)(unsafe.Pointer(&ifr.raw.Ifru[:SizeofSockaddrInet4][0])) |
|||
if raw.Family != AF_INET { |
|||
// Cannot safely interpret raw.Addr bytes as an IPv4 address.
|
|||
return nil, EINVAL |
|||
} |
|||
|
|||
return raw.Addr[:], nil |
|||
} |
|||
|
|||
// SetInet4Addr sets a C in_addr/Go []byte (4-byte IPv4 address) value in an
|
|||
// embedded sockaddr within the Ifreq's union data. v must be 4 bytes in length
|
|||
// or an error will be returned.
|
|||
func (ifr *Ifreq) SetInet4Addr(v []byte) error { |
|||
if len(v) != 4 { |
|||
return EINVAL |
|||
} |
|||
|
|||
var addr [4]byte |
|||
copy(addr[:], v) |
|||
|
|||
ifr.clear() |
|||
*(*RawSockaddrInet4)( |
|||
unsafe.Pointer(&ifr.raw.Ifru[:SizeofSockaddrInet4][0]), |
|||
) = RawSockaddrInet4{ |
|||
// Always set IP family as ioctls would require it anyway.
|
|||
Family: AF_INET, |
|||
Addr: addr, |
|||
} |
|||
|
|||
return nil |
|||
} |
|||
|
|||
// Uint16 returns the Ifreq union data as a C short/Go uint16 value.
|
|||
func (ifr *Ifreq) Uint16() uint16 { |
|||
return *(*uint16)(unsafe.Pointer(&ifr.raw.Ifru[:2][0])) |
|||
} |
|||
|
|||
// SetUint16 sets a C short/Go uint16 value as the Ifreq's union data.
|
|||
func (ifr *Ifreq) SetUint16(v uint16) { |
|||
ifr.clear() |
|||
*(*uint16)(unsafe.Pointer(&ifr.raw.Ifru[:2][0])) = v |
|||
} |
|||
|
|||
// Uint32 returns the Ifreq union data as a C int/Go uint32 value.
|
|||
func (ifr *Ifreq) Uint32() uint32 { |
|||
return *(*uint32)(unsafe.Pointer(&ifr.raw.Ifru[:4][0])) |
|||
} |
|||
|
|||
// SetUint32 sets a C int/Go uint32 value as the Ifreq's union data.
|
|||
func (ifr *Ifreq) SetUint32(v uint32) { |
|||
ifr.clear() |
|||
*(*uint32)(unsafe.Pointer(&ifr.raw.Ifru[:4][0])) = v |
|||
} |
|||
|
|||
// clear zeroes the ifreq's union field to prevent trailing garbage data from
|
|||
// being sent to the kernel if an ifreq is reused.
|
|||
func (ifr *Ifreq) clear() { |
|||
for i := range ifr.raw.Ifru { |
|||
ifr.raw.Ifru[i] = 0 |
|||
} |
|||
} |
|||
|
|||
// TODO(mdlayher): export as IfreqData? For now we can provide helpers such as
|
|||
// IoctlGetEthtoolDrvinfo which use these APIs under the hood.
|
|||
|
|||
// An ifreqData is an Ifreq which carries pointer data. To produce an ifreqData,
|
|||
// use the Ifreq.withData method.
|
|||
type ifreqData struct { |
|||
name [IFNAMSIZ]byte |
|||
// A type separate from ifreq is required in order to comply with the
|
|||
// unsafe.Pointer rules since the "pointer-ness" of data would not be
|
|||
// preserved if it were cast into the byte array of a raw ifreq.
|
|||
data unsafe.Pointer |
|||
// Pad to the same size as ifreq.
|
|||
_ [len(ifreq{}.Ifru) - SizeofPtr]byte |
|||
} |
|||
|
|||
// withData produces an ifreqData with the pointer p set for ioctls which require
|
|||
// arbitrary pointer data.
|
|||
func (ifr Ifreq) withData(p unsafe.Pointer) ifreqData { |
|||
return ifreqData{ |
|||
name: ifr.raw.Ifrn, |
|||
data: p, |
|||
} |
|||
} |
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue