adds byteexec to run the embedded wireguard-go

This commit is contained in:
Marvin Steadfast 2021-01-20 15:03:21 +01:00
parent 6286af0891
commit e736942f01
56 changed files with 5169 additions and 6 deletions

1
.gitignore vendored
View File

@ -83,3 +83,4 @@ fabric.properties
wg-quicker
assets/*
dist/*
bin/*

View File

@ -16,17 +16,19 @@ all: clean wg-quicker
.PHONY: clean
clean:
# rm wg-quicker || true
rm wg-quicker || true
rm -rf assets || true
rm -rf /tmp/wireguard-go || true
rm -rf bin || true
.PHONY: wireguard-go
wireguard-go: clean
mkdir bin
cd /tmp; \
git clone $(WIREGUARD-GO_REPO); \
cd wireguard-go; \
git checkout -b $(WIREGUARD-GO_VERSION) $(WIREGUARD-GO_VERSION); \
GOOS=linux GOARCH=$(GOARCH) $(GOARMLINE) $(GO) build -v -o wireguard-go $(GOFLAGS) .
mv /tmp/wireguard-go/wireguard-go bin/wireguard-go
.PHONY: generate
generate: wireguard-go

2
gen.go
View File

@ -1,3 +1,3 @@
package wgquick
//go:generate go-bindata -pkg assets -o assets/bindata.go -nomemcopy /tmp/wireguard-go/wireguard-go
//go:generate go-bindata -pkg assets -o assets/bindata.go -nomemcopy bin/wireguard-go

3
go.mod
View File

@ -3,6 +3,9 @@ module go.xsfx.dev/wg-quicker
go 1.12
require (
github.com/getlantern/byteexec v0.0.0-20170405023437-4cfb26ec74f4
github.com/getlantern/filepersist v0.0.0-20160317154340-c5f0cd24e799 // indirect
github.com/getlantern/golog v0.0.0-20201105130739-9586b8bde3a9 // indirect
github.com/sirupsen/logrus v1.4.0
github.com/stretchr/testify v1.3.0
github.com/vishvananda/netlink v1.0.0

20
go.sum
View File

@ -2,6 +2,24 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/getlantern/byteexec v0.0.0-20170405023437-4cfb26ec74f4 h1:Nqmy8i81dzokjNHpyOg24gnQBeGRF7D51m8HmBRNn0Y=
github.com/getlantern/byteexec v0.0.0-20170405023437-4cfb26ec74f4/go.mod h1:4WCQkaCIwta0KlF9bQZA1jYqp8bzIS2PeCqjnef8nZ8=
github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 h1:NRUJuo3v3WGC/g5YiyF790gut6oQr5f3FBI88Wv0dx4=
github.com/getlantern/context v0.0.0-20190109183933-c447772a6520/go.mod h1:L+mq6/vvYHKjCX2oez0CgEAJmbq1fbb/oNJIWQkBybY=
github.com/getlantern/errors v1.0.1 h1:XukU2whlh7OdpxnkXhNH9VTLVz0EVPGKDV5K0oWhvzw=
github.com/getlantern/errors v1.0.1/go.mod h1:l+xpFBrCtDLpK9qNjxs+cHU6+BAdlBaxHqikB6Lku3A=
github.com/getlantern/filepersist v0.0.0-20160317154340-c5f0cd24e799 h1:FhkPUYCQYmoxS02r2GRrIV7dahUIncRl36xzs3/mnjA=
github.com/getlantern/filepersist v0.0.0-20160317154340-c5f0cd24e799/go.mod h1:8DGAx0LNUfXNnEH+fXI0s3OCBA/351kZCiz/8YSK3i8=
github.com/getlantern/golog v0.0.0-20201105130739-9586b8bde3a9 h1:8MYJU90rB1bsavemKSAuDKBjtAKo5xq95bEPOnzV7CE=
github.com/getlantern/golog v0.0.0-20201105130739-9586b8bde3a9/go.mod h1:ZyIjgH/1wTCl+B+7yH1DqrWp6MPJqESmwmEQ89ZfhvA=
github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7 h1:micT5vkcr9tOVk1FiH8SWKID8ultN44Z+yzd2y/Vyb0=
github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7/go.mod h1:dD3CgOrwlzca8ed61CsZouQS5h5jIzkK9ZWrTcf0s+o=
github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55 h1:XYzSdCbkzOC0FDNrgJqGRo8PCMFOBFL9py72DRs7bmc=
github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55/go.mod h1:6mmzY2kW1TOOrVy+r41Za2MxXM+hhqTtY3oBKd2AgFA=
github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f h1:wrYrQttPS8FHIRSlsrcuKazukx/xqO/PpLZzZXsF+EA=
github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f/go.mod h1:D5ao98qkA6pxftxoqzibIBBrLSUli+kYnJqrgBf9cIA=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
@ -18,6 +36,8 @@ github.com/mdlayher/netlink v0.0.0-20191009155606-de872b0d824b h1:W3er9pI7mt2gOq
github.com/mdlayher/netlink v0.0.0-20191009155606-de872b0d824b/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M=
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721 h1:RlZweED6sbSArvlE924+mUcZuXKLBHA35U7LN621Bws=
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721/go.mod h1:Ickgr2WtCLZ2MDGd4Gr0geeCH5HybhRJbonOgQpvSxc=
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw=
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.4.0 h1:yKenngtzGh+cUSSh6GWbxW2abRqhYUSR/t/6+2QqNvE=

14
vendor/github.com/getlantern/byteexec/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,14 @@
language: go
go:
- 1.4.1
install:
- go get -d -t -v ./...
- go build -v ./...
- go get golang.org/x/tools/cmd/cover
- go get -v github.com/axw/gocov/gocov
- go get -v github.com/mattn/goveralls
script:
- $HOME/gopath/bin/goveralls -v -service travis-ci github.com/getlantern/byteexec

202
vendor/github.com/getlantern/byteexec/LICENSE generated vendored Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2014 Brave New Software Project, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,27 @@
MiniUPnPc
Copyright (c) 2005-2011, Thomas BERNARD
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

14
vendor/github.com/getlantern/byteexec/README.md generated vendored Normal file
View File

@ -0,0 +1,14 @@
byteexec [![Travis CI Status](https://travis-ci.org/getlantern/byteexec.svg?branch=master)](https://travis-ci.org/getlantern/byteexec) [![Coverage Status](https://coveralls.io/repos/getlantern/byteexec/badge.png)](https://coveralls.io/r/getlantern/byteexec) [![GoDoc](https://godoc.org/github.com/getlantern/byteexec?status.png)](http://godoc.org/github.com/getlantern/byteexec)
==========
byteexec provides a Golang package that allows executing files that are stored
as Go byte arrays. This is handy when combined with
[go-bindata](https://github.com/jteeuwen/go-bindata).
To install:
`go get github.com/getlantern/byteexec`
For docs:
`godoc github.com/getlantern/byteexec`

118
vendor/github.com/getlantern/byteexec/byteexec.go generated vendored Normal file
View File

@ -0,0 +1,118 @@
// Package byteexec provides a very basic facility for running executables
// supplied as byte arrays, which is handy when used with
// github.com/jteeuwen/go-bindata.
//
// byteexec works by storing the provided command in a file.
//
// Example Usage:
//
// programBytes := // read bytes from somewhere
// be, err := byteexec.New(programBytes, "new/path/to/executable")
// if err != nil {
// log.Fatalf("Uh oh: %s", err)
// }
// cmd := be.Command("arg1", "arg2")
// // cmd is an os/exec.Cmd
// err = cmd.Run()
//
// Note - byteexec.New is somewhat expensive, and Exec is safe for concurrent
// use, so it's advisable to create only one Exec for each executable.
package byteexec
import (
"fmt"
"os"
"os/exec"
"os/user"
"path/filepath"
"sync"
"github.com/getlantern/filepersist"
"github.com/getlantern/golog"
)
var (
log = golog.LoggerFor("Exec")
fileMode = os.FileMode(0744)
initMutex sync.Mutex
)
// Exec is a handle to an executable that can be used to create an exec.Cmd
// using the Command method. Exec is safe for concurrent use.
type Exec struct {
Filename string
}
// New creates a new Exec using the program stored in the provided data, at the
// provided filename (relative or absolute path allowed). If the path given is
// a relative path, the executable will be placed in one of the following
// locations:
//
// On Windows - %APPDATA%/byteexec
// On OSX - ~/Library/Application Support/byteexec
// All Others - ~/.byteexec
//
// Creating a new Exec can be somewhat expensive, so it's best to create only
// one Exec per executable and reuse that.
//
// WARNING - if a file already exists at this location and its contents differ
// from data, Exec will attempt to overwrite it.
func New(data []byte, filename string) (*Exec, error) {
log.Tracef("Creating new at %v", filename)
// Use initMutex to synchronize file operations by this process
initMutex.Lock()
defer initMutex.Unlock()
var err error
if !filepath.IsAbs(filename) {
filename, err = inStandardDir(filename)
if err != nil {
return nil, err
}
}
filename = renameExecutable(filename)
log.Tracef("Placing executable in %s", filename)
err = filepersist.Save(filename, data, fileMode)
if err != nil {
return nil, err
}
log.Trace("File saved, returning new Exec")
return newExec(filename)
}
// Command creates an exec.Cmd using the supplied args.
func (be *Exec) Command(args ...string) *exec.Cmd {
return exec.Command(be.Filename, args...)
}
func newExec(filename string) (*Exec, error) {
absolutePath, err := filepath.Abs(filename)
if err != nil {
return nil, err
}
return &Exec{Filename: absolutePath}, nil
}
func inStandardDir(filename string) (string, error) {
folder, err := pathForRelativeFiles()
if err != nil {
return "", err
}
err = os.MkdirAll(folder, fileMode)
if err != nil {
return "", fmt.Errorf("Unable to make folder %s: %s", folder, err)
}
return filepath.Join(folder, filename), nil
}
func inHomeDir(filename string) (string, error) {
log.Tracef("Determining user's home directory")
usr, err := user.Current()
if err != nil {
return "", fmt.Errorf("Unable to determine user's home directory: %s", err)
}
return filepath.Join(usr.HomeDir, filename), nil
}

View File

@ -0,0 +1,5 @@
// +build !windows
package byteexec
const linefeed = "\n"

View File

@ -0,0 +1,3 @@
package byteexec
const linefeed = "\r\n"

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

11
vendor/github.com/getlantern/byteexec/rename_darwin.go generated vendored Normal file
View File

@ -0,0 +1,11 @@
// +build !windows
package byteexec
func renameExecutable(orig string) string {
return orig
}
func pathForRelativeFiles() (string, error) {
return inHomeDir("Library/Application Support/byteexec")
}

11
vendor/github.com/getlantern/byteexec/rename_stub.go generated vendored Normal file
View File

@ -0,0 +1,11 @@
// +build !windows,!darwin
package byteexec
func renameExecutable(orig string) string {
return orig
}
func pathForRelativeFiles() (string, error) {
return inHomeDir(".byteexec")
}

View File

@ -0,0 +1,14 @@
package byteexec
import (
"os"
"path/filepath"
)
func renameExecutable(orig string) string {
return orig + ".exe"
}
func pathForRelativeFiles() (string, error) {
return filepath.Join(os.Getenv("APPDATA"), "byteexec"), nil
}

15
vendor/github.com/getlantern/context/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,15 @@
language: go
go:
- 1.6.2
install:
- go get -d -t -v ./...
- go build -v ./...
- go get golang.org/x/tools/cmd/cover
- go get -v github.com/axw/gocov/gocov
- go get -v github.com/mattn/goveralls
script:
- go test -race -v -covermode=atomic -coverprofile=profile.cov
- $HOME/gopath/bin/goveralls -coverprofile=profile.cov -service=travis-ci

202
vendor/github.com/getlantern/context/LICENSE generated vendored Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2016 Brave New Software Project, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

6
vendor/github.com/getlantern/context/README.md generated vendored Normal file
View File

@ -0,0 +1,6 @@
# context [![Travis CI Status](https://travis-ci.org/getlantern/context.svg?branch=master)](https://travis-ci.org/getlantern/context) [![Coverage Status](https://coveralls.io/repos/getlantern/context/badge.png?branch=master)](https://coveralls.io/r/getlantern/context)
Provides goroutine-based context state inspired by https://github.com/tylerb/gls
and https://github.com/jtolds/gls. It uses the same basic hack as tylerb's
library, but adds a stack abstraction that allows nested contexts similar to
jtolds' library, but using `Enter()` and `Exit()` instead of callback functions.

309
vendor/github.com/getlantern/context/context.go generated vendored Normal file
View File

@ -0,0 +1,309 @@
// Package context provides a mechanism for transparently tracking contextual
// state associated to the current goroutine and even across goroutines.
package context
import (
"sync"
)
// Manager provides the ability to create and access Contexts.
type Manager interface {
// Enter enters a new level on the current Context stack, creating a new Context
// if necessary.
Enter() Context
// Go starts the given function on a new goroutine but sharing the context of
// the current goroutine (if it has one).
Go(func())
// PutGlobal puts the given key->value pair into the global context.
PutGlobal(key string, value interface{})
// PutGlobalDynamic puts a key->value pair into the global context where the
// value is generated by a function that gets evaluated at every Read. If the
// value is a map[string]interface{}, we will unpack the map and set each
// contained key->value pair independently.
PutGlobalDynamic(key string, valueFN func() interface{})
// AsMap returns a map containing all values from the supplied obj if it is a
// Contextual, plus any addition values from along the stack, plus globals if so
// specified.
AsMap(obj interface{}, includeGlobals bool) Map
}
type manager struct {
contexts map[uint64]*context
mxContexts sync.RWMutex
global Map
mxGlobal sync.RWMutex
}
// NewManager creates a new Manager
func NewManager() Manager {
return &manager{
contexts: make(map[uint64]*context),
global: make(Map),
}
}
// Contextual is an interface for anything that maintains its own context.
type Contextual interface {
// Fill fills the given Map with all of this Contextual's context
Fill(m Map)
}
// Map is a map of key->value pairs.
type Map map[string]interface{}
// Fill implements the method from the Contextual interface.
func (_m Map) Fill(m Map) {
for key, value := range _m {
m[key] = value
}
}
// Context is a context containing key->value pairs
type Context interface {
// Enter enters a new level on this Context stack.
Enter() Context
// Go starts the given function on a new goroutine.
Go(fn func())
// Exit exits the current level on this Context stack.
Exit()
// Put puts a key->value pair into the current level of the context stack.
Put(key string, value interface{}) Context
// PutIfAbsent puts the given key->value pair into the current level of the
// context stack if and only if that key is defined nowhere within the context
// stack (including parent contexts).
PutIfAbsent(key string, value interface{}) Context
// PutDynamic puts a key->value pair into the current level of the context
// stack where the value is generated by a function that gets evaluated at
// every Read. If the value is a map[string]interface{}, we will unpack the
// map and set each contained key->value pair independently.
PutDynamic(key string, valueFN func() interface{}) Context
// Fill fills the given map with data from this Context
Fill(m Map)
// AsMap returns a map containing all values from the supplied obj if it is a
// Contextual, plus any addition values from along the stack, plus globals if
// so specified.
AsMap(obj interface{}, includeGlobals bool) Map
}
type context struct {
cm *manager
id uint64
parent *context
branchedFrom *context
data Map
mx sync.RWMutex
}
type dynval struct {
fn func() interface{}
}
func (cm *manager) Enter() Context {
return cm.enter(curGoroutineID())
}
func (cm *manager) enter(id uint64) *context {
cm.mxContexts.Lock()
parentOrNil := cm.contexts[id]
c := cm.makeContext(id, parentOrNil, nil)
cm.contexts[id] = c
cm.mxContexts.Unlock()
return c
}
func (cm *manager) exit(id uint64, parent *context) {
cm.mxContexts.Lock()
if parent == nil {
delete(cm.contexts, id)
} else {
cm.contexts[id] = parent
}
cm.mxContexts.Unlock()
}
func (cm *manager) branch(id uint64, from *context) {
next := cm.makeContext(id, nil, from)
cm.mxContexts.Lock()
cm.contexts[id] = next
cm.mxContexts.Unlock()
}
func (cm *manager) merge(id uint64) {
cm.mxContexts.Lock()
delete(cm.contexts, id)
cm.mxContexts.Unlock()
}
func (c *context) Enter() Context {
c.mx.RLock()
id := c.id
c.mx.RUnlock()
return c.cm.enter(id)
}
func (c *context) Go(fn func()) {
go func() {
id := curGoroutineID()
c.cm.branch(id, c)
fn()
c.cm.merge(id)
}()
}
func (cm *manager) Go(fn func()) {
c := cm.currentContext()
if c != nil {
c.Go(fn)
} else {
go fn()
}
}
func (cm *manager) makeContext(id uint64, parent *context, branchedFrom *context) *context {
return &context{
cm: cm,
id: id,
parent: parent,
branchedFrom: branchedFrom,
data: make(Map),
}
}
func (c *context) Exit() {
c.mx.RLock()
id := c.id
parent := c.parent
c.mx.RUnlock()
c.cm.exit(id, parent)
}
func (c *context) Put(key string, value interface{}) Context {
c.mx.Lock()
c.data[key] = value
c.mx.Unlock()
return c
}
func (c *context) PutIfAbsent(key string, value interface{}) Context {
for ctx := c; ctx != nil; {
ctx.mx.RLock()
_, exists := ctx.data[key]
next := ctx.parent
if next == nil {
next = ctx.branchedFrom
}
ctx.mx.RUnlock()
if exists {
return c
}
ctx = next
}
// Value not set, set it
return c.Put(key, value)
}
func (c *context) PutDynamic(key string, valueFN func() interface{}) Context {
value := &dynval{valueFN}
c.mx.Lock()
c.data[key] = value
c.mx.Unlock()
return c
}
func (cm *manager) PutGlobal(key string, value interface{}) {
cm.mxGlobal.Lock()
cm.global[key] = value
cm.mxGlobal.Unlock()
}
func (cm *manager) PutGlobalDynamic(key string, valueFN func() interface{}) {
value := &dynval{valueFN}
cm.mxGlobal.Lock()
cm.global[key] = value
cm.mxGlobal.Unlock()
}
func (c *context) Fill(m Map) {
for ctx := c; ctx != nil; {
ctx.mx.RLock()
fill(m, ctx.data)
next := ctx.parent
if next == nil {
next = ctx.branchedFrom
}
ctx.mx.RUnlock()
ctx = next
}
}
func (cm *manager) AsMap(obj interface{}, includeGlobals bool) Map {
return cm.currentContext().asMap(cm, obj, includeGlobals)
}
func (c *context) AsMap(obj interface{}, includeGlobals bool) Map {
return c.asMap(c.cm, obj, includeGlobals)
}
func (c *context) asMap(cm *manager, obj interface{}, includeGlobals bool) Map {
result := make(Map, 0)
cl, ok := obj.(Contextual)
if ok {
cl.Fill(result)
}
if c != nil {
c.Fill(result)
}
if includeGlobals {
cm.mxGlobal.RLock()
fill(result, cm.global)
cm.mxGlobal.RUnlock()
}
return result
}
func fill(m Map, from Map) {
if m != nil {
doFill := func(key string, _value interface{}) {
switch value := _value.(type) {
case map[string]interface{}:
for k, v := range value {
m[k] = v
}
default:
m[key] = value
}
}
for key, value := range from {
_, alreadyRead := m[key]
if !alreadyRead {
switch v := value.(type) {
case *dynval:
doFill(key, v.fn())
default:
doFill(key, v)
}
}
}
}
}
func (cm *manager) currentContext() *context {
id := curGoroutineID()
cm.mxContexts.RLock()
c := cm.contexts[id]
cm.mxContexts.RUnlock()
return c
}

130
vendor/github.com/getlantern/context/gotrack.go generated vendored Normal file
View File

@ -0,0 +1,130 @@
package context
import (
"bytes"
"errors"
"fmt"
"runtime"
"strconv"
"sync"
)
// Sourced https://github.com/bradfitz/http2/blob/dc0c5c000ec33e263612939744d51a3b68b9cece/gotrack.go
var goroutineSpace = []byte("goroutine ")
var littleBuf = sync.Pool{
New: func() interface{} {
buf := make([]byte, 64)
return &buf
},
}
func curGoroutineID() uint64 {
bp := littleBuf.Get().(*[]byte)
defer littleBuf.Put(bp)
b := *bp
b = b[:runtime.Stack(b, false)]
// Parse the 4707 out of "goroutine 4707 ["
b = bytes.TrimPrefix(b, goroutineSpace)
i := bytes.IndexByte(b, ' ')
if i < 0 {
panic(fmt.Sprintf("No space found in %q", b))
}
b = b[:i]
n, err := parseUintBytes(b, 10, 64)
if err != nil {
panic(fmt.Sprintf("Failed to parse goroutine ID out of %q: %v", b, err))
}
return n
}
// parseUintBytes is like strconv.ParseUint, but using a []byte.
func parseUintBytes(s []byte, base int, bitSize int) (n uint64, err error) {
var cutoff, maxVal uint64
if bitSize == 0 {
bitSize = int(strconv.IntSize)
}
s0 := s
switch {
case len(s) < 1:
err = strconv.ErrSyntax
return n, &strconv.NumError{Func: "ParseUint", Num: string(s0), Err: err}
case 2 <= base && base <= 36:
// valid base; nothing to do
case base == 0:
// Look for octal, hex prefix.
switch {
case s[0] == '0' && len(s) > 1 && (s[1] == 'x' || s[1] == 'X'):
base = 16
s = s[2:]
if len(s) < 1 {
err = strconv.ErrSyntax
return n, &strconv.NumError{Func: "ParseUint", Num: string(s0), Err: err}
}
case s[0] == '0':
base = 8
default:
base = 10
}
default:
err = errors.New("invalid base " + strconv.Itoa(base))
return n, &strconv.NumError{Func: "ParseUint", Num: string(s0), Err: err}
}
n = 0
cutoff = cutoff64(base)
maxVal = 1<<uint(bitSize) - 1
for i := 0; i < len(s); i++ {
var v byte
d := s[i]
switch {
case '0' <= d && d <= '9':
v = d - '0'
case 'a' <= d && d <= 'z':
v = d - 'a' + 10
case 'A' <= d && d <= 'Z':
v = d - 'A' + 10
default:
n = 0
err = strconv.ErrSyntax
return n, &strconv.NumError{Func: "ParseUint", Num: string(s0), Err: err}
}
if int(v) >= base {
n = 0
err = strconv.ErrSyntax
return n, &strconv.NumError{Func: "ParseUint", Num: string(s0), Err: err}
}
if n >= cutoff {
// n*base overflows
n = 1<<64 - 1
err = strconv.ErrRange
return n, &strconv.NumError{Func: "ParseUint", Num: string(s0), Err: err}
}
n *= uint64(base)
n1 := n + uint64(v)
if n1 < n || n1 > maxVal {
// n+v overflows
n = 1<<64 - 1
err = strconv.ErrRange
return n, &strconv.NumError{Func: "ParseUint", Num: string(s0), Err: err}
}
n = n1
}
return n, nil
}
// Return the first number n such that n*base >= 1<<64.
func cutoff64(base int) uint64 {
if base < 2 {
return 0
}
return (1<<64-1)/uint64(base) + 1
}

202
vendor/github.com/getlantern/errors/LICENSE generated vendored Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2018 Brave New Software Project, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

646
vendor/github.com/getlantern/errors/errors.go generated vendored Normal file
View File

@ -0,0 +1,646 @@
/*
Package errors defines error types used across Lantern project.
n, err := Foo()
if err != nil {
return n, errors.New("Unable to do Foo: %v", err)
}
or
n, err := Foo()
return n, errors.Wrap(err)
New() method will create a new error with err as its cause. Wrap will wrap err,
returning nil if err is nil. If err is an error from Go's standard library,
errors will extract details from that error, at least the Go type name and the
return value of err.Error().
One can record the operation on which the error occurred using Op():
return n, errors.New("Unable to do Foo: %v", err).Op("FooDooer")
One can also record additional data:
return n, errors.
New("Unable to do Foo: %v", err).
Op("FooDooer").
With("mydata", "myvalue").
With("moredata", 5)
When used with github.com/getlantern/ops, Error captures its current context
and propagates that data for use in calling layers.
When used with github.com/getlantern/golog, Error provides stacktraces:
Hello World
at github.com/getlantern/errors.TestNewWithCause (errors_test.go:999)
at testing.tRunner (testing.go:999)
at runtime.goexit (asm_amd999.s:999)
Caused by: World
at github.com/getlantern/errors.buildCause (errors_test.go:999)
at github.com/getlantern/errors.TestNewWithCause (errors_test.go:999)
at testing.tRunner (testing.go:999)
at runtime.goexit (asm_amd999.s:999)
Caused by: orld
Caused by: ld
at github.com/getlantern/errors.buildSubSubCause (errors_test.go:999)
at github.com/getlantern/errors.buildSubCause (errors_test.go:999)
at github.com/getlantern/errors.buildCause (errors_test.go:999)
at github.com/getlantern/errors.TestNewWithCause (errors_test.go:999)
at testing.tRunner (testing.go:999)
at runtime.goexit (asm_amd999.s:999)
Caused by: d
It's the caller's responsibility to avoid race conditions accessing the same
error instance from multiple goroutines.
*/
package errors
import (
"bufio"
"bytes"
"crypto/tls"
"crypto/x509"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"net"
"net/http"
"net/textproto"
"net/url"
"os"
"os/exec"
"reflect"
"runtime"
"strconv"
"strings"
"syscall"
"time"
"unicode"
"github.com/getlantern/context"
"github.com/getlantern/hidden"
"github.com/getlantern/ops"
"github.com/go-stack/stack"
)
// Error wraps system and application defined errors in unified structure for
// reporting and logging. It's not meant to be created directly. User New(),
// Wrap() and Report() instead.
type Error interface {
error
context.Contextual
// ErrorClean returns a non-parameterized version of the error whenever
// possible. For example, if the error text is:
//
// unable to dial www.google.com caused by: i/o timeout
//
// ErrorClean might return:
//
// unable to dial %v caused by: %v
//
// This can be useful when performing analytics on the error.
ErrorClean() string
// MultiLinePrinter implements the interface golog.MultiLine
MultiLinePrinter() func(buf *bytes.Buffer) bool
// Op attaches a hint of the operation triggers this Error. Many error types
// returned by net and os package have Op pre-filled.
Op(op string) Error
// With attaches arbitrary field to the error. keys will be normalized as
// underscore_divided_words, so all characters except letters and numbers will
// be replaced with underscores, and all letters will be lowercased.
With(key string, value interface{}) Error
// RootCause returns the bottom-most cause of this Error. If the Error
// resulted from wrapping a plain error, the wrapped error will be returned as
// the cause.
RootCause() error
}
type baseError struct {
errID uint64
hiddenID string
data context.Map
context context.Map
callStack stack.CallStack
}
// New creates an Error with supplied description and format arguments to the
// description. If any of the arguments is an error, we use that as the cause.
func New(desc string, args ...interface{}) Error {
return NewOffset(1, desc, args...)
}
// NewOffset is like New but offsets the stack by the given offset. This is
// useful for utilities like golog that may create errors on behalf of others.
func NewOffset(offset int, desc string, args ...interface{}) Error {
e := buildError(desc, fmt.Sprintf(desc, args...))
e.attachStack(2 + offset)
for _, arg := range args {
wrapped, isError := arg.(error)
if isError {
op, _, _, extraData := parseError(wrapped)
if op != "" {
e.Op(op)
}
for k, v := range extraData {
e.data[k] = v
}
we := &wrappingError{e, wrapped}
bufferError(we)
return we
}
}
bufferError(e)
return e
}
// Wrap creates an Error based on the information in an error instance. It
// returns nil if the error passed in is nil, so we can simply call
// errors.Wrap(s.l.Close()) regardless there's an error or not. If the error is
// already wrapped, it is returned as is.
func Wrap(err error) Error {
if err == nil {
return nil
}
if e, ok := err.(Error); ok {
return e
}
op, goType, desc, extraData := parseError(err)
if desc == "" {
desc = err.Error()
}
e := buildError(desc, desc)
e.attachStack(2)
if op != "" {
e.Op(op)
}
e.data["error_type"] = goType
for k, v := range extraData {
e.data[k] = v
}
if cause := getCause(err); cause != nil {
we := &wrappingError{e, cause}
bufferError(we)
return we
}
bufferError(e)
return e
}
// Fill implements the method from the context.Contextual interface.
func (e *baseError) Fill(m context.Map) {
if e == nil {
return
}
// Include the context, which supercedes the cause
for key, value := range e.context {
m[key] = value
}
// Now include the error's data, which supercedes everything
for key, value := range e.data {
m[key] = value
}
}
func (e *baseError) Op(op string) Error {
e.data["error_op"] = op
return e
}
func (e *baseError) With(key string, value interface{}) Error {
parts := strings.FieldsFunc(key, func(c rune) bool {
return !unicode.IsLetter(c) && !unicode.IsNumber(c)
})
k := strings.ToLower(strings.Join(parts, "_"))
if k == "error" || k == "error_op" {
// Never overwrite these
return e
}
switch actual := value.(type) {
case string, int, bool, time.Time:
e.data[k] = actual
default:
e.data[k] = fmt.Sprint(actual)
}
return e
}
func (e *baseError) RootCause() error {
return e
}
func (e *baseError) ErrorClean() string {
return e.data["error"].(string)
}
// Error satisfies the error interface
func (e *baseError) Error() string {
return e.data["error_text"].(string) + e.hiddenID
}
func (e *baseError) MultiLinePrinter() func(*bytes.Buffer) bool {
return e.topLevelPrinter()
}
func (e *baseError) topLevelPrinter() func(*bytes.Buffer) bool {
printingStack := false
stackPosition := 0
return func(buf *bytes.Buffer) bool {
if !printingStack {
buf.WriteString(e.Error())
printingStack = true
return len(e.callStack) > 0
}
call := e.callStack[stackPosition]
fmt.Fprintf(buf, " at %+n (%s:%d)", call, call, call)
stackPosition++
return stackPosition < len(e.callStack)
}
}
func (e *baseError) attachStack(skip int) {
call := stack.Caller(skip)
e.callStack = stack.Trace().TrimBelow(call)
e.data["error_location"] = fmt.Sprintf("%+n (%s:%d)", call, call, call)
}
func (e *baseError) id() uint64 {
return e.errID
}
func (e *baseError) setID(id uint64) {
e.errID = id
}
func (e *baseError) setHiddenID(id string) {
e.hiddenID = id
}
func buildError(desc string, fullText string) *baseError {
e := &baseError{
data: make(context.Map),
// We capture the current context to allow it to propagate to higher layers.
context: ops.AsMap(nil, false),
}
cleanedDesc := hidden.Clean(desc)
e.data["error"] = cleanedDesc
if fullText != "" {
e.data["error_text"] = hidden.Clean(fullText)
} else {
e.data["error_text"] = cleanedDesc
}
e.data["error_type"] = "errors.Error"
return e
}
type topLevelPrinter interface {
// Returns a printer which prints only the top-level error and any associated stack trace. The
// output of this printer will be a prefix of the output from MultiLinePrinter().
topLevelPrinter() func(*bytes.Buffer) bool
}
type unwrapper interface {
Unwrap() error
}
type wrappingError struct {
*baseError
wrapped error
}
// Implements error unwrapping as described in the standard library's errors package:
// https://golang.org/pkg/errors/#pkg-overview
func (e *wrappingError) Unwrap() error {
return e.wrapped
}
func (e *wrappingError) Fill(m context.Map) {
type filler interface{ Fill(context.Map) }
applyToChain(e.wrapped, func(err error) {
if f, ok := err.(filler); ok {
f.Fill(m)
}
})
e.baseError.Fill(m)
}
func (e *wrappingError) RootCause() error {
return unwrapToRoot(e)
}
func (e *wrappingError) MultiLinePrinter() func(*bytes.Buffer) bool {
var (
currentPrinter = e.baseError.topLevelPrinter()
nextErr = e.wrapped
prefix = ""
)
return func(buf *bytes.Buffer) bool {
fmt.Fprint(buf, prefix)
if currentPrinter(buf) {
prefix = ""
return true
}
if nextErr == nil {
return false
}
currentPrinter = getTopLevelPrinter(nextErr)
prefix = "Caused by: "
if uw, ok := nextErr.(unwrapper); ok {
nextErr = uw.Unwrap()
} else {
nextErr = nil
}
return true
}
}
// We have to implement these two methods or the fluid syntax will result in the embedded *baseError
// being returned, not the *wrappingError.
func (e *wrappingError) Op(op string) Error {
e.baseError = e.baseError.Op(op).(*baseError)
return e
}
func (e *wrappingError) With(key string, value interface{}) Error {
e.baseError = e.baseError.With(key, value).(*baseError)
return e
}
func getTopLevelPrinter(err error) func(*bytes.Buffer) bool {
if tlp, ok := err.(topLevelPrinter); ok {
return tlp.topLevelPrinter()
}
return func(buf *bytes.Buffer) bool {
fmt.Fprint(buf, err)
return false
}
}
func getCause(e error) error {
if uw, ok := e.(unwrapper); ok {
return uw.Unwrap()
}
// Look for hidden *baseErrors
hiddenIDs, extractErr := hidden.Extract(e.Error())
if extractErr == nil && len(hiddenIDs) > 0 {
// Take the first hidden ID as our cause
return get(hiddenIDs[0])
}
return nil
}
func unwrapToRoot(e error) error {
if uw, ok := e.(unwrapper); ok {
return unwrapToRoot(uw.Unwrap())
}
return e
}
// Applies f to the chain of errors unwrapped from err. The function is applied to the root cause
// first and err last.
func applyToChain(err error, f func(error)) {
if uw, ok := err.(unwrapper); ok {
applyToChain(uw.Unwrap(), f)
}
f(err)
}
func parseError(err error) (op string, goType string, desc string, extra map[string]string) {
extra = make(map[string]string)
// interfaces
if _, ok := err.(net.Error); ok {
if opError, ok := err.(*net.OpError); ok {
op = opError.Op
if opError.Source != nil {
extra["remote_addr"] = opError.Source.String()
}
if opError.Addr != nil {
extra["local_addr"] = opError.Addr.String()
}
extra["network"] = opError.Net
err = opError.Err
}
switch actual := err.(type) {
case *net.AddrError:
goType = "net.AddrError"
desc = actual.Err
extra["addr"] = actual.Addr
case *net.DNSError:
goType = "net.DNSError"
desc = actual.Err
extra["domain"] = actual.Name
if actual.Server != "" {
extra["dns_server"] = actual.Server
}
case *net.InvalidAddrError:
goType = "net.InvalidAddrError"
desc = actual.Error()
case *net.ParseError:
goType = "net.ParseError"
desc = "invalid " + actual.Type
extra["text_to_parse"] = actual.Text
case net.UnknownNetworkError:
goType = "net.UnknownNetworkError"
desc = "unknown network"
case syscall.Errno:
goType = "syscall.Errno"
desc = actual.Error()
case *url.Error:
goType = "url.Error"
desc = actual.Err.Error()
op = actual.Op
default:
goType = reflect.TypeOf(err).String()
desc = err.Error()
}
return
}
if _, ok := err.(runtime.Error); ok {
desc = err.Error()
switch err.(type) {
case *runtime.TypeAssertionError:
goType = "runtime.TypeAssertionError"
default:
goType = reflect.TypeOf(err).String()
}
return
}
// structs
switch actual := err.(type) {
case *http.ProtocolError:
desc = actual.ErrorString
if name, ok := httpProtocolErrors[err]; ok {
goType = name
} else {
goType = "http.ProtocolError"
}
case url.EscapeError, *url.EscapeError:
goType = "url.EscapeError"
desc = "invalid URL escape"
case url.InvalidHostError, *url.InvalidHostError:
goType = "url.InvalidHostError"
desc = "invalid character in host name"
case *textproto.Error:
goType = "textproto.Error"
desc = actual.Error()
case textproto.ProtocolError, *textproto.ProtocolError:
goType = "textproto.ProtocolError"
desc = actual.Error()
case tls.RecordHeaderError:
goType = "tls.RecordHeaderError"
desc = actual.Msg
extra["header"] = hex.EncodeToString(actual.RecordHeader[:])
case x509.CertificateInvalidError:
goType = "x509.CertificateInvalidError"
desc = actual.Error()
case x509.ConstraintViolationError:
goType = "x509.ConstraintViolationError"
desc = actual.Error()
case x509.HostnameError:
goType = "x509.HostnameError"
desc = actual.Error()
extra["host"] = actual.Host
case x509.InsecureAlgorithmError:
goType = "x509.InsecureAlgorithmError"
desc = actual.Error()
case x509.SystemRootsError:
goType = "x509.SystemRootsError"
desc = actual.Error()
case x509.UnhandledCriticalExtension:
goType = "x509.UnhandledCriticalExtension"
desc = actual.Error()
case x509.UnknownAuthorityError:
goType = "x509.UnknownAuthorityError"
desc = actual.Error()
case hex.InvalidByteError:
goType = "hex.InvalidByteError"
desc = "invalid byte"
case *json.InvalidUTF8Error:
goType = "json.InvalidUTF8Error"
desc = "invalid UTF-8 in string"
case *json.InvalidUnmarshalError:
goType = "json.InvalidUnmarshalError"
desc = actual.Error()
case *json.MarshalerError:
goType = "json.MarshalerError"
desc = actual.Error()
case *json.SyntaxError:
goType = "json.SyntaxError"
desc = actual.Error()
case *json.UnmarshalFieldError:
goType = "json.UnmarshalFieldError"
desc = actual.Error()
case *json.UnmarshalTypeError:
goType = "json.UnmarshalTypeError"
desc = actual.Error()
case *json.UnsupportedTypeError:
goType = "json.UnsupportedTypeError"
desc = actual.Error()
case *json.UnsupportedValueError:
goType = "json.UnsupportedValueError"
desc = actual.Error()
case *os.LinkError:
goType = "os.LinkError"
desc = actual.Error()
case *os.PathError:
goType = "os.PathError"
op = actual.Op
desc = actual.Err.Error()
case *os.SyscallError:
goType = "os.SyscallError"
op = actual.Syscall
desc = actual.Err.Error()
case *exec.Error:
goType = "exec.Error"
desc = actual.Err.Error()
case *exec.ExitError:
goType = "exec.ExitError"
desc = actual.Error()
// TODO: limit the length
extra["stderr"] = string(actual.Stderr)
case *strconv.NumError:
goType = "strconv.NumError"
desc = actual.Err.Error()
extra["function"] = actual.Func
case *time.ParseError:
goType = "time.ParseError"
desc = actual.Message
default:
desc = err.Error()
if t, ok := miscErrors[err]; ok {
goType = t
return
}
goType = reflect.TypeOf(err).String()
}
return
}
var httpProtocolErrors = map[error]string{
http.ErrHeaderTooLong: "http.ErrHeaderTooLong",
http.ErrShortBody: "http.ErrShortBody",
http.ErrNotSupported: "http.ErrNotSupported",
http.ErrUnexpectedTrailer: "http.ErrUnexpectedTrailer",
http.ErrMissingContentLength: "http.ErrMissingContentLength",
http.ErrNotMultipart: "http.ErrNotMultipart",
http.ErrMissingBoundary: "http.ErrMissingBoundary",
}
var miscErrors = map[error]string{
bufio.ErrInvalidUnreadByte: "bufio.ErrInvalidUnreadByte",
bufio.ErrInvalidUnreadRune: "bufio.ErrInvalidUnreadRune",
bufio.ErrBufferFull: "bufio.ErrBufferFull",
bufio.ErrNegativeCount: "bufio.ErrNegativeCount",
bufio.ErrTooLong: "bufio.ErrTooLong",
bufio.ErrNegativeAdvance: "bufio.ErrNegativeAdvance",
bufio.ErrAdvanceTooFar: "bufio.ErrAdvanceTooFar",
bufio.ErrFinalToken: "bufio.ErrFinalToken",
http.ErrWriteAfterFlush: "http.ErrWriteAfterFlush",
http.ErrBodyNotAllowed: "http.ErrBodyNotAllowed",
http.ErrHijacked: "http.ErrHijacked",
http.ErrContentLength: "http.ErrContentLength",
http.ErrBodyReadAfterClose: "http.ErrBodyReadAfterClose",
http.ErrHandlerTimeout: "http.ErrHandlerTimeout",
http.ErrLineTooLong: "http.ErrLineTooLong",
http.ErrMissingFile: "http.ErrMissingFile",
http.ErrNoCookie: "http.ErrNoCookie",
http.ErrNoLocation: "http.ErrNoLocation",
http.ErrSkipAltProtocol: "http.ErrSkipAltProtocol",
io.EOF: "io.EOF",
io.ErrClosedPipe: "io.ErrClosedPipe",
io.ErrNoProgress: "io.ErrNoProgress",
io.ErrShortBuffer: "io.ErrShortBuffer",
io.ErrShortWrite: "io.ErrShortWrite",
io.ErrUnexpectedEOF: "io.ErrUnexpectedEOF",
os.ErrInvalid: "os.ErrInvalid",
os.ErrPermission: "os.ErrPermission",
os.ErrExist: "os.ErrExist",
os.ErrNotExist: "os.ErrNotExist",
exec.ErrNotFound: "exec.ErrNotFound",
x509.ErrUnsupportedAlgorithm: "x509.ErrUnsupportedAlgorithm",
x509.IncorrectPasswordError: "x509.IncorrectPasswordError",
hex.ErrLength: "hex.ErrLength",
}

