generated from moul/golang-repo-template
-
-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: POC
- Loading branch information
Showing
12 changed files
with
359 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,12 +18,12 @@ changelog: | |
- '^docs:' | ||
- '^test:' | ||
brew: | ||
name: golang-repo-template | ||
name: quicssh | ||
github: | ||
owner: moul | ||
name: homebrew-moul | ||
commit_author: | ||
name: moul-bot | ||
email: "[email protected]" | ||
homepage: https://manfred.life/ | ||
description: "golang-repo-template" | ||
description: "quicssh" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,29 @@ | ||
# golang-repo-template | ||
# quicssh | ||
|
||
:smile: golang-repo-template does | ||
:smile: quicssh does | ||
|
||
[![CircleCI](https://circleci.com/gh/moul/golang-repo-template.svg?style=shield)](https://circleci.com/gh/moul/golang-repo-template) | ||
[![GoDoc](https://godoc.org/moul.io/golang-repo-template?status.svg)](https://godoc.org/moul.io/golang-repo-template) | ||
[![License](https://img.shields.io/github/license/moul/golang-repo-template.svg)](https://github.com/moul/golang-repo-template/blob/master/LICENSE) | ||
[![GitHub release](https://img.shields.io/github/release/moul/golang-repo-template.svg)](https://github.com/moul/golang-repo-template/releases) | ||
[![Go Report Card](https://goreportcard.com/badge/moul.io/golang-repo-template)](https://goreportcard.com/report/moul.io/golang-repo-template) | ||
[![Docker Metrics](https://images.microbadger.com/badges/image/moul/golang-repo-template.svg)](https://microbadger.com/images/moul/golang-repo-template) | ||
[![CircleCI](https://circleci.com/gh/moul/quicssh.svg?style=shield)](https://circleci.com/gh/moul/quicssh) | ||
[![GoDoc](https://godoc.org/moul.io/quicssh?status.svg)](https://godoc.org/moul.io/quicssh) | ||
[![License](https://img.shields.io/github/license/moul/quicssh.svg)](https://github.com/moul/quicssh/blob/master/LICENSE) | ||
[![GitHub release](https://img.shields.io/github/release/moul/quicssh.svg)](https://github.com/moul/quicssh/releases) | ||
[![Go Report Card](https://goreportcard.com/badge/moul.io/quicssh)](https://goreportcard.com/report/moul.io/quicssh) | ||
[![Docker Metrics](https://images.microbadger.com/badges/image/moul/quicssh.svg)](https://microbadger.com/images/moul/quicssh) | ||
[![Made by Manfred Touron](https://img.shields.io/badge/made%20by-Manfred%20Touron-blue.svg?style=flat)](https://manfred.life/) | ||
|
||
## Usage | ||
|
||
```console | ||
$ golang-repo-template -h | ||
$ quicssh -h | ||
... | ||
``` | ||
|
||
## Install | ||
|
||
```console | ||
$ go get -u moul.io/golang-repo-template | ||
$ go get -u moul.io/quicssh | ||
``` | ||
|
||
## License | ||
|
||
© 2019 [Manfred Touron](https://manfred.life) - | ||
[Apache-2.0 License](https://github.com/moul/golang-repo-template/blob/master/LICENSE) | ||
[Apache-2.0 License](https://github.com/moul/quicssh/blob/master/LICENSE) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package main | ||
|
||
import ( | ||
"crypto/tls" | ||
"log" | ||
"os" | ||
"sync" | ||
|
||
quic "github.com/lucas-clemente/quic-go" | ||
"golang.org/x/net/context" | ||
cli "gopkg.in/urfave/cli.v2" | ||
) | ||
|
||
func client(c *cli.Context) error { | ||
ctx, cancel := context.WithCancel(context.Background()) | ||
|
||
config := &tls.Config{ | ||
InsecureSkipVerify: true, | ||
NextProtos: []string{"quicssh"}, | ||
} | ||
|
||
log.Printf("Dialing %q...", c.String("addr")) | ||
session, err := quic.DialAddr(c.String("addr"), config, nil) | ||
if err != nil { | ||
return err | ||
} | ||
defer session.Close() | ||
|
||
log.Printf("Opening stream sync...") | ||
stream, err := session.OpenStreamSync(ctx) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
log.Printf("Piping stream with QUIC...") | ||
var wg sync.WaitGroup | ||
wg.Add(3) | ||
c1 := readAndWrite(ctx, stream, os.Stdout, &wg) | ||
c2 := readAndWrite(ctx, os.Stdin, stream, &wg) | ||
select { | ||
case err = <-c1: | ||
if err != nil { | ||
return err | ||
} | ||
case err = <-c2: | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
cancel() | ||
wg.Wait() | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,9 @@ | ||
module moul.io/golang-repo-template | ||
module moul.io/quicssh | ||
|
||
go 1.12 | ||
|
||
require ( | ||
github.com/lucas-clemente/quic-go v0.7.1-0.20190710050138-1441923ab031 | ||
golang.org/x/net v0.0.0-20190228165749-92fc7df08ae7 | ||
gopkg.in/urfave/cli.v2 v2.0.0-20180128182452-d3ae77c26ac8 | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= | ||
github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= | ||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= | ||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= | ||
github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk= | ||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= | ||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||
github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk= | ||
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= | ||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= | ||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= | ||
github.com/lucas-clemente/quic-go v0.7.1-0.20190710050138-1441923ab031 h1:wjcGvgllMOQw8wNYFH6acq/KlTAdjKMSo1EUYybHXto= | ||
github.com/lucas-clemente/quic-go v0.7.1-0.20190710050138-1441923ab031/go.mod h1:lb5aAxL68VvhZ00e7yYuQVK/9FLggtYy4qo7oI5qzqA= | ||
github.com/marten-seemann/qpack v0.1.0 h1:/0M7lkda/6mus9B8u34Asqm8ZhHAAt9Ho0vniNuVSVg= | ||
github.com/marten-seemann/qpack v0.1.0/go.mod h1:LFt1NU/Ptjip0C2CPkhimBz5CGE3WGDAUWqna+CNTrI= | ||
github.com/marten-seemann/qtls v0.3.1 h1:ySYIvhFjFY2JsNHY6VACvomMEDy3EvdPA6yciUFAiHw= | ||
github.com/marten-seemann/qtls v0.3.1/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk= | ||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= | ||
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= | ||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= | ||
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= | ||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= | ||
golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25 h1:jsG6UpNLt9iAsb0S2AGW28DveNzzgmbXR+ENoPjUeIU= | ||
golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||
golang.org/x/net v0.0.0-20190228165749-92fc7df08ae7 h1:Qe/u+eY379X4He4GBMFZYu3pmh1ML5yT1aL1ndNM1zQ= | ||
golang.org/x/net v0.0.0-20190228165749-92fc7df08ae7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= | ||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||
golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e h1:ZytStCyV048ZqDsWHiYDdoI2Vd4msMcrDECFxS+tL9c= | ||
golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= | ||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= | ||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= | ||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= | ||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= | ||
gopkg.in/urfave/cli.v2 v2.0.0-20180128182452-d3ae77c26ac8 h1:Ggy3mWN4l3PUFPfSG0YB3n5fVYggzysUmiUQ89SnX6Y= | ||
gopkg.in/urfave/cli.v2 v2.0.0-20180128182452-d3ae77c26ac8/go.mod h1:cKXr3E0k4aosgycml1b5z33BVV6hai1Kh7uDgFOkbcs= | ||
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= | ||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,63 @@ | ||
package main // import "moul.io/golang-repo-template" | ||
package main | ||
|
||
import "fmt" | ||
import ( | ||
"io" | ||
"os" | ||
"sync" | ||
|
||
"golang.org/x/net/context" | ||
cli "gopkg.in/urfave/cli.v2" | ||
) | ||
|
||
func main() { | ||
fmt.Println("Hello World!") | ||
app := &cli.App{ | ||
Commands: []*cli.Command{ | ||
{ | ||
Name: "server", | ||
Flags: []cli.Flag{ | ||
&cli.StringFlag{Name: "bind", Value: "localhost:4242"}, | ||
}, | ||
Action: server, | ||
}, | ||
{ | ||
Name: "client", | ||
Flags: []cli.Flag{ | ||
&cli.StringFlag{Name: "addr", Value: "localhost:4242"}, | ||
}, | ||
Action: client, | ||
}, | ||
}, | ||
} | ||
if err := app.Run(os.Args); err != nil { | ||
panic(err) | ||
} | ||
} | ||
|
||
func readAndWrite(ctx context.Context, r io.Reader, w io.Writer, wg *sync.WaitGroup) <-chan error { | ||
c := make(chan error) | ||
go func() { | ||
if wg != nil { | ||
defer wg.Done() | ||
} | ||
buff := make([]byte, 1024) | ||
|
||
for { | ||
select { | ||
case <-ctx.Done(): | ||
return | ||
default: | ||
nr, err := r.Read(buff) | ||
if err != nil { | ||
return | ||
} | ||
if nr > 0 { | ||
_, err := w.Write(buff[:nr]) | ||
if err != nil { | ||
return | ||
} | ||
} | ||
} | ||
} | ||
}() | ||
return c | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
package main | ||
|
||
import ( | ||
"crypto/rand" | ||
"crypto/rsa" | ||
"crypto/tls" | ||
"crypto/x509" | ||
"encoding/pem" | ||
"io" | ||
"log" | ||
"math/big" | ||
"net" | ||
"sync" | ||
|
||
quic "github.com/lucas-clemente/quic-go" | ||
"golang.org/x/net/context" | ||
cli "gopkg.in/urfave/cli.v2" | ||
) | ||
|
||
func server(c *cli.Context) error { | ||
// generate TLS certificate | ||
key, err := rsa.GenerateKey(rand.Reader, 1024) | ||
if err != nil { | ||
return err | ||
} | ||
template := x509.Certificate{SerialNumber: big.NewInt(1)} | ||
certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &key.PublicKey, key) | ||
if err != nil { | ||
return err | ||
} | ||
keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key)}) | ||
certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER}) | ||
tlsCert, err := tls.X509KeyPair(certPEM, keyPEM) | ||
if err != nil { | ||
return err | ||
} | ||
config := &tls.Config{ | ||
Certificates: []tls.Certificate{tlsCert}, | ||
NextProtos: []string{"quicssh"}, | ||
} | ||
|
||
// configure listener | ||
listener, err := quic.ListenAddr(c.String("bind"), config, nil) | ||
if err != nil { | ||
return err | ||
} | ||
defer listener.Close() | ||
log.Printf("Listening at %q...", c.String("bind")) | ||
|
||
ctx := context.Background() | ||
for { | ||
log.Printf("Accepting connection...") | ||
session, err := listener.Accept(ctx) | ||
if err != nil { | ||
log.Printf("listener error: %v", err) | ||
continue | ||
} | ||
|
||
go serverSessionHandler(ctx, session) | ||
} | ||
return nil | ||
} | ||
|
||
func serverSessionHandler(ctx context.Context, session quic.Session) { | ||
log.Printf("hanling session...") | ||
defer session.Close() | ||
for { | ||
stream, err := session.AcceptStream(ctx) | ||
if err != nil { | ||
log.Printf("session error: %v", err) | ||
break | ||
} | ||
go serverStreamHandler(ctx, stream) | ||
} | ||
} | ||
|
||
func serverStreamHandler(ctx context.Context, conn io.ReadWriteCloser) { | ||
log.Printf("handling stream...") | ||
defer conn.Close() | ||
|
||
rConn, err := net.DialTCP("tcp", nil, &net.TCPAddr{IP: net.IP{127, 0, 0, 1}, Port: 22}) | ||
if err != nil { | ||
log.Printf("dial error: %v", err) | ||
return | ||
} | ||
defer rConn.Close() | ||
|
||
ctx, cancel := context.WithCancel(ctx) | ||
|
||
var wg sync.WaitGroup | ||
wg.Add(2) | ||
c1 := readAndWrite(ctx, conn, rConn, &wg) | ||
c2 := readAndWrite(ctx, rConn, conn, &wg) | ||
select { | ||
case err = <-c1: | ||
if err != nil { | ||
log.Printf("readAndWrite error on c1: %v", err) | ||
return | ||
} | ||
case err = <-c2: | ||
if err != nil { | ||
log.Printf("readAndWrite error on c2: %v", err) | ||
return | ||
} | ||
} | ||
cancel() | ||
wg.Wait() | ||
log.Printf("Piping finished") | ||
} | ||
|
||
func netCopy(input io.Reader, output io.Writer) (err error) { | ||
buf := make([]byte, 8192) | ||
for { | ||
count, err := input.Read(buf) | ||
if err != nil { | ||
if err == io.EOF && count > 0 { | ||
output.Write(buf[:count]) | ||
} | ||
break | ||
} | ||
if count > 0 { | ||
log.Println(buf, count) | ||
output.Write(buf[:count]) | ||
} | ||
} | ||
return | ||
} |
Oops, something went wrong.