forked from quic-go/quic-go
pull some stuff from main.go into server.go
This commit is contained in:
@@ -3,17 +3,13 @@ package main
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"golang.org/x/net/http2"
|
"golang.org/x/net/http2"
|
||||||
"golang.org/x/net/http2/hpack"
|
"golang.org/x/net/http2/hpack"
|
||||||
|
|
||||||
"github.com/lucas-clemente/quic-go"
|
"github.com/lucas-clemente/quic-go"
|
||||||
"github.com/lucas-clemente/quic-go/crypto"
|
|
||||||
"github.com/lucas-clemente/quic-go/handshake"
|
|
||||||
"github.com/lucas-clemente/quic-go/protocol"
|
"github.com/lucas-clemente/quic-go/protocol"
|
||||||
"github.com/lucas-clemente/quic-go/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var supportedVersions = map[protocol.VersionNumber]bool{
|
var supportedVersions = map[protocol.VersionNumber]bool{
|
||||||
@@ -23,71 +19,16 @@ var supportedVersions = map[protocol.VersionNumber]bool{
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
path := os.Getenv("GOPATH") + "/src/github.com/lucas-clemente/quic-go/example/"
|
path := os.Getenv("GOPATH") + "/src/github.com/lucas-clemente/quic-go/example/"
|
||||||
keyData, err := crypto.LoadKeyData(path+"cert.der", path+"key.der")
|
|
||||||
|
server, err := quic.NewServer(path+"cert.der", path+"key.der", handleStream)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
serverConfig := handshake.NewServerConfig(crypto.NewCurve25519KEX(), keyData)
|
err = server.ListenAndServe("localhost:6121")
|
||||||
|
|
||||||
// TODO: When should a session be created?
|
|
||||||
sessions := map[protocol.ConnectionID]*quic.Session{}
|
|
||||||
|
|
||||||
addr, err := net.ResolveUDPAddr("udp", "localhost:6121")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
conn, err := net.ListenUDP("udp", addr)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
|
||||||
data := make([]byte, 0x10000)
|
|
||||||
n, remoteAddr, err := conn.ReadFromUDP(data)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
data = data[:n]
|
|
||||||
r := bytes.NewReader(data)
|
|
||||||
|
|
||||||
fmt.Printf("Received %d bytes from %v\n", n, remoteAddr)
|
|
||||||
|
|
||||||
publicHeader, err := quic.ParsePublicHeader(r)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
fmt.Printf("Got packet # %d\n", publicHeader.PacketNumber)
|
|
||||||
|
|
||||||
// Send Version Negotiation Packet if the client is speaking a different protocol version
|
|
||||||
if publicHeader.VersionFlag && !supportedVersions[publicHeader.VersionNumber] {
|
|
||||||
fmt.Println("Sending VersionNegotiationPacket")
|
|
||||||
fullReply := &bytes.Buffer{}
|
|
||||||
responsePublicHeader := quic.PublicHeader{ConnectionID: publicHeader.ConnectionID, PacketNumber: 1, VersionFlag: true}
|
|
||||||
err = responsePublicHeader.WritePublicHeader(fullReply)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
// TODO: Send all versions
|
|
||||||
utils.WriteUint32(fullReply, protocol.VersionNumberToTag(protocol.VersionNumber(32)))
|
|
||||||
_, err = conn.WriteToUDP(fullReply.Bytes(), remoteAddr)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
session, ok := sessions[publicHeader.ConnectionID]
|
|
||||||
if !ok {
|
|
||||||
session = quic.NewSession(conn, publicHeader.VersionNumber, publicHeader.ConnectionID, serverConfig, handleStream)
|
|
||||||
sessions[publicHeader.ConnectionID] = session
|
|
||||||
}
|
|
||||||
err = session.HandlePacket(remoteAddr, data[0:n-r.Len()], publicHeader, r)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Error handling packet: %s\n", err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleStream(frame *quic.StreamFrame) []quic.Frame {
|
func handleStream(frame *quic.StreamFrame) []quic.Frame {
|
||||||
|
|||||||
108
server.go
Normal file
108
server.go
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
package quic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/lucas-clemente/quic-go/crypto"
|
||||||
|
"github.com/lucas-clemente/quic-go/handshake"
|
||||||
|
"github.com/lucas-clemente/quic-go/protocol"
|
||||||
|
"github.com/lucas-clemente/quic-go/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
var supportedVersions = map[protocol.VersionNumber]bool{
|
||||||
|
30: true,
|
||||||
|
32: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Server of QUIC
|
||||||
|
type Server struct {
|
||||||
|
keyData *crypto.KeyData
|
||||||
|
scfg *handshake.ServerConfig
|
||||||
|
|
||||||
|
sessions map[protocol.ConnectionID]*Session
|
||||||
|
|
||||||
|
streamCallback StreamCallback
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewServer makes a new server
|
||||||
|
func NewServer(certPath, keyPath string, cb StreamCallback) (*Server, error) {
|
||||||
|
path := os.Getenv("GOPATH") + "/src/github.com/lucas-clemente/quic-go/example/"
|
||||||
|
keyData, err := crypto.LoadKeyData(path+"cert.der", path+"key.der")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
scfg := handshake.NewServerConfig(crypto.NewCurve25519KEX(), keyData)
|
||||||
|
|
||||||
|
return &Server{
|
||||||
|
keyData: keyData,
|
||||||
|
scfg: scfg,
|
||||||
|
streamCallback: cb,
|
||||||
|
sessions: map[protocol.ConnectionID]*Session{},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListenAndServe listens and serves a connection
|
||||||
|
func (s *Server) ListenAndServe(address string) error {
|
||||||
|
addr, err := net.ResolveUDPAddr("udp", address)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
conn, err := net.ListenUDP("udp", addr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
data := make([]byte, 1400)
|
||||||
|
n, remoteAddr, err := conn.ReadFromUDP(data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
data = data[:n]
|
||||||
|
r := bytes.NewReader(data)
|
||||||
|
|
||||||
|
fmt.Printf("Received %d bytes from %v\n", n, remoteAddr)
|
||||||
|
|
||||||
|
publicHeader, err := ParsePublicHeader(r)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Could not parse public header")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fmt.Printf("Got packet # %d\n", publicHeader.PacketNumber)
|
||||||
|
|
||||||
|
// Send Version Negotiation Packet if the client is speaking a different protocol version
|
||||||
|
if publicHeader.VersionFlag && !supportedVersions[publicHeader.VersionNumber] {
|
||||||
|
fmt.Println("Sending VersionNegotiationPacket")
|
||||||
|
fullReply := &bytes.Buffer{}
|
||||||
|
responsePublicHeader := PublicHeader{ConnectionID: publicHeader.ConnectionID, PacketNumber: 1, VersionFlag: true}
|
||||||
|
err = responsePublicHeader.WritePublicHeader(fullReply)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Could not write public header")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// TODO: Send all versions
|
||||||
|
utils.WriteUint32(fullReply, protocol.VersionNumberToTag(protocol.VersionNumber(32)))
|
||||||
|
_, err = conn.WriteToUDP(fullReply.Bytes(), remoteAddr)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Could not write to UDP")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
session, ok := s.sessions[publicHeader.ConnectionID]
|
||||||
|
if !ok {
|
||||||
|
session = NewSession(conn, publicHeader.VersionNumber, publicHeader.ConnectionID, s.scfg, s.streamCallback)
|
||||||
|
s.sessions[publicHeader.ConnectionID] = session
|
||||||
|
}
|
||||||
|
err = session.HandlePacket(remoteAddr, data[0:n-r.Len()], publicHeader, r)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error handling packet: %s\n", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user