57
vendor/github.com/getlantern/errors/hide.go generated vendored Normal file
View File

@ -0,0 +1,57 @@
package errors
import (
"encoding/binary"
"sync"
"github.com/getlantern/hidden"
)
var (
hiddenErrors = make([]hideableError, 100)
nextID = uint64(0)
hiddenMutex sync.RWMutex
)
type hideableError interface {
Error
id() uint64
setID(uint64)
setHiddenID(string)
}
// This trick saves the error to a ring buffer and embeds a non-printing
// hiddenID in the error's description, so that if the error is later wrapped
// by a standard error using something like
// fmt.Errorf("An error occurred: %v", thisError), we can subsequently extract
// the error simply using the hiddenID in the string.
func bufferError(e hideableError) {
hiddenMutex.Lock()
b := make([]byte, 8)
binary.BigEndian.PutUint64(b, nextID)
e.setID(nextID)
e.setHiddenID(hidden.ToString(b))
hiddenErrors[idxForID(nextID)] = e
nextID++
hiddenMutex.Unlock()
}
func get(hiddenID []byte) Error {
if len(hiddenID) != 8 {
return nil
}
id := binary.BigEndian.Uint64(hiddenID)
hiddenMutex.RLock()
err := hiddenErrors[idxForID(id)]
hiddenMutex.RUnlock()
if err != nil && err.id() == id {
// Found it!
return err
}
// buffer has rolled over
return nil
}
func idxForID(id uint64) int {
return int(id % uint64(len(hiddenErrors)))
}

