multiserver/init.go

820 lines
18 KiB
Go
Raw Normal View History

2021-01-24 05:00:26 -08:00
package main
import (
2021-03-29 09:57:30 -07:00
"bytes"
"crypto/subtle"
"encoding/binary"
2021-03-02 08:47:07 -08:00
"errors"
2021-03-29 09:57:30 -07:00
"io"
"log"
2021-01-20 12:44:35 -08:00
"net"
"strings"
"time"
"github.com/HimbeerserverDE/srp"
"github.com/anon55555/mt/rudp"
)
// Init completes the initialisation of a connection to a server or client c2
2021-03-29 09:57:30 -07:00
func Init(c, c2 *Conn, ignMedia, noAccessDenied bool, fin chan *Conn) {
defer close(fin)
2021-03-29 09:57:30 -07:00
if c2.IsSrv() {
// We're trying to connect to a server
// INIT
2021-03-29 09:57:30 -07:00
data := make([]byte, 11+len(c.Username()))
data[0] = uint8(0x00)
2021-01-19 11:37:35 -08:00
data[1] = uint8(ToServerInit)
data[2] = uint8(0x1c)
binary.BigEndian.PutUint16(data[3:5], uint16(0x0000))
2021-03-13 08:15:07 -08:00
binary.BigEndian.PutUint16(data[5:7], uint16(ProtoMin))
binary.BigEndian.PutUint16(data[7:9], uint16(ProtoLatest))
2021-03-29 09:57:30 -07:00
binary.BigEndian.PutUint16(data[9:11], uint16(len(c.Username())))
copy(data[11:], []byte(c.Username()))
time.Sleep(250 * time.Millisecond)
2021-03-29 09:57:30 -07:00
if _, err := c2.Send(rudp.Pkt{
Reader: bytes.NewReader(data),
PktInfo: rudp.PktInfo{
Channel: 1,
Unrel: true,
},
}); err != nil {
log.Print(err)
}
for {
2021-03-29 09:57:30 -07:00
pkt, err := c2.Recv()
if err != nil {
2021-03-02 08:47:07 -08:00
if errors.Is(err, net.ErrClosed) {
2021-03-29 09:57:30 -07:00
if err = c2.WhyClosed(); err != nil {
log.Print(c2.Addr().String(), " disconnected with error: ", err)
} else {
log.Print(c2.Addr().String(), " disconnected")
}
return
}
log.Print(err)
continue
}
2021-03-29 09:57:30 -07:00
r := ByteReader(pkt)
cmdBytes := make([]byte, 2)
r.Read(cmdBytes)
switch cmd := binary.BigEndian.Uint16(cmdBytes); cmd {
2021-01-14 10:06:40 -08:00
case ToClientHello:
2021-03-29 09:57:30 -07:00
r.Seek(5, io.SeekStart)
protoVerBytes := make([]byte, 2)
r.Read(protoVerBytes)
c2.protoVer = binary.BigEndian.Uint16(protoVerBytes)
r.Seek(10, io.SeekStart)
2021-03-13 08:15:07 -08:00
2021-03-29 09:57:30 -07:00
authMechByte, _ := r.ReadByte()
if authMechByte&AuthMechSRP > 0 {
// Compute and send SRP_BYTES_A
2021-03-29 09:57:30 -07:00
_, _, err := srp.NewClient([]byte(strings.ToLower(c.Username())), passPhrase)
if err != nil {
log.Print(err)
continue
}
A, a, err := srp.InitiateHandshake()
if err != nil {
log.Print(err)
continue
}
2021-03-29 09:57:30 -07:00
c.srp_A = A
c.srp_a = a
2021-03-29 09:57:30 -07:00
data := make([]byte, 5+len(c.srp_A))
data[0] = uint8(0x00)
2021-01-14 10:06:40 -08:00
data[1] = uint8(ToServerSrpBytesA)
2021-03-29 09:57:30 -07:00
binary.BigEndian.PutUint16(data[2:4], uint16(len(c.srp_A)))
copy(data[4:4+len(c.srp_A)], c.srp_A)
data[4+len(c.srp_A)] = uint8(1)
ack, err := c2.Send(rudp.Pkt{
Reader: bytes.NewReader(data),
PktInfo: rudp.PktInfo{
Channel: 1,
},
})
if err != nil {
log.Print(err)
continue
}
<-ack
} else {
// Compute and send s and v
2021-03-29 09:57:30 -07:00
s, v, err := srp.NewClient([]byte(strings.ToLower(c.Username())), passPhrase)
if err != nil {
log.Print(err)
continue
}
data := make([]byte, 7+len(s)+len(v))
data[0] = uint8(0x00)
2021-01-14 10:06:40 -08:00
data[1] = uint8(ToServerFirstSrp)
binary.BigEndian.PutUint16(data[2:4], uint16(len(s)))
copy(data[4:4+len(s)], s)
2021-01-11 13:05:51 -08:00
binary.BigEndian.PutUint16(data[4+len(s):6+len(s)], uint16(len(v)))
copy(data[6+len(s):6+len(s)+len(v)], v)
data[6+len(s)+len(v)] = uint8(0)
2021-03-29 09:57:30 -07:00
ack, err := c2.Send(rudp.Pkt{
Reader: bytes.NewReader(data),
PktInfo: rudp.PktInfo{
Channel: 1,
},
})
if err != nil {
log.Print(err)
continue
}
<-ack
}
2021-01-14 10:06:40 -08:00
case ToClientSrpBytesSB:
// Compute and send SRP_BYTES_M
2021-03-29 09:57:30 -07:00
lenSBytes := make([]byte, 2)
r.Read(lenSBytes)
lenS := binary.BigEndian.Uint16(lenSBytes)
2021-03-29 09:57:30 -07:00
s := make([]byte, lenS)
r.Read(s)
r.Seek(2, io.SeekCurrent)
B := make([]byte, r.Len())
r.Read(B)
K, err := srp.CompleteHandshake(c.srp_A, c.srp_a, []byte(strings.ToLower(c.Username())), passPhrase, s, B)
if err != nil {
log.Print(err)
continue
}
2021-03-29 09:57:30 -07:00
c.srp_K = K
2021-03-31 10:27:50 -07:00
M := srp.ClientProof([]byte(c.Username()), s, c.srp_A, B, c.srp_K)
data := make([]byte, 4+len(M))
data[0] = uint8(0x00)
2021-01-14 10:06:40 -08:00
data[1] = uint8(ToServerSrpBytesM)
binary.BigEndian.PutUint16(data[2:4], uint16(len(M)))
copy(data[4:], M)
2021-03-29 09:57:30 -07:00
ack, err := c2.Send(rudp.Pkt{
Reader: bytes.NewReader(data),
PktInfo: rudp.PktInfo{
Channel: 1,
},
})
if err != nil {
log.Print(err)
continue
}
<-ack
2021-01-14 10:06:40 -08:00
case ToClientAccessDenied:
// Auth failed for some reason
2021-03-09 13:23:41 -08:00
servers := ConfKey("servers").(map[interface{}]interface{})
var srv string
for server := range servers {
2021-03-29 09:57:30 -07:00
if ConfKey("servers:"+server.(string)+":address") == c2.Addr().String() {
srv = server.(string)
break
}
}
log.Print("authentication failed for server " + srv)
2021-01-16 10:14:31 -08:00
if noAccessDenied {
return
}
data := []byte{
2021-01-19 11:37:35 -08:00
0, ToClientAccessDenied,
AccessDeniedServerFail, 0, 0, 0, 0,
}
2021-03-29 09:57:30 -07:00
ack, err := c.Send(rudp.Pkt{Reader: bytes.NewReader(data)})
if err != nil {
log.Print(err)
}
<-ack
2021-03-29 09:57:30 -07:00
c.Close()
return
2021-01-14 10:06:40 -08:00
case ToClientAuthAccept:
// Auth succeeded
2021-03-14 05:52:31 -07:00
defer func() {
2021-03-29 09:57:30 -07:00
fin <- c2
2021-03-14 05:52:31 -07:00
}()
2021-03-29 09:57:30 -07:00
ack, err := c2.Send(rudp.Pkt{
Reader: bytes.NewReader([]byte{0, ToServerInit2, 0, 0}),
PktInfo: rudp.PktInfo{
Channel: 1,
},
})
if err != nil {
log.Print(err)
continue
}
<-ack
if !ignMedia {
return
}
2021-01-14 10:06:40 -08:00
case ToClientCsmRestrictionFlags:
// Definitions sent (by server)
if !ignMedia {
continue
}
v := []byte("5.4.0-dev-dd5a732fa")
data := make([]byte, 8+len(v))
2021-01-14 10:06:40 -08:00
copy(data[0:6], []byte{uint8(0), uint8(ToServerClientReady), uint8(5), uint8(4), uint8(0), uint8(0)})
binary.BigEndian.PutUint16(data[6:8], uint16(len(v)))
copy(data[8:], v)
2021-03-29 09:57:30 -07:00
_, err := c2.Send(rudp.Pkt{
Reader: bytes.NewReader(data),
PktInfo: rudp.PktInfo{
Channel: 1,
},
})
if err != nil {
log.Print(err)
continue
}
return
}
}
} else {
// We're trying to initialize a client
for {
2021-03-29 09:57:30 -07:00
pkt, err := c2.Recv()
if err != nil {
2021-03-02 08:47:07 -08:00
if errors.Is(err, net.ErrClosed) {
2021-03-29 09:57:30 -07:00
if err = c2.WhyClosed(); err != nil {
log.Print(c2.Addr().String(), " disconnected with error: ", err)
} else {
log.Print(c2.Addr().String(), " disconnected")
}
2021-03-29 09:57:30 -07:00
connectedConnsMu.Lock()
connectedConns--
connectedConnsMu.Unlock()
2021-01-10 13:37:42 -08:00
2021-03-29 09:57:30 -07:00
processLeave(c2)
return
}
log.Print(err)
continue
}
2021-03-29 09:57:30 -07:00
r := ByteReader(pkt)
cmdBytes := make([]byte, 2)
r.Read(cmdBytes)
switch cmd := binary.BigEndian.Uint16(cmdBytes); cmd {
2021-01-14 10:06:40 -08:00
case ToServerInit:
// Process data
2021-03-29 09:57:30 -07:00
r.Seek(11, io.SeekStart)
usernameBytes := make([]byte, r.Len())
r.Read(usernameBytes)
c2.username = string(usernameBytes)
r.Seek(5, io.SeekStart)
2021-03-13 08:15:07 -08:00
// Find protocol version
2021-03-29 09:57:30 -07:00
cliProtoMinBytes := make([]byte, 2)
r.Read(cliProtoMinBytes)
cliProtoMin := binary.BigEndian.Uint16(cliProtoMinBytes)
cliProtoMaxBytes := make([]byte, 2)
r.Read(cliProtoMaxBytes)
cliProtoMax := binary.BigEndian.Uint16(cliProtoMaxBytes)
2021-03-13 08:15:07 -08:00
var protov uint16
if cliProtoMax >= ProtoMin || cliProtoMin <= ProtoLatest {
if cliProtoMax > ProtoLatest {
protov = ProtoLatest
} else {
protov = ProtoLatest
}
}
2021-03-29 09:57:30 -07:00
c2.protoVer = protov
2021-03-13 08:15:07 -08:00
if strict, ok := ConfKey("force_latest_proto").(bool); (ok && strict) && (protov != ProtoLatest) || protov < ProtoMin || protov > ProtoLatest {
2021-03-13 08:15:07 -08:00
data := []byte{
0, ToClientAccessDenied,
AccessDeniedWrongVersion, 0, 0, 0, 0,
}
2021-03-29 09:57:30 -07:00
ack, err := c2.Send(rudp.Pkt{Reader: bytes.NewReader(data)})
2021-03-13 08:15:07 -08:00
if err != nil {
log.Print(err)
}
<-ack
2021-03-29 09:57:30 -07:00
c2.Close()
fin <- c
2021-03-13 08:15:07 -08:00
return
}
// Send HELLO
2021-03-29 09:57:30 -07:00
data := make([]byte, 13+len(c2.Username()))
data[0] = uint8(0x00)
2021-01-14 10:06:40 -08:00
data[1] = uint8(ToClientHello)
data[2] = uint8(0x1c)
binary.BigEndian.PutUint16(data[3:5], uint16(0x0000))
2021-03-13 08:15:07 -08:00
binary.BigEndian.PutUint16(data[5:7], uint16(protov))
2021-02-28 04:12:28 -08:00
// Check if user is banned
2021-03-29 09:57:30 -07:00
banned, bname, err := c2.IsBanned()
2021-02-28 04:12:28 -08:00
if err != nil {
log.Print(err)
continue
}
if banned {
2021-03-29 09:57:30 -07:00
log.Print("Banned user " + bname + " at " + c2.Addr().String() + " tried to connect")
2021-02-28 04:12:28 -08:00
reason := []byte("Your IP address is banned. Banned name is " + bname)
l := len(reason)
data := make([]byte, 7+l)
data[0] = uint8(0x00)
data[1] = uint8(ToClientAccessDenied)
data[2] = uint8(AccessDeniedCustomString)
binary.BigEndian.PutUint16(data[3:5], uint16(l))
copy(data[5:5+l], reason)
data[5+l] = uint8(0x00)
data[6+l] = uint8(0x00)
2021-03-29 09:57:30 -07:00
ack, err := c2.Send(rudp.Pkt{Reader: bytes.NewReader(data)})
2021-02-28 04:12:28 -08:00
if err != nil {
log.Print(err)
}
<-ack
2021-03-29 09:57:30 -07:00
c2.Close()
fin <- c
2021-02-28 04:12:28 -08:00
return
}
2021-01-14 10:06:40 -08:00
// Check if user is already connected
2021-03-29 09:57:30 -07:00
if IsOnline(c2.Username()) {
2021-01-14 10:06:40 -08:00
data := []byte{
2021-01-19 11:37:35 -08:00
0, ToClientAccessDenied,
AccessDeniedAlreadyConnected, 0, 0, 0, 0,
2021-01-14 10:06:40 -08:00
}
2021-03-29 09:57:30 -07:00
ack, err := c2.Send(rudp.Pkt{Reader: bytes.NewReader(data)})
2021-01-14 10:06:40 -08:00
if err != nil {
log.Print(err)
continue
}
<-ack
2021-03-29 09:57:30 -07:00
c2.Close()
fin <- c
2021-01-14 10:06:40 -08:00
return
}
2021-01-29 07:21:43 -08:00
// Check if username is reserved for media or RPC
2021-03-29 09:57:30 -07:00
if c2.Username() == "media" || c2.Username() == "rpc" {
2021-01-29 07:21:43 -08:00
data := []byte{
0, ToClientAccessDenied,
AccessDeniedWrongName, 0, 0, 0, 0,
}
2021-03-29 09:57:30 -07:00
ack, err := c2.Send(rudp.Pkt{Reader: bytes.NewReader(data)})
2021-01-29 07:21:43 -08:00
if err != nil {
log.Print(err)
continue
}
<-ack
2021-03-29 09:57:30 -07:00
c2.Close()
fin <- c
2021-01-29 07:21:43 -08:00
return
}
db, err := initAuthDB()
if err != nil {
log.Print(err)
continue
}
2021-03-29 09:57:30 -07:00
pwd, err := readAuthItem(db, c2.Username())
if err != nil {
log.Print(err)
continue
}
db.Close()
if pwd == "" {
// New player
2021-03-29 09:57:30 -07:00
c2.authMech = AuthMechFirstSRP
binary.BigEndian.PutUint32(data[7:11], uint32(AuthMechFirstSRP))
} else {
// Existing player
2021-03-29 09:57:30 -07:00
c2.authMech = AuthMechSRP
binary.BigEndian.PutUint32(data[7:11], uint32(AuthMechSRP))
}
2021-03-29 09:57:30 -07:00
binary.BigEndian.PutUint16(data[11:13], uint16(len(c2.Username())))
copy(data[13:], []byte(c2.Username()))
2021-03-29 09:57:30 -07:00
ack, err := c2.Send(rudp.Pkt{Reader: bytes.NewReader(data)})
if err != nil {
log.Print(err)
continue
}
<-ack
2021-01-14 10:06:40 -08:00
case ToServerFirstSrp:
// Process data
// Make sure the client is allowed to use AuthMechFirstSRP
2021-03-29 09:57:30 -07:00
if c2.authMech != AuthMechFirstSRP {
log.Print(c2.Addr().String() + " used unsupported AuthMechFirstSRP")
// Send ACCESS_DENIED
data := []byte{
2021-01-19 11:37:35 -08:00
0, ToClientAccessDenied,
AccessDeniedUnexpectedData, 0, 0, 0, 0,
}
2021-03-29 09:57:30 -07:00
ack, err := c2.Send(rudp.Pkt{Reader: bytes.NewReader(data)})
if err != nil {
log.Print(err)
continue
}
<-ack
2021-03-29 09:57:30 -07:00
c2.Close()
fin <- c
return
}
// This is a new player, save verifier and salt
2021-03-29 09:57:30 -07:00
lenSBytes := make([]byte, 2)
r.Read(lenSBytes)
lenS := binary.BigEndian.Uint16(lenSBytes)
s := make([]byte, lenS)
r.Read(s)
2021-03-29 09:57:30 -07:00
lenVBytes := make([]byte, 2)
r.Read(lenVBytes)
lenV := binary.BigEndian.Uint16(lenVBytes)
v := make([]byte, lenV)
r.Read(v)
emptyByte, _ := r.ReadByte()
2021-03-07 01:12:25 -08:00
// Also make sure to check for an empty password
2021-03-09 13:23:41 -08:00
disallow, ok := ConfKey("disallow_empty_passwords").(bool)
2021-03-29 09:57:30 -07:00
if ok && disallow && emptyByte > 0 {
log.Print(c2.Addr().String() + " used an empty password but disallow_empty_passwords is true")
2021-03-07 01:12:25 -08:00
// Send ACCESS_DENIED
data := []byte{
0, ToClientAccessDenied,
AccessDeniedEmptyPassword, 0, 0, 0, 0,
}
2021-03-29 09:57:30 -07:00
ack, err := c2.Send(rudp.Pkt{Reader: bytes.NewReader(data)})
2021-03-07 01:12:25 -08:00
if err != nil {
log.Print(err)
continue
}
<-ack
2021-03-29 09:57:30 -07:00
c2.Close()
fin <- c
2021-03-07 01:12:25 -08:00
return
}
pwd := encodeVerifierAndSalt(s, v)
db, err := initAuthDB()
if err != nil {
log.Print(err)
continue
}
2021-03-29 09:57:30 -07:00
err = addAuthItem(db, c2.Username(), pwd)
if err != nil {
log.Print(err)
continue
}
2021-03-29 09:57:30 -07:00
err = addPrivItem(db, c2.Username())
if err != nil {
log.Print(err)
continue
}
db.Close()
// Send AUTH_ACCEPT
data := []byte{
2021-01-19 11:37:35 -08:00
0, ToClientAuthAccept,
// Position stuff
2021-01-19 11:37:35 -08:00
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
// Map seed
2021-01-19 11:37:35 -08:00
0, 0, 0, 0,
0, 0, 0, 0,
// Send interval
2021-01-19 11:37:35 -08:00
0x3D, 0xB8, 0x51, 0xEC,
// Sudo mode mechs
2021-01-19 11:37:35 -08:00
0, 0, 0, AuthMechSRP,
}
2021-03-29 09:57:30 -07:00
ack, err := c2.Send(rudp.Pkt{Reader: bytes.NewReader(data)})
if err != nil {
log.Print(err)
continue
}
<-ack
2021-01-14 10:06:40 -08:00
case ToServerSrpBytesA:
// Process data
// Make sure the client is allowed to use AuthMechSRP
2021-03-29 09:57:30 -07:00
if c2.authMech != AuthMechSRP {
log.Print(c2.Addr().String() + " used unsupported AuthMechSRP")
// Send ACCESS_DENIED
data := []byte{
2021-01-19 11:37:35 -08:00
0, ToClientAccessDenied,
AccessDeniedUnexpectedData, 0, 0, 0, 0,
}
2021-03-29 09:57:30 -07:00
ack, err := c2.Send(rudp.Pkt{Reader: bytes.NewReader(data)})
if err != nil {
log.Print(err)
continue
}
<-ack
2021-03-29 09:57:30 -07:00
c2.Close()
return
}
2021-03-29 09:57:30 -07:00
lenABytes := make([]byte, 2)
r.Read(lenABytes)
lenA := binary.BigEndian.Uint16(lenABytes)
A := make([]byte, lenA)
r.Read(A)
db, err := initAuthDB()
if err != nil {
log.Print(err)
continue
}
2021-03-29 09:57:30 -07:00
pwd, err := readAuthItem(db, c2.Username())
if err != nil {
log.Print(err)
continue
}
db.Close()
s, v, err := decodeVerifierAndSalt(pwd)
if err != nil {
log.Print(err)
continue
}
B, _, K, err := srp.Handshake(A, v)
if err != nil {
log.Print(err)
continue
}
2021-03-29 09:57:30 -07:00
c2.srp_s = s
c2.srp_A = A
c2.srp_B = B
c2.srp_K = K
// Send SRP_BYTES_S_B
data := make([]byte, 6+len(s)+len(B))
data[0] = uint8(0x00)
2021-01-14 10:06:40 -08:00
data[1] = uint8(ToClientSrpBytesSB)
binary.BigEndian.PutUint16(data[2:4], uint16(len(s)))
copy(data[4:4+len(s)], s)
binary.BigEndian.PutUint16(data[4+len(s):6+len(s)], uint16(len(B)))
copy(data[6+len(s):6+len(s)+len(B)], B)
2021-03-29 09:57:30 -07:00
ack, err := c2.Send(rudp.Pkt{Reader: bytes.NewReader(data)})
if err != nil {
log.Print(err)
continue
}
<-ack
2021-01-14 10:06:40 -08:00
case ToServerSrpBytesM:
// Process data
// Make sure the client is allowed to use AuthMechSRP
2021-03-29 09:57:30 -07:00
if c2.authMech != AuthMechSRP {
log.Print(c2.Addr().String() + " used unsupported AuthMechSRP")
// Send ACCESS_DENIED
data := []byte{
2021-01-19 11:37:35 -08:00
0, ToClientAccessDenied,
AccessDeniedUnexpectedData, 0, 0, 0, 0,
}
2021-03-29 09:57:30 -07:00
ack, err := c2.Send(rudp.Pkt{Reader: bytes.NewReader(data)})
if err != nil {
log.Print(err)
continue
}
<-ack
2021-03-29 09:57:30 -07:00
c2.Close()
fin <- c
return
}
2021-03-29 09:57:30 -07:00
lenMBytes := make([]byte, 2)
r.Read(lenMBytes)
lenM := binary.BigEndian.Uint16(lenMBytes)
M := make([]byte, lenM)
r.Read(M)
2021-03-31 10:27:50 -07:00
M2 := srp.ClientProof([]byte(c2.Username()), c2.srp_s, c2.srp_A, c2.srp_B, c2.srp_K)
if subtle.ConstantTimeCompare(M, M2) == 1 {
// Password is correct
// Send AUTH_ACCEPT
data := []byte{
2021-01-19 11:37:35 -08:00
0, ToClientAuthAccept,
// Position stuff
2021-01-19 11:37:35 -08:00
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
// Map seed
2021-01-19 11:37:35 -08:00
0, 0, 0, 0,
0, 0, 0, 0,
// Send interval
2021-01-19 11:37:35 -08:00
0x3D, 0xB8, 0x51, 0xEC,
// Sudo mode mechs
2021-01-19 11:37:35 -08:00
0, 0, 0, AuthMechSRP,
}
2021-03-29 09:57:30 -07:00
ack, err := c2.Send(rudp.Pkt{Reader: bytes.NewReader(data)})
if err != nil {
log.Print(err)
continue
}
<-ack
} else {
// Client supplied wrong password
2021-03-29 09:57:30 -07:00
log.Print("User " + c2.Username() + " at " + c2.Addr().String() + " supplied wrong password")
// Send ACCESS_DENIED
data := []byte{
2021-01-19 11:37:35 -08:00
0, ToClientAccessDenied,
AccessDeniedWrongPassword, 0, 0, 0, 0,
}
2021-03-29 09:57:30 -07:00
ack, err := c2.Send(rudp.Pkt{Reader: bytes.NewReader(data)})
if err != nil {
log.Print(err)
continue
}
<-ack
2021-03-29 09:57:30 -07:00
c2.Close()
fin <- c
return
}
2021-01-14 10:06:40 -08:00
case ToServerInit2:
2021-03-29 09:57:30 -07:00
c2.announceMedia()
2021-01-16 10:14:31 -08:00
case ToServerRequestMedia:
2021-04-01 11:27:58 -07:00
c2.sendMedia(r)
2021-01-16 10:14:31 -08:00
case ToServerClientReady:
2021-03-13 09:58:51 -08:00
defaultSrv := ConfKey("default_server").(string)
2021-03-29 09:57:30 -07:00
defSrv := func() *Conn {
2021-03-13 09:58:51 -08:00
defaultSrvAddr := ConfKey("servers:" + defaultSrv + ":address").(string)
srvaddr, err := net.ResolveUDPAddr("udp", defaultSrvAddr)
if err != nil {
log.Print(err)
return nil
}
conn, err := net.DialUDP("udp", nil, srvaddr)
if err != nil {
log.Print(err)
return nil
}
2021-03-29 09:57:30 -07:00
srv, err := Connect(conn)
2021-03-13 09:58:51 -08:00
if err != nil {
log.Print(err)
return nil
}
2021-03-29 09:57:30 -07:00
fin2 := make(chan *Conn) // close-only
go Init(c2, srv, ignMedia, noAccessDenied, fin2)
2021-03-17 09:18:21 -07:00
<-fin2
2021-03-29 09:57:30 -07:00
go processJoin(c2)
2021-03-13 09:58:51 -08:00
return srv
}
2021-03-09 13:23:41 -08:00
if forceDefaultServer, ok := ConfKey("force_default_server").(bool); !forceDefaultServer || !ok {
2021-03-29 09:57:30 -07:00
srvname, err := StorageKey("server:" + c2.Username())
2021-01-20 12:44:35 -08:00
if err != nil {
2021-03-09 13:23:41 -08:00
srvname, ok = ConfKey("servers:" + ConfKey("default_server").(string) + ":address").(string)
2021-01-20 12:44:35 -08:00
if !ok {
2021-03-29 09:57:30 -07:00
go c2.SendChatMsg("Could not connect you to your last server!")
2021-01-20 12:44:35 -08:00
2021-03-13 09:58:51 -08:00
fin <- defSrv()
2021-01-20 12:44:35 -08:00
return
}
}
2021-03-09 13:23:41 -08:00
straddr, ok := ConfKey("servers:" + srvname + ":address").(string)
2021-01-20 12:44:35 -08:00
if !ok {
2021-03-29 09:57:30 -07:00
go c2.SendChatMsg("Could not connect you to your last server!")
2021-01-20 12:44:35 -08:00
2021-03-13 09:58:51 -08:00
fin <- defSrv()
2021-01-20 12:44:35 -08:00
return
}
srvaddr, err := net.ResolveUDPAddr("udp", straddr)
if err != nil {
2021-03-29 09:57:30 -07:00
go c2.SendChatMsg("Could not connect you to your last server!")
2021-01-20 12:44:35 -08:00
2021-03-13 09:58:51 -08:00
fin <- defSrv()
2021-01-20 12:44:35 -08:00
return
}
conn, err := net.DialUDP("udp", nil, srvaddr)
if err != nil {
2021-03-29 09:57:30 -07:00
go c2.SendChatMsg("Could not connect you to your last server!")
2021-01-20 12:44:35 -08:00
2021-03-13 09:58:51 -08:00
fin <- defSrv()
2021-01-20 12:44:35 -08:00
return
}
2021-03-13 09:58:51 -08:00
if srvname != defaultSrv {
2021-03-29 09:57:30 -07:00
srv, err := Connect(conn)
2021-01-20 12:44:35 -08:00
if err != nil {
2021-03-29 09:57:30 -07:00
go c2.SendChatMsg("Could not connect you to your last server!")
2021-01-20 12:44:35 -08:00
2021-03-13 09:58:51 -08:00
fin <- defSrv()
2021-01-20 12:44:35 -08:00
return
}
2021-03-29 09:57:30 -07:00
fin2 := make(chan *Conn) // close-only
go Init(c2, srv, ignMedia, noAccessDenied, fin2)
2021-03-14 05:52:31 -07:00
<-fin2
2021-03-29 09:57:30 -07:00
go c2.updateDetachedInvs(srvname)
go processJoin(c2)
2021-01-20 12:44:35 -08:00
fin <- srv
return
}
}
2021-03-13 09:58:51 -08:00
fin <- defSrv()
return
}
}
}
}