Permalink
Browse files

Merge branch 'master' of github.com:manpat/yojimbo

  • Loading branch information...
manpat committed Aug 18, 2017
2 parents 50b781d + e02219c commit a35a3e90fefa26f5650a36179a1b62e6bdd90678
Showing with 367 additions and 103 deletions.
  1. +6 −2 client.cpp
  2. +2 −2 client_server.cpp
  3. +3 −1 docker/copyFiles.bat
  4. +0 −59 docker/matcher/matcher.go
  5. +3 −2 loopback.cpp
  6. +2 −3 {docker → }/matcher/Dockerfile
  7. +210 −0 matcher/matcher.go
  8. +1 −1 netcode.io
  9. +6 −6 premake5.lua
  10. +1 −1 reliable.io
  11. +9 −2 secure_client.cpp
  12. +6 −2 secure_server.cpp
  13. +6 −2 server.cpp
  14. +2 −2 shared.h
  15. +2 −2 soak.cpp
  16. +2 −2 test.cpp
  17. +53 −8 yojimbo.cpp
  18. +53 −6 yojimbo.h
View
@@ -1,7 +1,7 @@
/*
Insecure Client.
Yojimbo Client Example (insecure)
Copyright © 2016, The Network Protocol Company, Inc.
Copyright © 2016 - 2017, The Network Protocol Company, Inc.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
@@ -72,6 +72,10 @@ int ClientMain( int argc, char * argv[] )
client.InsecureConnect( privateKey, clientId, serverAddress );
char addressString[256];
client.GetAddress().ToString( addressString, sizeof( addressString ) );
printf( "client address is %s\n", addressString );
const double deltaTime = 0.01f;
signal( SIGINT, interrupt_handler );
View
@@ -1,7 +1,7 @@
/*
Client/Server Testbed
Yojimbo Client/Server Example.
Copyright © 2016, The Network Protocol Company, Inc.
Copyright © 2016 - 2017, The Network Protocol Company, Inc.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
View
@@ -4,7 +4,9 @@ mkdir yojimbo
mkdir yojimbo\tests
copy ..\*.h yojimbo
copy ..\*.cpp yojimbo
copy ..\premake5.lua libyojimbo
copy ..\premake5.lua yojimbo
robocopy /MIR /DCOPY:T ..\tlsf yojimbo\tlsf
robocopy /MIR /DCOPY:T ..\netcode.io yojimbo\netcode.io
robocopy /MIR /DCOPY:T ..\reliable.io yojimbo\reliable.io
REM because robocopy sometimes sets non-zero error codes on successful operation. what the actual fuck windows
cmd /c "exit /b 0"
View

This file was deleted.

Oops, something went wrong.
View
@@ -1,7 +1,7 @@
/*
Client/Server Testbed
Yojimbo Loopback Example.
Copyright © 2016, The Network Protocol Company, Inc.
Copyright © 2016 - 2017, The Network Protocol Company, Inc.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
@@ -66,6 +66,7 @@ class LoopbackAdapter : public Adapter
void ServerSendLoopbackPacket( int clientIndex, const uint8_t * packetData, int packetBytes, uint64_t packetSequence )
{
(void) clientIndex;
yojimbo_assert( client );
yojimbo_assert( clientIndex == 0 );
client->ProcessLoopbackPacket( packetData, packetBytes, packetSequence );
@@ -12,9 +12,8 @@ RUN wget https://github.com/jedisct1/libsodium/releases/download/1.0.10/libsodiu
rm -rf libsodium* && \
ldconfig
RUN go get github.com/gorilla/mux
RUN go get github.com/gorilla/context
RUN go get github.com/networkprotocol/netcode.io/go/netcode
RUN go get -u github.com/gorilla/mux
RUN go get -u github.com/gorilla/context
RUN cd /go/bin && \
openssl genrsa -out server.key 4096 && \
View
@@ -0,0 +1,210 @@
package main
// #cgo pkg-config: libsodium
// #include <sodium.h>
import "C"
import (
"io"
"fmt"
"log"
"net"
"time"
"unsafe"
"strconv"
"net/http"
"sync/atomic"
"encoding/base64"
"encoding/binary"
"github.com/gorilla/mux"
"github.com/gorilla/context"
)
const Port = 8080
const ServerAddress = "127.0.0.1"
const ServerPort = 40000
const KeyBytes = 32
const AuthBytes = 16
const ConnectTokenExpiry = 45
const ConnectTokenBytes = 2048
const ConnectTokenPrivateBytes = 1024
const UserDataBytes = 256
const TimeoutSeconds = 5
const VersionInfo = "NETCODE 1.01\x00"
var MatchNonce = uint64(0)
var PrivateKey = [] byte { 0x60, 0x6a, 0xbe, 0x6e, 0xc9, 0x19, 0x10, 0xea,
0x9a, 0x65, 0x62, 0xf6, 0x6f, 0x2b, 0x30, 0xe4,
0x43, 0x71, 0xd6, 0x2c, 0xd1, 0x99, 0x27, 0x26,
0x6b, 0x3c, 0x60, 0xf4, 0xb7, 0x15, 0xab, 0xa1 };
const (
ADDRESS_NONE = 0
ADDRESS_IPV4 = 1
ADDRESS_IPV6 = 2
)
func WriteAddresses( buffer []byte, addresses []net.UDPAddr ) (int) {
binary.LittleEndian.PutUint32(buffer[0:], (uint32)(len(addresses)))
offset := 4
for _, addr := range addresses {
ipv4 := addr.IP.To4()
port := addr.Port
if ipv4 != nil {
buffer[offset] = ADDRESS_IPV4
buffer[offset+1] = ipv4[0]
buffer[offset+2] = ipv4[1]
buffer[offset+3] = ipv4[2]
buffer[offset+4] = ipv4[3]
buffer[offset+5] = (byte) (port&0xFF)
buffer[offset+6] = (byte) (port>>8)
} else {
buffer[offset] = ADDRESS_IPV6
copy( buffer[offset+1:], addr.IP )
buffer[offset+17] = (byte) (port&0xFF)
buffer[offset+18] = (byte) (port>>8)
}
offset += 19
}
return offset
}
type ConnectTokenPrivate struct {
ClientId uint64
TimeoutSeconds int32
ServerAddresses []net.UDPAddr
ClientToServerKey [KeyBytes]byte
ServerToClientKey [KeyBytes]byte
UserData [UserDataBytes]byte
}
func NewConnectTokenPrivate(clientId uint64, serverAddresses []net.UDPAddr, timeoutSeconds int32, userData []byte, clientToServerKey []byte, serverToClientKey []byte ) (*ConnectTokenPrivate) {
connectTokenPrivate := &ConnectTokenPrivate{}
connectTokenPrivate.ClientId = clientId
connectTokenPrivate.TimeoutSeconds = timeoutSeconds
connectTokenPrivate.ServerAddresses = serverAddresses
copy( connectTokenPrivate.UserData[:], userData[0:UserDataBytes] )
copy( connectTokenPrivate.ClientToServerKey[:], clientToServerKey[0:KeyBytes] )
copy( connectTokenPrivate.ServerToClientKey[:], serverToClientKey[0:KeyBytes] )
return connectTokenPrivate
}
func (token *ConnectTokenPrivate) Write( buffer []byte ) {
binary.LittleEndian.PutUint64(buffer[0:], token.ClientId)
binary.LittleEndian.PutUint32(buffer[8:], (uint32)(token.TimeoutSeconds))
addressBytes := WriteAddresses( buffer[12:], token.ServerAddresses )
copy( buffer[12+addressBytes:], token.ClientToServerKey[:] )
copy( buffer[12+addressBytes+KeyBytes:], token.ServerToClientKey[:] )
copy( buffer[12+addressBytes+KeyBytes*2:], token.UserData[:] )
}
type ConnectToken struct {
ProtocolId uint64
CreateTimestamp uint64
ExpireTimestamp uint64
Sequence uint64
PrivateData *ConnectTokenPrivate
TimeoutSeconds int32
ServerAddresses []net.UDPAddr
ClientToServerKey [KeyBytes]byte
ServerToClientKey [KeyBytes]byte
PrivateKey [KeyBytes]byte
}
func NewConnectToken(clientId uint64, serverAddresses []net.UDPAddr, protocolId uint64, expireSeconds uint64, timeoutSeconds int32, sequence uint64, userData []byte, privateKey []byte) (*ConnectToken) {
connectToken := &ConnectToken{}
connectToken.ProtocolId = protocolId
connectToken.CreateTimestamp = uint64(time.Now().Unix())
if expireSeconds >= 0 {
connectToken.ExpireTimestamp = connectToken.CreateTimestamp + expireSeconds
} else {
connectToken.ExpireTimestamp = 0xFFFFFFFFFFFFFFFF
}
connectToken.Sequence = sequence
connectToken.TimeoutSeconds = timeoutSeconds
connectToken.ServerAddresses = serverAddresses
C.randombytes_buf(unsafe.Pointer(&connectToken.ClientToServerKey[0]), KeyBytes)
C.randombytes_buf(unsafe.Pointer(&connectToken.ServerToClientKey[0]), KeyBytes)
copy( connectToken.PrivateKey[:], privateKey[:] )
connectToken.PrivateData = NewConnectTokenPrivate( clientId, serverAddresses, timeoutSeconds, userData, connectToken.ClientToServerKey[:], connectToken.ServerToClientKey[:] )
return connectToken
}
func EncryptAEAD(message []byte, additional []byte, nonce uint64, key []byte) bool {
nonceData := make([]byte, 12)
binary.LittleEndian.PutUint64(nonceData[4:], nonce)
encryptedLengthLongLong := (C.ulonglong(len(message)))
return C.crypto_aead_chacha20poly1305_ietf_encrypt(
(*C.uchar)(&message[0]),
&encryptedLengthLongLong,
(*C.uchar)(&message[0]),
(C.ulonglong)(len(message)),
(*C.uchar)(&additional[0]),
(C.ulonglong)(len(additional)),
(*C.uchar)(nil),
(*C.uchar)(&nonceData[0]),
(*C.uchar)(&key[0])) == 0
}
func (token *ConnectToken) Write( buffer []byte ) (bool) {
copy( buffer, VersionInfo )
binary.LittleEndian.PutUint64(buffer[13:], token.ProtocolId)
binary.LittleEndian.PutUint64(buffer[21:], token.CreateTimestamp)
binary.LittleEndian.PutUint64(buffer[29:], token.ExpireTimestamp)
binary.LittleEndian.PutUint64(buffer[37:], token.Sequence)
token.PrivateData.Write( buffer[45:] )
additional := make([]byte, 13+8+8)
copy( additional, VersionInfo[0:13] )
binary.LittleEndian.PutUint64(additional[13:], token.ProtocolId)
binary.LittleEndian.PutUint64(additional[21:], token.ExpireTimestamp)
if !EncryptAEAD( buffer[45:45+ConnectTokenPrivateBytes-AuthBytes], additional[:], token.Sequence, token.PrivateKey[:] ) {
return false
}
binary.LittleEndian.PutUint32(buffer[ConnectTokenPrivateBytes+45:], (uint32)(token.TimeoutSeconds))
offset := WriteAddresses( buffer[1024+49:], token.ServerAddresses )
copy( buffer[1024+49+offset:], token.ClientToServerKey[:] )
copy( buffer[1024+49+offset+KeyBytes:], token.ServerToClientKey[:] )
return true
}
func GenerateConnectToken(clientId uint64, serverAddresses []net.UDPAddr, protocolId uint64, expireSeconds uint64, timeoutSeconds int32, sequence uint64, userData []byte, privateKey []byte) ([]byte) {
connectToken := NewConnectToken( clientId, serverAddresses, protocolId, expireSeconds, timeoutSeconds, sequence, userData, privateKey )
if connectToken == nil {
return nil
}
buffer := make([]byte, ConnectTokenBytes )
if !connectToken.Write( buffer ) {
return nil
}
return buffer
}
func MatchHandler( w http.ResponseWriter, r * http.Request ) {
vars := mux.Vars( r )
atomic.AddUint64( &MatchNonce, 1 )
clientId, _ := strconv.ParseUint( vars["clientId"], 10, 64 )
protocolId, _ := strconv.ParseUint( vars["protocolId"], 10, 64 )
serverAddresses := make( []net.UDPAddr, 1 )
serverAddresses[0] = net.UDPAddr{ IP: net.ParseIP( ServerAddress ), Port: ServerPort }
userData := make( []byte, UserDataBytes )
connectToken := GenerateConnectToken( clientId, serverAddresses, protocolId, ConnectTokenExpiry, TimeoutSeconds, MatchNonce, userData, PrivateKey )
if connectToken == nil {
log.Printf( "error: failed to generate connect token" )
return
}
connectTokenBase64 := base64.StdEncoding.EncodeToString( connectToken )
w.Header().Set( "Content-Type", "application/text" )
if _, err := io.WriteString( w, connectTokenBase64 ); err != nil {
log.Printf( "error: failed to write string response" )
return
}
fmt.Printf( "matched client %.16x to %s:%d\n", clientId, ServerAddress, ServerPort )
}
func main() {
fmt.Printf( "\nstarted matchmaker on port %d\n\n", Port )
router := mux.NewRouter()
router.HandleFunc( "/match/{protocolId:[0-9]+}/{clientId:[0-9]+}", MatchHandler )
log.Fatal( http.ListenAndServeTLS( ":" + strconv.Itoa(Port), "server.pem", "server.key", context.ClearHandler( router ) ) )
}
Submodule netcode.io updated 142 files
View
@@ -9,10 +9,10 @@ solution "Yojimbo"
platforms { "x64" }
configurations { "Debug", "Release" }
if os.is "windows" then
includedirs { ".", "./windows", "netcode.io/c", "reliable.io" }
includedirs { ".", "./windows", "netcode.io", "reliable.io" }
libdirs { "./windows" }
else
includedirs { ".", "/usr/local/include", "netcode.io/c", "reliable.io" }
includedirs { ".", "/usr/local/include", "netcode.io", "reliable.io" }
targetdir "bin/"
end
rtti "Off"
@@ -31,7 +31,7 @@ project "test"
project "yojimbo"
kind "StaticLib"
defines { "NETCODE_ENABLE_TESTS=1", "RELIABLE_ENABLE_TESTS=1" }
files { "yojimbo.h", "yojimbo.cpp", "tlsf/tlsf.h", "tlsf/tlsf.c", "netcode.io/c/netcode.c", "netcode.io/c/netcode.h", "reliable.io/reliable.c", "reliable.io/reliable.h" }
files { "yojimbo.h", "yojimbo.cpp", "tlsf/tlsf.h", "tlsf/tlsf.c", "netcode.io/netcode.c", "netcode.io/netcode.h", "reliable.io/reliable.c", "reliable.io/reliable.h" }
project "client"
files { "client.cpp", "shared.h" }
@@ -177,7 +177,7 @@ if not os.is "windows" then
description = "Build and run the matchmaker web service inside a docker container",
execute = function ()
os.execute "docker run --rm --privileged alpine hwclock -s" -- workaround for clock getting out of sync on macos. see https://docs.docker.com/docker-for-mac/troubleshoot/#issues
os.execute "cd docker/matcher && docker build -t networkprotocol:yojimbo-matcher . && docker run -ti -p 8080:8080 networkprotocol:yojimbo-matcher"
os.execute "cd matcher && docker build -t networkprotocol:yojimbo-matcher . && docker run -ti -p 8080:8080 networkprotocol:yojimbo-matcher"
end
}
@@ -251,7 +251,7 @@ if not os.is "windows" then
trigger = "loc",
description = "Count lines of code",
execute = function ()
os.execute "wc -l *.h *.cpp netcode.io/c/*.c netcode.io/c/*.h reliable.io/*.c reliable.io/*.h"
os.execute "wc -l *.h *.cpp netcode.io/*.c netcode.io/*.h reliable.io/*.c reliable.io/*.h"
end
}
@@ -342,7 +342,7 @@ else
trigger = "matcher",
description = "Build and run the matchmaker web service inside a docker container",
execute = function ()
os.execute "cd docker\\matcher && docker build -t networkprotocol:yojimbo-matcher . && docker run -ti -p 8080:8080 networkprotocol:yojimbo-matcher"
os.execute "cd matcher && docker build -t networkprotocol:yojimbo-matcher . && docker run -ti -p 8080:8080 networkprotocol:yojimbo-matcher"
end
}
Submodule reliable.io updated 2 files
+0 −25 TODO
+3 −3 reliable.c
Oops, something went wrong.

0 comments on commit a35a3e9

Please sign in to comment.