122
vendor/github.com/getlantern/filepersist/filepersist.go generated vendored Normal file
View File

@ -0,0 +1,122 @@
// package filepersist provdies a mechanism for persisting data to a file at a
// permanent location
package filepersist
import (
"fmt"
"io"
"os"
"github.com/getlantern/golog"
)
var (
log = golog.LoggerFor("filepersist")
)
// Save saves the given data to the file at filename. If an existing file at
// that filename already exists, this simply chmods the existing file to match
// the given fileMode and otherwise leaves it alone.
func Save(filename string, data []byte, fileMode os.FileMode) error {
log.Tracef("Attempting to open %v for creating, but only if it doesn't already exist", filename)
file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_EXCL, fileMode)
if err != nil {
if !os.IsExist(err) {
return fmt.Errorf("Unexpected error opening %s: %s", filename, err)
}
log.Tracef("%s already exists, check to make sure contents is the same", filename)
if dataMatches(filename, data) {
log.Tracef("Data in %s matches expected, using existing", filename)
chmod(filename, fileMode)
// TODO - maybe don't swallow the error, but returning something
// unique so the caller can decide whether or not to ignore it.
return nil
}
log.Tracef("Data in %s doesn't match expected, truncating file", filename)
file, err = openAndTruncate(filename, fileMode, true)
if err != nil {
return fmt.Errorf("Unable to truncate %s: %s", filename, err)
}
}
log.Tracef("Created new file at %s, writing data", filename)
_, err = file.Write(data)
if err != nil {
if err := os.Remove(filename); err != nil {
log.Debugf("Unable to remove file: %v", err)
}
return fmt.Errorf("Unable to write to file at %s: %s", filename, err)
}
if err := file.Sync(); err != nil {
log.Debugf("Unable to sync file: %v", err)
}
if err := file.Close(); err != nil {
log.Debugf("Unable to close file: %v", err)
}
log.Trace("File saved")
return nil
}
func openAndTruncate(filename string, fileMode os.FileMode, removeIfNecessary bool) (*os.File, error) {
file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, fileMode)
if err != nil && os.IsPermission(err) && removeIfNecessary {
log.Tracef("Permission denied truncating file %v, try to remove", filename)
err = os.Remove(filename)
if err != nil {
return nil, fmt.Errorf("Unable to remove file %v: %v", filename, err)
}
return openAndTruncate(filename, fileMode, false)
}
return file, err
}
// dataMatches compares the file at filename byte for byte with the given data
func dataMatches(filename string, data []byte) bool {
file, err := os.OpenFile(filename, os.O_RDONLY, 0)
if err != nil {
log.Tracef("Unable to open existing file at %s for reading: %s", filename, err)
return false
}
fileInfo, err := file.Stat()
if err != nil {
log.Tracef("Unable to stat file %s", filename)
return false
}
if fileInfo.Size() != int64(len(data)) {
return false
}
b := make([]byte, 65536)
i := 0
for {
n, err := file.Read(b)
if err != nil && err != io.EOF {
log.Tracef("Error reading %s for comparison: %s", filename, err)
return false
}
for j := 0; j < n; j++ {
if b[j] != data[i] {
return false
}
i = i + 1
}
if err == io.EOF {
break
}
}
return true
}
func chmod(filename string, fileMode os.FileMode) {
fi, err := os.Stat(filename)
if err != nil || fi.Mode() != fileMode {
log.Tracef("Chmodding %v", filename)
err = os.Chmod(filename, fileMode)
if err != nil {
log.Debugf("Warning - unable to chmod %v: %v", filename, err)
}
}
}

