Last active
December 22, 2018 18:03
-
-
Save upperwal/ffecb9e8015a87a128eba9c7beefd6b9 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
package main | |
import ( | |
"bufio" | |
"crypto/ecdsa" | |
"crypto/elliptic" | |
"crypto/rand" | |
"crypto/tls" | |
"crypto/x509" | |
"errors" | |
"flag" | |
"fmt" | |
"math/big" | |
mrand "math/rand" | |
"net" | |
"os" | |
"strings" | |
"time" | |
"github.com/gogo/protobuf/proto" | |
"github.com/libp2p/go-libp2p-crypto" | |
ic "github.com/libp2p/go-libp2p-crypto" | |
pb "github.com/libp2p/go-libp2p-crypto/pb" | |
quic "github.com/lucas-clemente/quic-go" | |
) | |
const hostname = "quic.ipfs" | |
const certValidityPeriod = 180 * 24 * time.Hour | |
func keyToCertificate(sk ic.PrivKey) (interface{}, *x509.Certificate, error) { | |
sn, err := rand.Int(rand.Reader, big.NewInt(1<<62)) | |
if err != nil { | |
return nil, nil, err | |
} | |
tmpl := &x509.Certificate{ | |
SerialNumber: sn, | |
NotBefore: time.Now().Add(-24 * time.Hour), | |
NotAfter: time.Now().Add(certValidityPeriod), | |
IsCA: true, | |
BasicConstraintsValid: true, | |
} | |
var publicKey, privateKey interface{} | |
keyBytes, err := sk.Bytes() | |
if err != nil { | |
return nil, nil, err | |
} | |
pbmes := new(pb.PrivateKey) | |
if err := proto.Unmarshal(keyBytes, pbmes); err != nil { | |
return nil, nil, err | |
} | |
switch pbmes.GetType() { | |
case pb.KeyType_RSA: | |
k, err := x509.ParsePKCS1PrivateKey(pbmes.GetData()) | |
if err != nil { | |
return nil, nil, err | |
} | |
publicKey = &k.PublicKey | |
privateKey = k | |
// TODO: add support for ECDSA | |
default: | |
return nil, nil, errors.New("unsupported key type for TLS") | |
} | |
certDER, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, publicKey, privateKey) | |
if err != nil { | |
return nil, nil, err | |
} | |
cert, err := x509.ParseCertificate(certDER) | |
if err != nil { | |
return nil, nil, err | |
} | |
return privateKey, cert, nil | |
} | |
func generateConfig(privKey ic.PrivKey) (*tls.Config, error) { | |
key, hostCert, err := keyToCertificate(privKey) | |
if err != nil { | |
return nil, err | |
} | |
// The ephemeral key used just for a couple of connections (or a limited time). | |
ephemeralKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) | |
if err != nil { | |
return nil, err | |
} | |
// Sign the ephemeral key using the host key. | |
// This is the only time that the host's private key of the peer is needed. | |
// Note that this step could be done asynchronously, such that a running node doesn't need access its private key at all. | |
certTemplate := &x509.Certificate{ | |
DNSNames: []string{hostname}, | |
SerialNumber: big.NewInt(1), | |
NotBefore: time.Now().Add(-24 * time.Hour), | |
NotAfter: time.Now().Add(certValidityPeriod), | |
} | |
certDER, err := x509.CreateCertificate(rand.Reader, certTemplate, hostCert, ephemeralKey.Public(), key) | |
if err != nil { | |
return nil, err | |
} | |
cert, err := x509.ParseCertificate(certDER) | |
if err != nil { | |
return nil, err | |
} | |
return &tls.Config{ | |
ServerName: hostname, | |
InsecureSkipVerify: true, // This is not insecure here. We will verify the cert chain ourselves. | |
ClientAuth: tls.RequireAnyClientCert, | |
Certificates: []tls.Certificate{{ | |
Certificate: [][]byte{cert.Raw, hostCert.Raw}, | |
PrivateKey: ephemeralKey, | |
}}, | |
}, nil | |
} | |
var quicConfig = &quic.Config{ | |
Versions: []quic.VersionNumber{101}, | |
MaxIncomingStreams: 1000, | |
MaxIncomingUniStreams: -1, // disable unidirectional streams | |
MaxReceiveStreamFlowControlWindow: 3 * (1 << 20), // 3 MB | |
MaxReceiveConnectionFlowControlWindow: 4.5 * (1 << 20), // 4.5 MB | |
AcceptCookie: func(clientAddr net.Addr, cookie *quic.Cookie) bool { | |
// TODO(#6): require source address validation when under load | |
return true | |
}, | |
KeepAlive: true, | |
} | |
func handleAccept(l quic.Listener) { | |
for { | |
s, err := l.Accept() | |
if err != nil { | |
fmt.Println(err) | |
os.Exit(1) | |
} | |
fmt.Println("Connected to: ", s.RemoteAddr()) | |
/* if !_remote { | |
ss, err := quic.Dial(*_pconn, s.RemoteAddr(), "0.0.0.0:0", _tlsConfig, quicConfig) | |
if err != nil { | |
fmt.Println(err) | |
os.Exit(1) | |
} | |
fmt.Println("Back Connected to: ", ss.RemoteAddr()) | |
} */ | |
} | |
} | |
func main() { | |
port := flag.String("p", "0", "port") | |
flag.Parse() | |
pconn, err := net.ListenPacket("udp4", "0.0.0.0:"+*port) | |
if err != nil { | |
fmt.Println(err) | |
os.Exit(1) | |
} | |
fmt.Println("My: ", pconn.LocalAddr()) | |
pconn_laddr := pconn.LocalAddr().String() | |
idx := strings.LastIndex(pconn_laddr, ":") | |
port_str := pconn_laddr[idx+1:] | |
r := mrand.New(mrand.NewSource(int64(35544))) | |
prvKey, _, err := crypto.GenerateKeyPairWithReader(crypto.RSA, 2048, r) | |
if err != nil { | |
panic(err) | |
} | |
tlsConf, err := generateConfig(prvKey) | |
if err != nil { | |
fmt.Println(err) | |
os.Exit(1) | |
} | |
l, err := quic.Listen(pconn, tlsConf, quicConfig) | |
if err != nil { | |
fmt.Println(err) | |
os.Exit(1) | |
} | |
go handleAccept(l) | |
reader := bufio.NewReader(os.Stdin) | |
for { | |
fmt.Print("Enter text: ") | |
text, _ := reader.ReadString('\n') | |
text = strings.TrimRight(text, "\n") | |
fmt.Println("Remote: ", text) | |
addr, err := net.ResolveUDPAddr("udp", text) | |
if err != nil { | |
fmt.Println("ResolveUDPAddr err ", err) | |
os.Exit(1) | |
} | |
s, err := quic.Dial(pconn, addr, "192.168.0.102:"+port_str, tlsConf, quicConfig) | |
if err != nil { | |
fmt.Println(err) | |
os.Exit(1) | |
} | |
fmt.Println("Connected to: ", s.RemoteAddr(), s.LocalAddr()) | |
} | |
select {} | |
} |
This file contains hidden or 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
package main | |
import ( | |
"bufio" | |
"flag" | |
"fmt" | |
"net" | |
"os" | |
"strings" | |
) | |
func handleIncoming(conn *net.UDPConn) { | |
b := make([]byte, 1024*10) | |
for { | |
n, addr, err := conn.ReadFromUDP(b) | |
if err != nil { | |
fmt.Println(err) | |
os.Exit(1) | |
} | |
fmt.Println("Read", n, "bytes from", addr, "data", string(b[:n])) | |
} | |
} | |
func main() { | |
port := flag.String("p", "0", "port") | |
flag.Parse() | |
laddr, err := net.ResolveUDPAddr("udp", "0.0.0.0:"+*port) | |
pconn, err := net.ListenUDP("udp4", laddr) | |
if err != nil { | |
fmt.Println(err) | |
os.Exit(1) | |
} | |
fmt.Println("My: ", pconn.LocalAddr()) | |
go handleIncoming(pconn) | |
reader := bufio.NewReader(os.Stdin) | |
for { | |
fmt.Print("Enter text: ") | |
text, _ := reader.ReadString('\n') | |
text = strings.TrimRight(text, "\n") | |
fmt.Println("Remote: ", text) | |
raddr, err := net.ResolveUDPAddr("udp", text) | |
n, err := pconn.WriteTo([]byte("Abhishek"), raddr) | |
if err != nil { | |
fmt.Println(err) | |
} | |
fmt.Println("Written: ", n) | |
} | |
select {} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment