sandertv / go-raknet Goto Github PK
View Code? Open in Web Editor NEWGo library implementing a basic version of the RakNet protocol.
License: MIT License
Go library implementing a basic version of the RakNet protocol.
License: MIT License
Currently, when packets are not immediately read from a *raknet.Conn
, the server will be blocked until this happens anyway. Having a single client block until the next packet is acceptable, but blocking the entire server is unacceptable, as packets that are not instantly handled could directly result in a considerable slowdown for all other clients.
I'm new to go and I've no experience with go tickers but I'm sure this condition is true 100 times every 4 seconds by default and it's not supposed to be.
t.Unix()
is the current time in seconds and will be the same 100 times every second
The Listener.Accept method (https://github.com/Sandertv/go-raknet/blob/master/listener.go#L79) currently does not obtain connections that are ready right away. It gets a connection that still needs to do the RakNet connection sequence, which poses a problem if the client has a poor connection. Listener.Accept can block up to 10 seconds, after which it times out and tries the next connection, until a new client can be accepted. This is a major issue for frequent connection attempts with a high latency.
Hello, I believe I found a bug and will submit a patch soon.
The bug is this:
When using the project as proxy the MTU may be different between clients and server, and that will break the raknet protocol, that is MTU sensitive, because packets between server and clients in the example proxy are passed as raw data, they are not assembled, while the MTUs are negotiated between proxy and server and proxy and clients inside the raknet handshake.
The solution I found was to connect to the server first, get the MTU of the server, and disconnect. Wait for client connections but limiting max MTU with client to match MTU of the server, and then when opening the connection to the server after a client connects, limit server MTU with client's. This will cover usecases where either client or server have bigger MTU than the other, by limiting the MTU of the connection to the least of the two sides.
As of v1.14.0, go-raknet uses cookies to prevent IP spoofing attacks. These cookies are very inexpensive to generate and check. Some server providers (OVH specifically) have built-in protection against these kinds of attacks however, which breaks when used in combination with these cookies, meaning clients are entirely unable to connect.
To avert this, there is a DisableCookies field in go-raknet, but ideally this should not exist. People have messaged OVH to let them know of this issue so this may be fixed in the future. That would mean removing the field in go-raknet, which is a backwards incompatible change (so not great).
Remove this field before release?
I just updated go-raknet to the latest release available and this error occurs:
panic: error establishing a connection: connection timed out
goroutine 1 [running]:
main.main()
/home/gio/Desktop/test/gophertunnel/main.go:39 +0x56b
You can reproduce by using the proxy from the gophertunnel repo and connecting to "hivebedrock.network:19132"
Before the update I was using the one from this commit and it worked
This error is from here
I don't know why the raknet connection is timing out, the ConnectionRequestAccepted is received correctly.
For some reason, the recordCount is set to 1 from the start while writing an acknowledgement packet, resulting in a recordCount that is too high. If the packet is read, this will result in an overflow, because it expects another record to be available.
Trying to connect to a server which uses the RakNet security flag (In OpenConnectionReply1) causes a timeout. While I am not 100% sure that the timeout is not caused by some other error in go-raknet other RakNet libraries failed because of the servers usage of the security flag (See CloudburstMC/Network#37). Connecting to the server with Bedrock Edition (or https://github.com/extremeheat/fb-raknet) works fine since both use the original RakNet.
Reproduceable example code:
package main
import (
"github.com/sandertv/go-raknet"
"time"
)
func main() {
conn, err := raknet.DialTimeout("play.timecrack.net:19132", time.Duration(5)*time.Second)
if err != nil {
panic(err.Error())
}
defer func(conn *raknet.Conn) {
err := conn.Close()
if err != nil {
panic(err.Error())
}
}(conn)
println("Connected")
}
go-raknet uses a buffered channel for storing and retrieving incoming packets from a connection. This channel needs to have a large buffered size to prevent an entire Listener from being blocked if this channel is full, which is not ideal. The channel is currently created with a size of 512: https://github.com/Sandertv/go-raknet/blob/master/conn.go#L103
This channel is responsible for roughly a third of allocations/in use memory of go-raknet and remains a potential attack vector against listeners.
This channel should be replaced with a different (dynamic) approach that doesn't require buffering beforehand and doesn't block when the buffer is full.
Lines 666 to 669 in fbd2ad1
Theoretically speaking the client should never send more than one or two unique split IDs, and go-raknet allows up to 256 at one time. This could be abused to keep ~97mb (256*255*1492
) of data in memory from one connection if they don't send the last split for each packet.
The Discord invite has expired or has been deleted. Please update it to a new one. Thanks!
how do i get a raklib packet from the buffer string?
!without connection, only from buffer string!
go-raknet should have a security measurement stopping ips from spamming bad packets over and over
This happens randomly on different servers, this one in particular, on lbsg:
panic: error discovering MTU size: read udp myIP:46257->lbsgIP:19132: read: message too long
Also, the way the MTU is discovered (subtracting 40 to the size every 1/2 second) it's not the same way minecraft itself does it. Minecraft only uses 3 MTU sizes: 1492, 1200, 576
When i use conn.Write(), it causes the following errors
2022/08/25 19:50:01 error handling packet: error handling packet in datagram: error handling packet: error measuring rtt: ping timestamp is in the future
....
Just byte send testing is ok.
This happens on some servers, mostly nethergames, but not all of the time
It happens with raknet.Dial but not with net.Dial("udp", addr)
It will happen the first time dialing, and then not happen for a while, unless I turn off my wifi and turn it back on on my PC
It occurs at:
Line 438 in c8d5d29
Currently a packet is resent if no ACK is received before Round-Trip Time + 10ms
since it was sent.
This is "fine" for most of the servers sending ACKs every 10ms (PocketMine)
But there are some servers, like SteadFast2 which instead will send ACKs every 25ms
The RTT is not perfect, changes continuously overtime and only indicates a rough estimate of the ping latency which is different than the ACK one
So, on some servers packets will be resent forever since it's impossible to receive an ACK in time.
The effect of this is not noticeable because the client and server will automatically discard duplicate packets.
When trying to execute a executable generated with this example code it fails:
package main
import (
"github.com/sandertv/go-raknet"
)
func main() {
listener, _ := raknet.Listen("0.0.0.0:19132")
listener.PongData([]byte("MCPE;Dedicated Server;120;1.20.50;1000;9999;13253860896781930865;Bedrock level;Survival;1;19132;19133;"))
defer listener.Close()
for {
conn, _ := listener.Accept()
b := make([]byte, 1024*1024*4)
_, _ = conn.Read(b)
}
}
The following error:
C:\Users\current_user\Test>Test.exe
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x0 pc=0x9c62a9]
goroutine 1 [running]:
github.com/sandertv/go-raknet.(*Listener).PongData(0x0?, {0xc0000c6000?, 0x0?, 0x9ff13d?})
C:/Users/current_user/go/pkg/mod/github.com/sandertv/[email protected]/listener.go:139 +0x29
main.main()
C:/Users/current_user/Test/main.go:9 +0x88
two logs were triggered:
2023/07/27 11:48:03 listener: error handling packet (addr = x.x.x.x:46926): error reading unconnected ping: unexpected EOF
2023/07/28 11:09:03 listener: error handling packet (addr = x.x.x.x:46926): error reading unconnected ping: EOF
those logs might be the reason for these two players being kept on the (dragonfly) server, even while disconnected:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.