14
vendor/github.com/getlantern/golog/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,14 @@
language: go
go:
- 1.4.1
install:
- go get -d -t -v ./...
- go build -v ./...
- go get golang.org/x/tools/cmd/cover
- go get -v github.com/axw/gocov/gocov
- go get -v github.com/mattn/goveralls
script:
- $HOME/gopath/bin/goveralls -v -service travis-ci github.com/getlantern/golog

202
vendor/github.com/getlantern/golog/LICENSE generated vendored Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2014 Brave New Software Project, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

6
vendor/github.com/getlantern/golog/README.md generated vendored Normal file
View File

@ -0,0 +1,6 @@
golog [![Travis CI Status](https://travis-ci.org/getlantern/golog.svg?branch=master)](https://travis-ci.org/getlantern/golog)&nbsp;[![Coverage Status](https://coveralls.io/repos/getlantern/golog/badge.png)](https://coveralls.io/r/getlantern/golog)&nbsp;[![GoDoc](https://godoc.org/github.com/getlantern/golog?status.png)](http://godoc.org/github.com/getlantern/golog)
==========
Provides logging used in many getlantern components.
[GoDoc](https://godoc.org/github.com/getlantern/golog)

14
vendor/github.com/getlantern/golog/go.mod generated vendored Normal file
View File

@ -0,0 +1,14 @@
module github.com/getlantern/golog
go 1.12
require (
github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 // indirect
github.com/getlantern/errors v1.0.1
github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7 // indirect
github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55
github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f
github.com/go-stack/stack v1.8.0 // indirect
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c
github.com/stretchr/testify v1.3.0
)

21
vendor/github.com/getlantern/golog/go.sum generated vendored Normal file
View File

@ -0,0 +1,21 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 h1:NRUJuo3v3WGC/g5YiyF790gut6oQr5f3FBI88Wv0dx4=
github.com/getlantern/context v0.0.0-20190109183933-c447772a6520/go.mod h1:L+mq6/vvYHKjCX2oez0CgEAJmbq1fbb/oNJIWQkBybY=
github.com/getlantern/errors v1.0.1 h1:XukU2whlh7OdpxnkXhNH9VTLVz0EVPGKDV5K0oWhvzw=
github.com/getlantern/errors v1.0.1/go.mod h1:l+xpFBrCtDLpK9qNjxs+cHU6+BAdlBaxHqikB6Lku3A=
github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7 h1:micT5vkcr9tOVk1FiH8SWKID8ultN44Z+yzd2y/Vyb0=
github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7/go.mod h1:dD3CgOrwlzca8ed61CsZouQS5h5jIzkK9ZWrTcf0s+o=
github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55 h1:XYzSdCbkzOC0FDNrgJqGRo8PCMFOBFL9py72DRs7bmc=
github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55/go.mod h1:6mmzY2kW1TOOrVy+r41Za2MxXM+hhqTtY3oBKd2AgFA=
github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f h1:wrYrQttPS8FHIRSlsrcuKazukx/xqO/PpLZzZXsF+EA=
github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f/go.mod h1:D5ao98qkA6pxftxoqzibIBBrLSUli+kYnJqrgBf9cIA=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw=
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=

480
vendor/github.com/getlantern/golog/golog.go generated vendored Normal file
View File

@ -0,0 +1,480 @@
// Package golog implements logging functions that log errors to stderr and
// debug messages to stdout. Trace logging is also supported.
// Trace logs go to stdout as well, but they are only written if the program
// is run with environment variable "TRACE=true".
// A stack dump will be printed after the message if "PRINT_STACK=true".
package golog
import (
"bufio"
"bytes"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"path/filepath"
"runtime"
"sort"
"strconv"
"strings"
"sync"
"sync/atomic"
"github.com/getlantern/errors"
"github.com/getlantern/hidden"
"github.com/getlantern/ops"
"github.com/oxtoacart/bpool"
)
const (
// ERROR is an error Severity
ERROR = 500
// FATAL is an error Severity
FATAL = 600
)
var (
outs atomic.Value
prepender atomic.Value
reporters []ErrorReporter
reportersMutex sync.RWMutex
bufferPool = bpool.NewBufferPool(200)
onFatal atomic.Value
)
// Severity is a level of error (higher values are more severe)
type Severity int
func (s Severity) String() string {
switch s {
case ERROR:
return "ERROR"
case FATAL:
return "FATAL"
default:
return "UNKNOWN"
}
}
func init() {
DefaultOnFatal()
ResetOutputs()
ResetPrepender()
}
// SetPrepender sets a function to write something, e.g., the timestamp, before
// each line of the log.
func SetPrepender(p func(io.Writer)) {
prepender.Store(p)
}
func ResetPrepender() {
SetPrepender(func(io.Writer) {})
}
func GetPrepender() func(io.Writer) {
return prepender.Load().(func(io.Writer))
}
// SetOutputs sets the outputs for error and debug logs to use the given writers.
// Returns a function that resets outputs to their original values prior to calling SetOutputs.
func SetOutputs(errorOut io.Writer, debugOut io.Writer) (reset func()) {
oldOuts := outs.Load()
outs.Store(&outputs{
ErrorOut: errorOut,
DebugOut: debugOut,
})
return func() {
outs.Store(oldOuts)
}
}
// Deprecated: instead of calling ResetOutputs, use the reset function returned by SetOutputs.
func ResetOutputs() {
SetOutputs(os.Stderr, os.Stdout)
}
func GetOutputs() *outputs {
return outs.Load().(*outputs)
}
// RegisterReporter registers the given ErrorReporter. All logged Errors are
// sent to this reporter.
func RegisterReporter(reporter ErrorReporter) {
reportersMutex.Lock()
reporters = append(reporters, reporter)
reportersMutex.Unlock()
}
// OnFatal configures golog to call the given function on any FATAL error. By
// default, golog calls os.Exit(1) on any FATAL error.
func OnFatal(fn func(err error)) {
onFatal.Store(fn)
}
// DefaultOnFatal enables the default behavior for OnFatal
func DefaultOnFatal() {
onFatal.Store(func(err error) {
os.Exit(1)
})
}
type outputs struct {
ErrorOut io.Writer
DebugOut io.Writer
}
// MultiLine is an interface for arguments that support multi-line output.
type MultiLine interface {
// MultiLinePrinter returns a function that can be used to print the
// multi-line output. The returned function writes one line to the buffer and
// returns true if there are more lines to write. This function does not need
// to take care of trailing carriage returns, golog handles that
// automatically.
MultiLinePrinter() func(buf *bytes.Buffer) bool
}
// ErrorReporter is a function to which the logger will report errors.
// It the given error and corresponding message along with associated ops
// context. This should return quickly as it executes on the critical code
// path. The recommended approach is to buffer as much as possible and discard
// new reports if the buffer becomes saturated.
type ErrorReporter func(err error, severity Severity, ctx map[string]interface{})
type Logger interface {
// Debug logs to stdout
Debug(arg interface{})
// Debugf logs to stdout
Debugf(message string, args ...interface{})
// Error logs to stderr
Error(arg interface{}) error
// Errorf logs to stderr. It returns the first argument that's an error, or
// a new error built using fmt.Errorf if none of the arguments are errors.
Errorf(message string, args ...interface{}) error
// Fatal logs to stderr and then exits with status 1
Fatal(arg interface{})
// Fatalf logs to stderr and then exits with status 1
Fatalf(message string, args ...interface{})
// Trace logs to stderr only if TRACE=true
Trace(arg interface{})
// Tracef logs to stderr only if TRACE=true
Tracef(message string, args ...interface{})
// TraceOut provides access to an io.Writer to which trace information can
// be streamed. If running with environment variable "TRACE=true", TraceOut
// will point to os.Stderr, otherwise it will point to a ioutil.Discared.
// Each line of trace information will be prefixed with this Logger's
// prefix.
TraceOut() io.Writer
// IsTraceEnabled() indicates whether or not tracing is enabled for this
// logger.
IsTraceEnabled() bool
// AsStdLogger returns an standard logger
AsStdLogger() *log.Logger
}
func LoggerFor(prefix string) Logger {
l := &logger{
prefix: prefix + ": ",
pc: make([]uintptr, 10),
}
trace := os.Getenv("TRACE")
l.traceOn, _ = strconv.ParseBool(trace)
if !l.traceOn {
prefixes := strings.Split(trace, ",")
for _, p := range prefixes {
if prefix == strings.Trim(p, " ") {
l.traceOn = true
break
}
}
}
if l.traceOn {
l.traceOut = l.newTraceWriter()
} else {
l.traceOut = ioutil.Discard
}
printStack := os.Getenv("PRINT_STACK")
l.printStack, _ = strconv.ParseBool(printStack)
return l
}
type logger struct {
prefix string
traceOn bool
traceOut io.Writer
printStack bool
outs atomic.Value
pc []uintptr
funcForPc *runtime.Func
}
// attaches the file and line number corresponding to
// the log message
func (l *logger) linePrefix(skipFrames int) string {
runtime.Callers(skipFrames, l.pc)
funcForPc := runtime.FuncForPC(l.pc[0])
file, line := funcForPc.FileLine(l.pc[0] - 1)
return fmt.Sprintf("%s%s:%d ", l.prefix, filepath.Base(file), line)
}
func (l *logger) print(out io.Writer, skipFrames int, severity string, arg interface{}) {
buf := bufferPool.Get()
defer bufferPool.Put(buf)
GetPrepender()(buf)
linePrefix := l.linePrefix(skipFrames)
writeHeader := func() {
buf.WriteString(severity)
buf.WriteString(" ")
buf.WriteString(linePrefix)
}
if arg != nil {
ml, isMultiline := arg.(MultiLine)
if !isMultiline {
writeHeader()
fmt.Fprintf(buf, "%v", arg)
printContext(buf, arg)
buf.WriteByte('\n')
} else {
mlp := ml.MultiLinePrinter()
first := true
for {
writeHeader()
more := mlp(buf)
if first {
printContext(buf, arg)
first = false
}
buf.WriteByte('\n')
if !more {
break
}
}
}
}
b := []byte(hidden.Clean(buf.String()))
_, err := out.Write(b)
if err != nil {
errorOnLogging(err)
}
if l.printStack {
l.doPrintStack()
}
}
func (l *logger) printf(out io.Writer, skipFrames int, severity string, err error, message string, args ...interface{}) {
buf := bufferPool.Get()
defer bufferPool.Put(buf)
GetPrepender()(buf)
linePrefix := l.linePrefix(skipFrames)
buf.WriteString(severity)
buf.WriteString(" ")
buf.WriteString(linePrefix)
fmt.Fprintf(buf, message, args...)
printContext(buf, err)
buf.WriteByte('\n')
b := []byte(hidden.Clean(buf.String()))
_, err2 := out.Write(b)
if err2 != nil {
errorOnLogging(err2)
}
if l.printStack {
l.doPrintStack()
}
}
func (l *logger) Debug(arg interface{}) {
l.print(GetOutputs().DebugOut, 4, "DEBUG", arg)
}
func (l *logger) Debugf(message string, args ...interface{}) {
l.printf(GetOutputs().DebugOut, 4, "DEBUG", nil, message, args...)
}
func (l *logger) Error(arg interface{}) error {
return l.errorSkipFrames(arg, 1, ERROR)
}
func (l *logger) Errorf(message string, args ...interface{}) error {
return l.errorSkipFrames(errors.NewOffset(1, message, args...), 1, ERROR)
}
func (l *logger) Fatal(arg interface{}) {
fatal(l.errorSkipFrames(arg, 1, FATAL))
}
func (l *logger) Fatalf(message string, args ...interface{}) {
fatal(l.errorSkipFrames(errors.NewOffset(1, message, args...), 1, FATAL))
}
func fatal(err error) {
fn := onFatal.Load().(func(err error))
fn(err)
}
func (l *logger) errorSkipFrames(arg interface{}, skipFrames int, severity Severity) error {
var err error
switch e := arg.(type) {
case error:
err = e
default:
err = fmt.Errorf("%v", e)
}
l.print(GetOutputs().ErrorOut, skipFrames+4, severity.String(), err)
return report(err, severity)
}
func (l *logger) Trace(arg interface{}) {
if l.traceOn {
l.print(GetOutputs().DebugOut, 4, "TRACE", arg)
}
}
func (l *logger) Tracef(message string, args ...interface{}) {
if l.traceOn {
l.printf(GetOutputs().DebugOut, 4, "TRACE", nil, message, args...)
}
}
func (l *logger) TraceOut() io.Writer {
return l.traceOut
}
func (l *logger) IsTraceEnabled() bool {
return l.traceOn
}
func (l *logger) newTraceWriter() io.Writer {
pr, pw := io.Pipe()
br := bufio.NewReader(pr)
if !l.traceOn {
return pw
}
go func() {
defer func() {
if err := pr.Close(); err != nil {
errorOnLogging(err)
}
}()
defer func() {
if err := pw.Close(); err != nil {
errorOnLogging(err)
}
}()
for {
line, err := br.ReadString('\n')
if err == nil {
// Log the line (minus the trailing newline)
l.print(GetOutputs().DebugOut, 6, "TRACE", line[:len(line)-1])
} else {
l.printf(GetOutputs().DebugOut, 6, "TRACE", nil, "TraceWriter closed due to unexpected error: %v", err)
return
}
}
}()
return pw
}
type errorWriter struct {
l *logger
}
// Write implements method of io.Writer, due to different call depth,
// it will not log correct file and line prefix
func (w *errorWriter) Write(p []byte) (n int, err error) {
s := string(p)
if s[len(s)-1] == '\n' {
s = s[:len(s)-1]
}
w.l.print(GetOutputs().ErrorOut, 6, "ERROR", s)
return len(p), nil
}
func (l *logger) AsStdLogger() *log.Logger {
return log.New(&errorWriter{l}, "", 0)
}
func (l *logger) doPrintStack() {
var b []byte
buf := bytes.NewBuffer(b)
for _, pc := range l.pc {
funcForPc := runtime.FuncForPC(pc)
if funcForPc == nil {
break
}
name := funcForPc.Name()
if strings.HasPrefix(name, "runtime.") {
break
}
file, line := funcForPc.FileLine(pc)
fmt.Fprintf(buf, "\t%s\t%s: %d\n", name, file, line)
}
if _, err := buf.WriteTo(os.Stderr); err != nil {
errorOnLogging(err)
}
}
func errorOnLogging(err error) {
fmt.Fprintf(os.Stderr, "Unable to log: %v\n", err)
}
func printContext(buf *bytes.Buffer, err interface{}) {
// Note - we don't include globals when printing in order to avoid polluting the text log
values := ops.AsMap(err, false)
if len(values) == 0 {
return
}
buf.WriteString(" [")
var keys []string
for key := range values {
keys = append(keys, key)
}
sort.Strings(keys)
for i, key := range keys {
value := values[key]
if i > 0 {
buf.WriteString(" ")
}
buf.WriteString(key)
buf.WriteString("=")
fmt.Fprintf(buf, "%v", value)
}
buf.WriteByte(']')
}
func report(err error, severity Severity) error {
var reportersCopy []ErrorReporter
reportersMutex.RLock()
if len(reporters) > 0 {
reportersCopy = make([]ErrorReporter, len(reporters))
copy(reportersCopy, reporters)
}
reportersMutex.RUnlock()
if len(reportersCopy) > 0 {
ctx := ops.AsMap(err, true)
ctx["severity"] = severity.String()
for _, reporter := range reportersCopy {
// We include globals when reporting
reporter(err, severity, ctx)
}
}
return err
}

29
vendor/github.com/getlantern/hex/LICENSE generated vendored Normal file
View File

@ -0,0 +1,29 @@
Copyright (c) 2009 The Go Authors.
Copyright (c) 2016 Brave New Software Project, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

110
vendor/github.com/getlantern/hex/hex.go generated vendored Normal file
View File

@ -0,0 +1,110 @@
// Copyright 2009 The Go Authors.
// Copyright 2016 Brave New Software Project, Inc.
// All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package hex implements hexadecimal encoding and decoding. It's taken almost
// verbatim from golang/encoding/hex, however it allows using a different set
// of encoding characters than the standard 0-F.
package hex
import (
"errors"
"fmt"
)
// DefaultEncoding behaves just like golang/encoding/hex.
var DefaultEncoding = NewEncoding("0123456789abcdef")
// An Encoding that uses a specific table of encoding characters.
type Encoding struct {
hextable string
}
// NewEncoding constructs an Encoding using the given hextable.
func NewEncoding(hextable string) *Encoding {
return &Encoding{hextable}
}
// EncodedLen returns the length of an encoding of n source bytes.
func EncodedLen(n int) int { return n * 2 }
// Encode encodes src into EncodedLen(len(src))
// bytes of dst. As a convenience, it returns the number
// of bytes written to dst, but this value is always EncodedLen(len(src)).
// Encode implements hexadecimal encoding.
func (e *Encoding) Encode(dst, src []byte) int {
for i, v := range src {
dst[i*2] = e.hextable[v>>4]
dst[i*2+1] = e.hextable[v&0x0f]
}
return len(src) * 2
}
// ErrLength results from decoding an odd length slice.
var ErrLength = errors.New("encoding/hex: odd length hex string")
// InvalidByteError values describe errors resulting from an invalid byte in a hex string.
type InvalidByteError byte
func (e InvalidByteError) Error() string {
return fmt.Sprintf("encoding/hex: invalid byte: %#U", rune(e))
}
func DecodedLen(x int) int { return x / 2 }
// Decode decodes src into DecodedLen(len(src)) bytes, returning the actual
// number of bytes written to dst.
//
// If Decode encounters invalid input, it returns an error describing the failure.
func (e *Encoding) Decode(dst, src []byte) (int, error) {
if len(src)%2 == 1 {
return 0, ErrLength
}
for i := 0; i < len(src)/2; i++ {
a, ok := e.fromHexChar(src[i*2])
if !ok {
return 0, InvalidByteError(src[i*2])
}
b, ok := e.fromHexChar(src[i*2+1])
if !ok {
return 0, InvalidByteError(src[i*2+1])
}
dst[i] = (a << 4) | b
}
return len(src) / 2, nil
}
// fromHexChar converts a hex character into its value and a success flag.
func (e *Encoding) fromHexChar(c byte) (byte, bool) {
for i, ch := range []byte(e.hextable) {
if ch == c {
return byte(i), true
}
}
return 0, false
}
// EncodeToString returns the hexadecimal encoding of src.
func (e *Encoding) EncodeToString(src []byte) string {
dst := make([]byte, EncodedLen(len(src)))
e.Encode(dst, src)
return string(dst)
}
// DecodeString returns the bytes represented by the hexadecimal string s.
func (e *Encoding) DecodeString(s string) ([]byte, error) {
src := []byte(s)
dst := make([]byte, DecodedLen(len(src)))
_, err := e.Decode(dst, src)
if err != nil {
return nil, err
}
return dst, nil
}

202
vendor/github.com/getlantern/hidden/LICENSE generated vendored Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2016 Brave New Software Project, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

66
vendor/github.com/getlantern/hidden/hidden.go generated vendored Normal file
View File

@ -0,0 +1,66 @@
// Package hidden provides the ability to "hide" binary data in a string using
// a hex encoding with non-printing characters. Hidden data is demarcated with
// a leading and trailing NUL character.
package hidden
import (
"bytes"
"fmt"
"regexp"
"github.com/getlantern/hex"
)
// 16 non-printing characters
const hextable = "\x01\x02\x03\x04\x05\x06\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17"
var (
hexencoding = hex.NewEncoding(hextable)
re *regexp.Regexp
)
func init() {
var err error
re, err = regexp.Compile(fmt.Sprintf("\x00[%v]+\x00", hextable))
if err != nil {
panic(err)
}
}
// ToString encodes the given data as a hidden string, including leadnig and
// trailing NULs.
func ToString(data []byte) string {
buf := bytes.NewBuffer(make([]byte, 0, 2+hex.EncodedLen(len(data))))
// Leading NUL
buf.WriteByte(0)
buf.WriteString(hexencoding.EncodeToString(data))
// Trailing NUL
buf.WriteByte(0)
return buf.String()
}
// FromString extracts the hidden data from a string, which is expected to
// contain leading and trailing NULs.
func FromString(str string) ([]byte, error) {
return hexencoding.DecodeString(str[1 : len(str)-1])
}
// Extract extracts all hidden data from an arbitrary string.
func Extract(str string) ([][]byte, error) {
m := re.FindAllString(str, -1)
result := make([][]byte, 0, len(m))
for _, s := range m {
b, err := FromString(s)
if err != nil {
return nil, err
}
result = append(result, b)
}
return result, nil
}
// Clean removes any hidden data from an arbitrary string.
func Clean(str string) string {
return re.ReplaceAllString(str, "")
}

202
vendor/github.com/getlantern/ops/LICENSE generated vendored Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2017 Brave New Software Project, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

154
vendor/github.com/getlantern/ops/ops.go generated vendored Normal file
View File

@ -0,0 +1,154 @@
// Package ops provides a facility for tracking the processing of operations,
// including contextual metadata about the operation and their final success or
// failure. An op is assumed to have succeeded if by the time of calling Exit()
// no errors have been reported. The final status can be reported to a metrics
// facility.
package ops
import (
"sync"
"sync/atomic"
"github.com/getlantern/context"
)
var (
cm = context.NewManager()
reporters []Reporter
reportersMutex sync.RWMutex
)
// Reporter is a function that reports the success or failure of an Op. If
// failure is nil, the Op can be considered successful.
type Reporter func(failure error, ctx map[string]interface{})
// Op represents an operation that's being performed. It mimics the API of
// context.Context.
type Op interface {
// Begin marks the beginning of an Op under this Op.
Begin(name string) Op
// Go starts the given function on a new goroutine.
Go(fn func())
// End marks the end of this op, at which point the Op will report its success
// or failure to all registered Reporters.
End()
// Cancel cancels this op so that even if End() is called later, it will not
// report its success or failure.
Cancel()
// Set puts a key->value pair into the current Op's context.
Set(key string, value interface{}) Op
// SetDynamic puts a key->value pair into the current Op's context, where the
// value is generated by a function that gets evaluated at every Read.
SetDynamic(key string, valueFN func() interface{}) Op
// FailIf marks this Op as failed if the given err is not nil. If FailIf is
// called multiple times, the latest error will be reported as the failure.
// Returns the original error for convenient chaining.
FailIf(err error) error
}
type op struct {
ctx context.Context
canceled bool
failure atomic.Value
}
// RegisterReporter registers the given reporter.
func RegisterReporter(reporter Reporter) {
reportersMutex.Lock()
reporters = append(reporters, reporter)
reportersMutex.Unlock()
}
// Begin marks the beginning of a new Op.
func Begin(name string) Op {
return &op{ctx: cm.Enter().Put("op", name).PutIfAbsent("root_op", name)}
}
func (o *op) Begin(name string) Op {
return &op{ctx: o.ctx.Enter().Put("op", name).PutIfAbsent("root_op", name)}
}
func (o *op) Go(fn func()) {
o.ctx.Go(fn)
}
// Go mimics the method from context.Manager.
func Go(fn func()) {
cm.Go(fn)
}
func (o *op) Cancel() {
o.canceled = true
}
func (o *op) End() {
if o.canceled {
return
}
var reportersCopy []Reporter
reportersMutex.RLock()
if len(reporters) > 0 {
reportersCopy = make([]Reporter, len(reporters))
copy(reportersCopy, reporters)
}
reportersMutex.RUnlock()
if len(reportersCopy) > 0 {
var failure error
_failure := o.failure.Load()
ctx := o.ctx.AsMap(_failure, true)
if _failure != nil {
failure = _failure.(error)
_, errorSet := ctx["error"]
if !errorSet {
ctx["error"] = failure.Error()
}
}
for _, reporter := range reportersCopy {
reporter(failure, ctx)
}
}
o.ctx.Exit()
}
func (o *op) Set(key string, value interface{}) Op {
o.ctx.Put(key, value)
return o
}
// SetGlobal puts a key->value pair into the global context, which is inherited
// by all Ops.
func SetGlobal(key string, value interface{}) {
cm.PutGlobal(key, value)
}
func (o *op) SetDynamic(key string, valueFN func() interface{}) Op {
o.ctx.PutDynamic(key, valueFN)
return o
}
// SetGlobalDynamic is like SetGlobal but uses a function to derive the value
// at read time.
func SetGlobalDynamic(key string, valueFN func() interface{}) {
cm.PutGlobalDynamic(key, valueFN)
}
// AsMap mimics the method from context.Manager.
func AsMap(obj interface{}, includeGlobals bool) context.Map {
return cm.AsMap(obj, includeGlobals)
}
func (o *op) FailIf(err error) error {
if err != nil {
o.failure.Store(err)
}
return err
}

15
vendor/github.com/go-stack/stack/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,15 @@
language: go
sudo: false
go:
- 1.7.x
- 1.8.x
- 1.9.x
- 1.10.x
- 1.11.x
- tip
before_install:
- go get github.com/mattn/goveralls
script:
- goveralls -service=travis-ci

21
vendor/github.com/go-stack/stack/LICENSE.md generated vendored Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Chris Hines
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

38
vendor/github.com/go-stack/stack/README.md generated vendored Normal file
View File

@ -0,0 +1,38 @@
[![GoDoc](https://godoc.org/github.com/go-stack/stack?status.svg)](https://godoc.org/github.com/go-stack/stack)
[![Go Report Card](https://goreportcard.com/badge/go-stack/stack)](https://goreportcard.com/report/go-stack/stack)
[![TravisCI](https://travis-ci.org/go-stack/stack.svg?branch=master)](https://travis-ci.org/go-stack/stack)
[![Coverage Status](https://coveralls.io/repos/github/go-stack/stack/badge.svg?branch=master)](https://coveralls.io/github/go-stack/stack?branch=master)
# stack
Package stack implements utilities to capture, manipulate, and format call
stacks. It provides a simpler API than package runtime.
The implementation takes care of the minutia and special cases of interpreting
the program counter (pc) values returned by runtime.Callers.
## Versioning
Package stack publishes releases via [semver](http://semver.org/) compatible Git
tags prefixed with a single 'v'. The master branch always contains the latest
release. The develop branch contains unreleased commits.
## Formatting
Package stack's types implement fmt.Formatter, which provides a simple and
flexible way to declaratively configure formatting when used with logging or
error tracking packages.
```go
func DoTheThing() {
c := stack.Caller(0)
log.Print(c) // "source.go:10"
log.Printf("%+v", c) // "pkg/path/source.go:10"
log.Printf("%n", c) // "DoTheThing"
s := stack.Trace().TrimRuntime()
log.Print(s) // "[source.go:15 caller.go:42 main.go:14]"
}
```
See the docs for all of the supported formatting options.

1
vendor/github.com/go-stack/stack/go.mod generated vendored Normal file
View File

@ -0,0 +1 @@
module github.com/go-stack/stack

400
vendor/github.com/go-stack/stack/stack.go generated vendored Normal file
View File

@ -0,0 +1,400 @@
// +build go1.7
// Package stack implements utilities to capture, manipulate, and format call
// stacks. It provides a simpler API than package runtime.
//
// The implementation takes care of the minutia and special cases of
// interpreting the program counter (pc) values returned by runtime.Callers.
//
// Package stack's types implement fmt.Formatter, which provides a simple and
// flexible way to declaratively configure formatting when used with logging
// or error tracking packages.
package stack
import (
"bytes"
"errors"
"fmt"
"io"
"runtime"
"strconv"
"strings"
)
// Call records a single function invocation from a goroutine stack.
type Call struct {
frame runtime.Frame
}
// Caller returns a Call from the stack of the current goroutine. The argument
// skip is the number of stack frames to ascend, with 0 identifying the
// calling function.
func Caller(skip int) Call {
// As of Go 1.9 we need room for up to three PC entries.
//
// 0. An entry for the stack frame prior to the target to check for
// special handling needed if that prior entry is runtime.sigpanic.
// 1. A possible second entry to hold metadata about skipped inlined
// functions. If inline functions were not skipped the target frame
// PC will be here.
// 2. A third entry for the target frame PC when the second entry
// is used for skipped inline functions.
var pcs [3]uintptr
n := runtime.Callers(skip+1, pcs[:])
frames := runtime.CallersFrames(pcs[:n])
frame, _ := frames.Next()
frame, _ = frames.Next()
return Call{
frame: frame,
}
}
// String implements fmt.Stinger. It is equivalent to fmt.Sprintf("%v", c).
func (c Call) String() string {
return fmt.Sprint(c)
}
// MarshalText implements encoding.TextMarshaler. It formats the Call the same
// as fmt.Sprintf("%v", c).
func (c Call) MarshalText() ([]byte, error) {
if c.frame == (runtime.Frame{}) {
return nil, ErrNoFunc
}
buf := bytes.Buffer{}
fmt.Fprint(&buf, c)
return buf.Bytes(), nil
}
// ErrNoFunc means that the Call has a nil *runtime.Func. The most likely
// cause is a Call with the zero value.
var ErrNoFunc = errors.New("no call stack information")
// Format implements fmt.Formatter with support for the following verbs.
//
// %s source file
// %d line number
// %n function name
// %k last segment of the package path
// %v equivalent to %s:%d
//
// It accepts the '+' and '#' flags for most of the verbs as follows.
//
// %+s path of source file relative to the compile time GOPATH,
// or the module path joined to the path of source file relative
// to module root
// %#s full path of source file
// %+n import path qualified function name
// %+k full package path
// %+v equivalent to %+s:%d
// %#v equivalent to %#s:%d
func (c Call) Format(s fmt.State, verb rune) {
if c.frame == (runtime.Frame{}) {
fmt.Fprintf(s, "%%!%c(NOFUNC)", verb)
return
}
switch verb {
case 's', 'v':
file := c.frame.File
switch {
case s.Flag('#'):
// done
case s.Flag('+'):
file = pkgFilePath(&c.frame)
default:
const sep = "/"
if i := strings.LastIndex(file, sep); i != -1 {
file = file[i+len(sep):]
}
}
io.WriteString(s, file)
if verb == 'v' {
buf := [7]byte{':'}
s.Write(strconv.AppendInt(buf[:1], int64(c.frame.Line), 10))
}
case 'd':
buf := [6]byte{}
s.Write(strconv.AppendInt(buf[:0], int64(c.frame.Line), 10))
case 'k':
name := c.frame.Function
const pathSep = "/"
start, end := 0, len(name)
if i := strings.LastIndex(name, pathSep); i != -1 {
start = i + len(pathSep)
}
const pkgSep = "."
if i := strings.Index(name[start:], pkgSep); i != -1 {
end = start + i
}
if s.Flag('+') {
start = 0
}
io.WriteString(s, name[start:end])
case 'n':
name := c.frame.Function
if !s.Flag('+') {
const pathSep = "/"
if i := strings.LastIndex(name, pathSep); i != -1 {
name = name[i+len(pathSep):]
}
const pkgSep = "."
if i := strings.Index(name, pkgSep); i != -1 {
name = name[i+len(pkgSep):]
}
}
io.WriteString(s, name)
}
}
// Frame returns the call frame infomation for the Call.
func (c Call) Frame() runtime.Frame {
return c.frame
}
// PC returns the program counter for this call frame; multiple frames may
// have the same PC value.
//
// Deprecated: Use Call.Frame instead.
func (c Call) PC() uintptr {
return c.frame.PC
}
// CallStack records a sequence of function invocations from a goroutine
// stack.
type CallStack []Call
// String implements fmt.Stinger. It is equivalent to fmt.Sprintf("%v", cs).
func (cs CallStack) String() string {
return fmt.Sprint(cs)
}
var (
openBracketBytes = []byte("[")
closeBracketBytes = []byte("]")
spaceBytes = []byte(" ")
)
// MarshalText implements encoding.TextMarshaler. It formats the CallStack the
// same as fmt.Sprintf("%v", cs).
func (cs CallStack) MarshalText() ([]byte, error) {
buf := bytes.Buffer{}
buf.Write(openBracketBytes)
for i, pc := range cs {
if i > 0 {
buf.Write(spaceBytes)
}
fmt.Fprint(&buf, pc)
}
buf.Write(closeBracketBytes)
return buf.Bytes(), nil
}
// Format implements fmt.Formatter by printing the CallStack as square brackets
// ([, ]) surrounding a space separated list of Calls each formatted with the
// supplied verb and options.
func (cs CallStack) Format(s fmt.State, verb rune) {
s.Write(openBracketBytes)
for i, pc := range cs {
if i > 0 {
s.Write(spaceBytes)
}
pc.Format(s, verb)
}
s.Write(closeBracketBytes)
}
// Trace returns a CallStack for the current goroutine with element 0
// identifying the calling function.
func Trace() CallStack {
var pcs [512]uintptr
n := runtime.Callers(1, pcs[:])
frames := runtime.CallersFrames(pcs[:n])
cs := make(CallStack, 0, n)
// Skip extra frame retrieved just to make sure the runtime.sigpanic
// special case is handled.
frame, more := frames.Next()
for more {
frame, more = frames.Next()
cs = append(cs, Call{frame: frame})
}
return cs
}
// TrimBelow returns a slice of the CallStack with all entries below c
// removed.
func (cs CallStack) TrimBelow(c Call) CallStack {
for len(cs) > 0 && cs[0] != c {
cs = cs[1:]
}
return cs
}
// TrimAbove returns a slice of the CallStack with all entries above c
// removed.
func (cs CallStack) TrimAbove(c Call) CallStack {
for len(cs) > 0 && cs[len(cs)-1] != c {
cs = cs[:len(cs)-1]
}
return cs
}
// pkgIndex returns the index that results in file[index:] being the path of
// file relative to the compile time GOPATH, and file[:index] being the
// $GOPATH/src/ portion of file. funcName must be the name of a function in
// file as returned by runtime.Func.Name.
func pkgIndex(file, funcName string) int {
// As of Go 1.6.2 there is no direct way to know the compile time GOPATH
// at runtime, but we can infer the number of path segments in the GOPATH.
// We note that runtime.Func.Name() returns the function name qualified by
// the import path, which does not include the GOPATH. Thus we can trim
// segments from the beginning of the file path until the number of path
// separators remaining is one more than the number of path separators in
// the function name. For example, given:
//
// GOPATH /home/user
// file /home/user/src/pkg/sub/file.go
// fn.Name() pkg/sub.Type.Method
//
// We want to produce:
//
// file[:idx] == /home/user/src/
// file[idx:] == pkg/sub/file.go
//
// From this we can easily see that fn.Name() has one less path separator
// than our desired result for file[idx:]. We count separators from the
// end of the file path until it finds two more than in the function name
// and then move one character forward to preserve the initial path
// segment without a leading separator.
const sep = "/"
i := len(file)
for n := strings.Count(funcName, sep) + 2; n > 0; n-- {
i = strings.LastIndex(file[:i], sep)
if i == -1 {
i = -len(sep)
break
}
}
// get back to 0 or trim the leading separator
return i + len(sep)
}
// pkgFilePath returns the frame's filepath relative to the compile-time GOPATH,
// or its module path joined to its path relative to the module root.
//
// As of Go 1.11 there is no direct way to know the compile time GOPATH or
// module paths at runtime, but we can piece together the desired information
// from available information. We note that runtime.Frame.Function contains the
// function name qualified by the package path, which includes the module path
// but not the GOPATH. We can extract the package path from that and append the
// last segments of the file path to arrive at the desired package qualified
// file path. For example, given:
//
// GOPATH /home/user
// import path pkg/sub
// frame.File /home/user/src/pkg/sub/file.go
// frame.Function pkg/sub.Type.Method
// Desired return pkg/sub/file.go
//
// It appears that we simply need to trim ".Type.Method" from frame.Function and
// append "/" + path.Base(file).
//
// But there are other wrinkles. Although it is idiomatic to do so, the internal
// name of a package is not required to match the last segment of its import
// path. In addition, the introduction of modules in Go 1.11 allows working
// without a GOPATH. So we also must make these work right:
//
// GOPATH /home/user
// import path pkg/go-sub
// package name sub
// frame.File /home/user/src/pkg/go-sub/file.go
// frame.Function pkg/sub.Type.Method
// Desired return pkg/go-sub/file.go
//
// Module path pkg/v2
// import path pkg/v2/go-sub
// package name sub
// frame.File /home/user/cloned-pkg/go-sub/file.go
// frame.Function pkg/v2/sub.Type.Method
// Desired return pkg/v2/go-sub/file.go
//
// We can handle all of these situations by using the package path extracted
// from frame.Function up to, but not including, the last segment as the prefix
// and the last two segments of frame.File as the suffix of the returned path.
// This preserves the existing behavior when working in a GOPATH without modules
// and a semantically equivalent behavior when used in module aware project.
func pkgFilePath(frame *runtime.Frame) string {
pre := pkgPrefix(frame.Function)
post := pathSuffix(frame.File)
if pre == "" {
return post
}
return pre + "/" + post
}
// pkgPrefix returns the import path of the function's package with the final
// segment removed.
func pkgPrefix(funcName string) string {
const pathSep = "/"
end := strings.LastIndex(funcName, pathSep)
if end == -1 {
return ""
}
return funcName[:end]
}
// pathSuffix returns the last two segments of path.
func pathSuffix(path string) string {
const pathSep = "/"
lastSep := strings.LastIndex(path, pathSep)
if lastSep == -1 {
return path
}
return path[strings.LastIndex(path[:lastSep], pathSep)+1:]
}
var runtimePath string
func init() {
var pcs [3]uintptr
runtime.Callers(0, pcs[:])
frames := runtime.CallersFrames(pcs[:])
frame, _ := frames.Next()
file := frame.File
idx := pkgIndex(frame.File, frame.Function)
runtimePath = file[:idx]
if runtime.GOOS == "windows" {
runtimePath = strings.ToLower(runtimePath)
}
}
func inGoroot(c Call) bool {
file := c.frame.File
if len(file) == 0 || file[0] == '?' {
return true
}
if runtime.GOOS == "windows" {
file = strings.ToLower(file)
}
return strings.HasPrefix(file, runtimePath) || strings.HasSuffix(file, "/_testmain.go")
}
// TrimRuntime returns a slice of the CallStack with the topmost entries from
// the go runtime removed. It considers any calls originating from unknown
// files, files under GOROOT, or _testmain.go as part of the runtime.
func (cs CallStack) TrimRuntime() CallStack {
for len(cs) > 0 && inGoroot(cs[len(cs)-1]) {
cs = cs[:len(cs)-1]
}
return cs
}

202
vendor/github.com/oxtoacart/bpool/LICENSE generated vendored Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2014 Percy Wegmann
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

65
vendor/github.com/oxtoacart/bpool/README.md generated vendored Normal file
View File

@ -0,0 +1,65 @@
# bpool [![GoDoc](https://godoc.org/github.com/oxtoacart/bpool?status.png)](https://godoc.org/github.com/oxtoacart/bpool)
Package bpool implements leaky pools of byte arrays and Buffers as bounded channels.
It is based on the leaky buffer example from the Effective Go documentation: http://golang.org/doc/effective_go.html#leaky_buffer
bpool provides the following pool types:
* [bpool.BufferPool](https://godoc.org/github.com/oxtoacart/bpool#BufferPool)
which provides a fixed-size pool of
[bytes.Buffers](http://golang.org/pkg/bytes/#Buffer).
* [bpool.BytePool](https://godoc.org/github.com/oxtoacart/bpool#BytePool) which
provides a fixed-size pool of `[]byte` slices with a pre-set width (length).
* [bpool.SizedBufferPool](https://godoc.org/github.com/oxtoacart/bpool#SizedBufferPool),
which is an alternative to `bpool.BufferPool` that pre-sizes the capacity of
buffers issued from the pool and discards buffers that have grown too large
upon return.
A common use case for this package is to use buffers to execute HTML templates
against (via ExecuteTemplate) or encode JSON into (via json.NewEncoder). This
allows you to catch any rendering or marshalling errors prior to writing to a
`http.ResponseWriter`, which helps to avoid writing incomplete or malformed data
to the response.
## Install
`go get github.com/oxtoacart/bpool`
## Documentation
See [godoc.org](http://godoc.org/github.com/oxtoacart/bpool) or use `godoc github.com/oxtoacart/bpool`
## Example
Here's a quick example for using `bpool.BufferPool`. We create a pool of the
desired size, call the `Get()` method to obtain a buffer for use, and call
`Put(buf)` to return the buffer to the pool.
```go
var bufpool *bpool.BufferPool
func main() {
bufpool = bpool.NewBufferPool(48)
}
func someFunction() error {
// Get a buffer from the pool
buf := bufpool.Get()
...
...
...
// Return the buffer to the pool
bufpool.Put(buf)
return nil
}
```
## License
Apache 2.0 Licensed. See the LICENSE file for details.

6
vendor/github.com/oxtoacart/bpool/bpool.go generated vendored Normal file
View File

@ -0,0 +1,6 @@
/*
Package bpool implements leaky pools of byte arrays and Buffers as bounded
channels. It is based on the leaky buffer example from the Effective Go
documentation: http://golang.org/doc/effective_go.html#leaky_buffer
*/
package bpool

45
vendor/github.com/oxtoacart/bpool/bufferpool.go generated vendored Normal file
View File

@ -0,0 +1,45 @@
package bpool
import (
"bytes"
)
// BufferPool implements a pool of bytes.Buffers in the form of a bounded
// channel.
type BufferPool struct {
c chan *bytes.Buffer
}
// NewBufferPool creates a new BufferPool bounded to the given size.
func NewBufferPool(size int) (bp *BufferPool) {
return &BufferPool{
c: make(chan *bytes.Buffer, size),
}
}
// Get gets a Buffer from the BufferPool, or creates a new one if none are
// available in the pool.
func (bp *BufferPool) Get() (b *bytes.Buffer) {
select {
case b = <-bp.c:
// reuse existing buffer
default:
// create new buffer
b = bytes.NewBuffer([]byte{})
}
return
}
// Put returns the given Buffer to the BufferPool.
func (bp *BufferPool) Put(b *bytes.Buffer) {
b.Reset()
select {
case bp.c <- b:
default: // Discard the buffer if the pool is full.
}
}
// NumPooled returns the number of items currently pooled.
func (bp *BufferPool) NumPooled() int {
return len(bp.c)
}

56
vendor/github.com/oxtoacart/bpool/bytepool.go generated vendored Normal file
View File

@ -0,0 +1,56 @@
package bpool
// BytePool implements a leaky pool of []byte in the form of a bounded
// channel.
type BytePool struct {
c chan []byte
w int
h int
}
// NewBytePool creates a new BytePool bounded to the given maxSize, with new
// byte arrays sized based on width.
func NewBytePool(maxSize int, width int) (bp *BytePool) {
return &BytePool{
c: make(chan []byte, maxSize),
w: width,
}
}
// Get gets a []byte from the BytePool, or creates a new one if none are
// available in the pool.
func (bp *BytePool) Get() (b []byte) {
select {
case b = <-bp.c:
// reuse existing buffer
default:
// create new buffer
b = make([]byte, bp.w)
}
return
}
// Put returns the given Buffer to the BytePool.
func (bp *BytePool) Put(b []byte) {
if cap(b) < bp.w {
// someone tried to put back a too small buffer, discard it
return
}
select {
case bp.c <- b[:bp.w]:
// buffer went back into pool
default:
// buffer didn't go back into pool, just discard
}
}
// NumPooled returns the number of items currently pooled.
func (bp *BytePool) NumPooled() int {
return len(bp.c)
}
// Width returns the width of the byte arrays in this pool.
func (bp *BytePool) Width() (n int) {
return bp.w
}

81
vendor/github.com/oxtoacart/bpool/byteslice.go generated vendored Normal file
View File

@ -0,0 +1,81 @@
package bpool
// WrapByteSlice wraps a []byte as a ByteSlice
func WrapByteSlice(full []byte, headerLength int) ByteSlice {
return ByteSlice{
full: full,
current: full[headerLength:],
head: headerLength,
end: len(full),
}
}
// ByteSlice provides a wrapper around []byte with some added convenience
type ByteSlice struct {
full []byte
current []byte
head int
end int
}
// ResliceTo reslices the end of the current slice.
func (b ByteSlice) ResliceTo(end int) ByteSlice {
return ByteSlice{
full: b.full,
current: b.current[:end],
head: b.head,
end: b.head + end,
}
}
// Bytes returns the current slice
func (b ByteSlice) Bytes() []byte {
return b.current
}
// BytesWithHeader returns the current slice preceded by the header
func (b ByteSlice) BytesWithHeader() []byte {
return b.full[:b.end]
}
// Full returns the full original buffer underlying the ByteSlice
func (b ByteSlice) Full() []byte {
return b.full
}
// ByteSlicePool is a bool of byte slices
type ByteSlicePool interface {
// Get gets a byte slice from the pool
GetSlice() ByteSlice
// Put returns a byte slice to the pool
PutSlice(ByteSlice)
// NumPooled returns the number of currently pooled items
NumPooled() int
}
// NewByteSlicePool creates a new ByteSlicePool bounded to the
// given maxSize, with new byte arrays sized based on width
func NewByteSlicePool(maxSize int, width int) ByteSlicePool {
return NewHeaderPreservingByteSlicePool(maxSize, width, 0)
}
// NewHeaderPreservingByteSlicePool creates a new ByteSlicePool bounded to the
// given maxSize, with new byte arrays sized based on width and headerLength
// preserved at the beginning of the slice.
func NewHeaderPreservingByteSlicePool(maxSize int, width int, headerLength int) ByteSlicePool {
return &BytePool{
c: make(chan []byte, maxSize),
w: width + headerLength,
h: headerLength,
}
}
// GetSlice implements the method from interface ByteSlicePool
func (bp *BytePool) GetSlice() ByteSlice {
return WrapByteSlice(bp.Get(), bp.h)
}
// PutSlice implements the method from interface ByteSlicePool
func (bp *BytePool) PutSlice(b ByteSlice) {
bp.Put(b.Full())
}

5
vendor/github.com/oxtoacart/bpool/go.mod generated vendored Normal file
View File

@ -0,0 +1,5 @@
module github.com/oxtoacart/bpool
go 1.12
require github.com/stretchr/testify v1.3.0

7
vendor/github.com/oxtoacart/bpool/go.sum generated vendored Normal file
View File

@ -0,0 +1,7 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=

60
vendor/github.com/oxtoacart/bpool/sizedbufferpool.go generated vendored Normal file
View File

@ -0,0 +1,60 @@
package bpool
import (
"bytes"
)
// SizedBufferPool implements a pool of bytes.Buffers in the form of a bounded
// channel. Buffers are pre-allocated to the requested size.
type SizedBufferPool struct {
c chan *bytes.Buffer
a int
}
// SizedBufferPool creates a new BufferPool bounded to the given size.
// size defines the number of buffers to be retained in the pool and alloc sets
// the initial capacity of new buffers to minimize calls to make().
//
// The value of alloc should seek to provide a buffer that is representative of
// most data written to the the buffer (i.e. 95th percentile) without being
// overly large (which will increase static memory consumption). You may wish to
// track the capacity of your last N buffers (i.e. using an []int) prior to
// returning them to the pool as input into calculating a suitable alloc value.
func NewSizedBufferPool(size int, alloc int) (bp *SizedBufferPool) {
return &SizedBufferPool{
c: make(chan *bytes.Buffer, size),
a: alloc,
}
}
// Get gets a Buffer from the SizedBufferPool, or creates a new one if none are
// available in the pool. Buffers have a pre-allocated capacity.
func (bp *SizedBufferPool) Get() (b *bytes.Buffer) {
select {
case b = <-bp.c:
// reuse existing buffer
default:
// create new buffer
b = bytes.NewBuffer(make([]byte, 0, bp.a))
}
return
}
// Put returns the given Buffer to the SizedBufferPool.
func (bp *SizedBufferPool) Put(b *bytes.Buffer) {
b.Reset()
// Release buffers over our maximum capacity and re-create a pre-sized
// buffer to replace it.
// Note that the cap(b.Bytes()) provides the capacity from the read off-set
// only, but as we've called b.Reset() the full capacity of the underlying
// byte slice is returned.
if cap(b.Bytes()) > bp.a {
b = bytes.NewBuffer(make([]byte, 0, bp.a))
}
select {
case bp.c <- b:
default: // Discard the buffer if the pool is full.
}
}

20
vendor/modules.txt vendored
View File

@ -1,5 +1,23 @@
# github.com/davecgh/go-spew v1.1.1
github.com/davecgh/go-spew/spew
# github.com/getlantern/byteexec v0.0.0-20170405023437-4cfb26ec74f4
github.com/getlantern/byteexec
# github.com/getlantern/context v0.0.0-20190109183933-c447772a6520
github.com/getlantern/context
# github.com/getlantern/errors v1.0.1
github.com/getlantern/errors
# github.com/getlantern/filepersist v0.0.0-20160317154340-c5f0cd24e799
github.com/getlantern/filepersist
# github.com/getlantern/golog v0.0.0-20201105130739-9586b8bde3a9
github.com/getlantern/golog
# github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7
github.com/getlantern/hex
# github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55
github.com/getlantern/hidden
# github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f
github.com/getlantern/ops
# github.com/go-stack/stack v1.8.0
github.com/go-stack/stack
# github.com/konsorten/go-windows-terminal-sequences v1.0.1
github.com/konsorten/go-windows-terminal-sequences
# github.com/mdlayher/genetlink v0.0.0-20191008151445-a2cadeac9a63
@ -7,6 +25,8 @@ github.com/mdlayher/genetlink
# github.com/mdlayher/netlink v0.0.0-20191009155606-de872b0d824b
github.com/mdlayher/netlink
github.com/mdlayher/netlink/nlenc
# github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c
github.com/oxtoacart/bpool
# github.com/pmezard/go-difflib v1.0.0
github.com/pmezard/go-difflib/difflib
# github.com/sirupsen/logrus v1.4.0

33
wg.go
View File

@ -8,13 +8,34 @@ import (
"os/exec"
"strings"
"syscall"
"time"
"github.com/getlantern/byteexec"
"github.com/sirupsen/logrus"
"github.com/vishvananda/netlink"
"go.xsfx.dev/wg-quicker/assets"
"golang.org/x/sys/unix"
"golang.zx2c4.com/wireguard/wgctrl"
)
// wgGo runs a embedded wireguard-go for interface creation.
func wgGo(iface string) error {
wgob, err := assets.Asset("bin/wireguard-go")
if err != nil {
return fmt.Errorf("cannot get wireguard-go: %w", err)
}
wgo, err := byteexec.New(wgob, "wireguard-go")
if err != nil {
return fmt.Errorf("unable to build byteexec for wireguard-go: %w", err)
}
cmd := wgo.Command(iface)
cmd.Start()
return nil
}
// Up sets and configures the wg interface. Mostly equivalent to `wg-quick up iface`
func Up(cfg *Config, iface string, logger logrus.FieldLogger) error {
log := logger.WithField("iface", iface)
@ -172,6 +193,7 @@ func SyncLink(cfg *Config, iface string, log logrus.FieldLogger) (netlink.Link,
return nil, err
}
log.Info("link not found, creating")
wgLink := &netlink.GenericLink{
LinkAttrs: netlink.LinkAttrs{
Name: iface,
@ -180,11 +202,16 @@ func SyncLink(cfg *Config, iface string, log logrus.FieldLogger) (netlink.Link,
LinkType: "wireguard",
}
if err := netlink.LinkAdd(wgLink); err != nil {
log.WithError(err).Error("cannot create link")
return nil, err
log.WithError(err).Errorf("cannot create link: %w", err)
log.Info("trying to use embedded wireguard-go...")
if err := wgGo(iface); err != nil {
log.WithError(err).Errorf("cannot create link through wireguard-go: %w", err)
return nil, fmt.Errorf("cannot create link")
}
}
// TODO: ADD WIREGUARD-GO HERE!!!1111!!
// Needs some sleeping to wait for interface creating.
time.Sleep(1 * time.Second)
link, err = netlink.LinkByName(iface)
if err != nil {