move stuff from example server to new Session and SessionConfig classes

This commit is contained in:
Lucas Clemente 2016-04-14 17:56:19 +02:00
parent 49ccd0bb01
commit 09879ed4f7
5 changed files with 225 additions and 122 deletions

View file

@ -12,7 +12,7 @@ import (
)
const (
// QuicVersion32Bytes is the QUIC protocol version
// QuicVersionNumber32 is the QUIC protocol version
QuicVersionNumber32 = 32
)
@ -25,6 +25,11 @@ func main() {
panic(err)
}
serverConfig := quic.NewServerConfig(crypto.NewCurve25519KEX(), keyData)
// TODO: When should a session be created?
sessions := map[uint64]*quic.Session{}
addr, err := net.ResolveUDPAddr("udp", "localhost:6121")
if err != nil {
panic(err)
@ -35,121 +40,45 @@ func main() {
panic(err)
}
data := make([]byte, 0x10000)
n, remoteAddr, err := conn.ReadFromUDP(data)
if err != nil {
panic(err)
}
data = data[:n]
r := bytes.NewReader(data)
fmt.Printf("Remote addr: %v\n", remoteAddr)
publicHeader, err := quic.ParsePublicHeader(r)
if err != nil {
panic(err)
}
// send Version Negotiation Packet if the client is speaking a different protocol version
if publicHeader.VersionFlag && publicHeader.QuicVersion != QuicVersion32 {
fmt.Println("Sending VersionNegotiationPacket")
fullReply := &bytes.Buffer{}
responsePublicHeader := quic.PublicHeader{ConnectionID: publicHeader.ConnectionID, PacketNumber: 1, VersionFlag: true}
err = responsePublicHeader.WritePublicHeader(fullReply)
for {
data := make([]byte, 0x10000)
n, remoteAddr, err := conn.ReadFromUDP(data)
if err != nil {
panic(err)
}
utils.WriteUint32BigEndian(fullReply, QuicVersion32)
conn.WriteToUDP(fullReply.Bytes(), remoteAddr)
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("%#v\n", publicHeader)
// Send Version Negotiation Packet if the client is speaking a different protocol version
if publicHeader.VersionFlag && publicHeader.QuicVersion != QuicVersion32 {
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)
}
utils.WriteUint32BigEndian(fullReply, QuicVersion32)
_, err := conn.WriteToUDP(fullReply.Bytes(), remoteAddr)
if err != nil {
panic(err)
}
continue
}
session, ok := sessions[publicHeader.ConnectionID]
if !ok {
session = quic.NewSession(conn, publicHeader.ConnectionID, serverConfig)
sessions[publicHeader.ConnectionID] = session
}
session.HandlePacket(remoteAddr, data[0:n-r.Len()], publicHeader, r)
}
nullAEAD := &crypto.NullAEAD{}
r, err = nullAEAD.Open(0, data[0:int(r.Size())-r.Len()], r)
if err != nil {
panic(err)
}
privateFlag, err := r.ReadByte()
if err != nil {
panic(err)
}
var entropyAcc quic.EntropyAccumulator
entropyAcc.Add(publicHeader.PacketNumber, privateFlag&0x01 > 0)
frame, err := quic.ParseStreamFrame(r)
if err != nil {
panic(err)
}
messageTag, cryptoData, err := quic.ParseCryptoMessage(frame.Data)
if err != nil {
panic(err)
}
if messageTag != quic.TagCHLO {
panic("expected CHLO")
}
fmt.Printf("Talking to: %q\n", cryptoData[quic.TagUAID])
kex := crypto.NewCurve25519KEX()
serverConfig := &bytes.Buffer{}
quic.WriteCryptoMessage(serverConfig, quic.TagSCFG, map[quic.Tag][]byte{
quic.TagSCID: []byte{0xC5, 0x1C, 0x73, 0x6B, 0x8F, 0x48, 0x49, 0xAE, 0xB3, 0x00, 0xA2, 0xD4, 0x4B, 0xA0, 0xCF, 0xDF},
quic.TagKEXS: []byte("C255"),
quic.TagAEAD: []byte("AESG"),
quic.TagPUBS: append([]byte{0x20, 0x00, 0x00}, kex.PublicKey()...),
quic.TagOBIT: []byte{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7},
quic.TagEXPY: []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
quic.TagVER: []byte("Q032"),
})
proof, err := keyData.SignServerProof(frame.Data, serverConfig.Bytes())
if err != nil {
panic(err)
}
serverReply := &bytes.Buffer{}
quic.WriteCryptoMessage(serverReply, quic.TagREJ, map[quic.Tag][]byte{
quic.TagSCFG: serverConfig.Bytes(),
quic.TagCERT: keyData.GetCERTdata(),
quic.TagPROF: proof,
})
replyFrame := &bytes.Buffer{}
replyFrame.WriteByte(0) // Private header
quic.WriteAckFrame(replyFrame, &quic.AckFrame{
Entropy: entropyAcc.Get(),
LargestObserved: 1,
})
quic.WriteStreamFrame(replyFrame, &quic.StreamFrame{
StreamID: 1,
Data: serverReply.Bytes(),
})
fullReply := &bytes.Buffer{}
responsePublicHeader := quic.PublicHeader{ConnectionID: publicHeader.ConnectionID, PacketNumber: 1}
fmt.Println(responsePublicHeader)
err = responsePublicHeader.WritePublicHeader(fullReply)
if err != nil {
panic(err)
}
nullAEAD.Seal(0, fullReply, fullReply.Bytes(), replyFrame.Bytes())
conn.WriteToUDP(fullReply.Bytes(), remoteAddr)
n, _, err = conn.ReadFromUDP(data)
if err != nil {
panic(err)
}
data = data[:n]
r = bytes.NewReader(data)
publicHeader, err = quic.ParsePublicHeader(r)
if err != nil {
panic(err)
}
fmt.Printf("%#v\n", publicHeader)
}