|
|
@ -10,6 +10,7 @@ import (
|
|
|
|
"reflect"
|
|
|
|
"reflect"
|
|
|
|
"sync"
|
|
|
|
"sync"
|
|
|
|
"sync/atomic"
|
|
|
|
"sync/atomic"
|
|
|
|
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
const (
|
|
|
@ -19,6 +20,7 @@ const (
|
|
|
|
|
|
|
|
|
|
|
|
type ServerSession struct {
|
|
|
|
type ServerSession struct {
|
|
|
|
Session
|
|
|
|
Session
|
|
|
|
|
|
|
|
LastSeen time.Time
|
|
|
|
IncomingPackets chan[]byte
|
|
|
|
IncomingPackets chan[]byte
|
|
|
|
OutgoingPackets chan *Packet
|
|
|
|
OutgoingPackets chan *Packet
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -160,6 +162,7 @@ func(server *Server) listen_udp() {
|
|
|
|
server.sessions_lock.Lock()
|
|
|
|
server.sessions_lock.Lock()
|
|
|
|
server.sessions[session.ID] = &ServerSession{
|
|
|
|
server.sessions[session.ID] = &ServerSession{
|
|
|
|
Session: session,
|
|
|
|
Session: session,
|
|
|
|
|
|
|
|
LastSeen: time.Now(),
|
|
|
|
IncomingPackets: make(chan[]byte, SESSION_BUFFER_SIZE),
|
|
|
|
IncomingPackets: make(chan[]byte, SESSION_BUFFER_SIZE),
|
|
|
|
OutgoingPackets: make(chan *Packet, SESSION_BUFFER_SIZE),
|
|
|
|
OutgoingPackets: make(chan *Packet, SESSION_BUFFER_SIZE),
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -264,6 +267,7 @@ func(server *Server) listen_udp() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
session.remote = client_addr
|
|
|
|
session.remote = client_addr
|
|
|
|
|
|
|
|
session.LastSeen = time.Now()
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: Make a better server hello
|
|
|
|
// TODO: Make a better server hello
|
|
|
|
server_hello, err := NewSessionData(&session.Session, []byte("hello"))
|
|
|
|
server_hello, err := NewSessionData(&session.Session, []byte("hello"))
|
|
|
@ -293,11 +297,8 @@ func(server *Server) listen_udp() {
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
close(session.IncomingPackets)
|
|
|
|
|
|
|
|
close(session.OutgoingPackets)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
server.sessions_lock.Lock()
|
|
|
|
server.sessions_lock.Lock()
|
|
|
|
delete(server.sessions, session_id)
|
|
|
|
server.close_session(session)
|
|
|
|
server.sessions_lock.Unlock()
|
|
|
|
server.sessions_lock.Unlock()
|
|
|
|
|
|
|
|
|
|
|
|
server.Log("Session %s closed", session_id)
|
|
|
|
server.Log("Session %s closed", session_id)
|
|
|
@ -310,6 +311,8 @@ func(server *Server) listen_udp() {
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
session.LastSeen = time.Now()
|
|
|
|
|
|
|
|
|
|
|
|
buf_copy := make([]byte, read - COMMAND_LENGTH - ID_LENGTH)
|
|
|
|
buf_copy := make([]byte, read - COMMAND_LENGTH - ID_LENGTH)
|
|
|
|
copy(buf_copy, buf[COMMAND_LENGTH+ID_LENGTH:read])
|
|
|
|
copy(buf_copy, buf[COMMAND_LENGTH+ID_LENGTH:read])
|
|
|
|
|
|
|
|
|
|
|
@ -330,10 +333,12 @@ func(server *Server) listen_udp() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
server.sessions_lock.Lock()
|
|
|
|
server.sessions_lock.Lock()
|
|
|
|
for session_id, session := range(server.sessions) {
|
|
|
|
sessions := make([]*ServerSession, 0, len(server.sessions))
|
|
|
|
close(session.IncomingPackets)
|
|
|
|
for _, session := range(server.sessions) {
|
|
|
|
close(session.OutgoingPackets)
|
|
|
|
sessions = append(sessions, session)
|
|
|
|
delete(server.sessions, session_id)
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, session := range(sessions) {
|
|
|
|
|
|
|
|
server.close_session(session)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
server.sessions_lock.Unlock()
|
|
|
|
server.sessions_lock.Unlock()
|
|
|
|
|
|
|
|
|
|
|
@ -342,7 +347,7 @@ func(server *Server) listen_udp() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func(server *Server) send_sessions() {
|
|
|
|
func(server *Server) send_sessions() {
|
|
|
|
for true {
|
|
|
|
for server.active.Load() {
|
|
|
|
packets := <- server.send_packets
|
|
|
|
packets := <- server.send_packets
|
|
|
|
if packets == nil {
|
|
|
|
if packets == nil {
|
|
|
|
break
|
|
|
|
break
|
|
|
@ -359,6 +364,40 @@ func(server *Server) send_sessions() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func(server *Server) close_session(session *ServerSession) {
|
|
|
|
|
|
|
|
close(session.IncomingPackets)
|
|
|
|
|
|
|
|
close(session.OutgoingPackets)
|
|
|
|
|
|
|
|
delete(server.sessions, session.ID)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const SESSION_TIMEOUT = time.Minute * 5
|
|
|
|
|
|
|
|
const SESSION_TIMEOUT_CHECK = time.Minute
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func(server *Server) cleanup_sessions() {
|
|
|
|
|
|
|
|
for server.active.Load() {
|
|
|
|
|
|
|
|
select {
|
|
|
|
|
|
|
|
case <-time.After(SESSION_TIMEOUT_CHECK):
|
|
|
|
|
|
|
|
server.Log("Running stale session check")
|
|
|
|
|
|
|
|
server.sessions_lock.Lock()
|
|
|
|
|
|
|
|
now := time.Now()
|
|
|
|
|
|
|
|
stale_sessions := make([]*ServerSession, 0, len(server.sessions))
|
|
|
|
|
|
|
|
for _, session := range(server.sessions) {
|
|
|
|
|
|
|
|
if now.Sub(session.LastSeen) >= SESSION_TIMEOUT {
|
|
|
|
|
|
|
|
server.Log("Closing stale session %s for %s", session.ID, session.Peer)
|
|
|
|
|
|
|
|
stale_sessions = append(stale_sessions, session)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for _, session := range(stale_sessions) {
|
|
|
|
|
|
|
|
server.close_session(session)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
server.sessions_lock.Unlock()
|
|
|
|
|
|
|
|
// TODO: add a way for this to be shutdown instantly on server shutdown
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func(server *Server) Start(listen string) error {
|
|
|
|
func(server *Server) Start(listen string) error {
|
|
|
|
was_inactive := server.active.CompareAndSwap(false, true)
|
|
|
|
was_inactive := server.active.CompareAndSwap(false, true)
|
|
|
|
if was_inactive == false {
|
|
|
|
if was_inactive == false {
|
|
|
@ -379,6 +418,7 @@ func(server *Server) Start(listen string) error {
|
|
|
|
|
|
|
|
|
|
|
|
go server.listen_udp()
|
|
|
|
go server.listen_udp()
|
|
|
|
go server.send_sessions()
|
|
|
|
go server.send_sessions()
|
|
|
|
|
|
|
|
go server.cleanup_sessions()
|
|
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|