Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

panic: runtime error: slice bounds out of range [-1:] #40

Closed
terrifictable opened this issue Dec 18, 2022 · 12 comments · Fixed by #41 or #43
Closed

panic: runtime error: slice bounds out of range [-1:] #40

terrifictable opened this issue Dec 18, 2022 · 12 comments · Fixed by #41 or #43
Assignees
Labels
bug Something isn't working good first issue Good for newcomers
Milestone

Comments

@terrifictable
Copy link

When running pings in coroutines after a few "threads" finish i get this error/panic:

panic: runtime error: slice bounds out of range [-3:]

goroutine 183 [running]:
github.com/dreamscached/minequery/v2.(*Pinger).ping17ReadStatusResponsePacketPayload(0xc0000564a0?, {0x2673ea66f98, 0xc0065da1c0})
        C:/Users/Sandbox/go/pkg/mod/github.com/dreamscached/minequery/v2@v2.3.0/ping_17.go:1841 +0x525

This is my code:

var wg sync.WaitGroup
var pingout []minequery.Status17
for i, data := range payload {
  wg.Add(1)

  go func(data Data, i int) {
    defer wg.Done()

    res, err := minequery.Ping17(data.IP, data.Ports[0].Port)
    if err != nil { fmt.Printf("[%d -> %s] (Failed) %s\n", i, data.IP, err); return }
    pingout = append(pingout, *res)
  }(data, i)
}
wg.Wait()
@dreamscached
Copy link
Owner

What server are you trying to ping? Does the issue persist if pinged synchronously?

@dreamscached dreamscached added the bug Something isn't working label Dec 18, 2022
@terrifictable
Copy link
Author

terrifictable commented Dec 18, 2022

What server are you trying to ping? Does the issue persist if pinged synchronously?

it also happens when running synchronously

@terrifictable
Copy link
Author

terrifictable commented Dec 18, 2022

It happens with quite a few servers (...in context to scanning a list of 5k servers)

i would say its about 2/1000 servers that cause this error
but all the servers that cause this problem seem to be offline (or i may be/am getting ip banned)

oh and its always a diffrent server, sometimes ip xxx.xxx.x.xxx causes that panic to happen and if i run again, xxx.xxx.x.xxx works fine without any problems but another server causes the panic

@dreamscached
Copy link
Owner

I'll add a failsafe there but generally I struggle to imagine what exactly is the cause there without a way to reproduce, so far I couldn't reproduce it anyhow. Can you share a list of your servers? If it's sensitive not to post it here you can direct them to my e-mail or Discord if you prefer.

@terrifictable
Copy link
Author

terrifictable commented Dec 19, 2022

I'll add a failsafe there but generally I struggle to imagine what exactly is the cause there without a way to reproduce, so far I couldn't reproduce it anyhow. Can you share a list of your servers? If it's sensitive not to post it here you can direct them to my e-mail or Discord if you prefer.

i was using a server list from a discord server,
im now using mat-1's server ip list
because im searching for a server

the new list im using doesnt seem to cause the panic as much as the old one, but it still does, i found a probably really bad workarround by using a function that calls the scan and catches a panic

@terrifictable
Copy link
Author

terrifictable commented Dec 19, 2022

This is my code:

package main

import (
    "fmt"
    "time"
    "io/ioutil"
    "log"
    "encoding/json"

    "os"
    "encoding/binary"
    "image/png"
    "bytes"
    "encoding/base64"
    "github.com/dreamscached/minequery/v2"
)

type Data struct {
    IP        string `json:"ip"`
    Timestamp string `json:"timestamp"`
    Ports     []struct {
        Port    int `json:"port"`
        Proto   string `json:"proto"`
        Status  string `json:"status"`
        Reason  string `json:"reason"`
        TTL     int `json:"ttl"`
    } `json:"ports"`
}


type ResponseData struct {
    VersionName     string
    ProtocolVersion int

    OnlinePlayers int
    MaxPlayers    int
    SamplePlayers []minequery.PlayerEntry17

    Description string
    Icon        string

    PreviewsChat       bool
    EnforcesSecureChat bool
}

type Response struct {
    Data ResponseData
    IP string
    Port int
}

var panics int

func wrapAndCountPanics(f func()) {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("(Error) go func panicked")
            panics++
        }
    }()

    f()
}

func main() {
    start := time.Now().UnixMilli()
    var pingout []Response

    fmt.Println("\n [ Start ] ")


    file, err := os.Open("../ips")
    if err != nil {
        log.Fatal("Error when opening file: ", err)
    }

    defer func() {
        final, _ := json.MarshalIndent(pingout, "", "  ")
        err := ioutil.WriteFile("../ping_out.json", final, os.ModePerm)
        if err != nil {
            fmt.Printf("(Error -> ioutil.WriteFile) %s\n", err)
        }
        file.Close()

        fmt.Printf("\n [ End | Took: %dms ] \n", time.Now().UnixMilli()-start)
    }()


    i := 0
    byteBuff := make([]byte, 6)
    for ;; {

        func() {
            defer func() { i++ }()

            _, err = file.Read(byteBuff)
            if err != nil { return }

            ip := fmt.Sprintf("%d.%d.%d.%d", byteBuff[0], byteBuff[1], byteBuff[2], byteBuff[3])
            port := int(binary.BigEndian.Uint16(byteBuff[4:]))

            res, err := minequery.Ping17(ip, port)
            if err != nil { fmt.Printf("[%d -> %s:%d] (Failed) %s\n", i, ip, port, err); return }

            var iconBuf bytes.Buffer
            var b64Icon string
            if res.Icon != nil {
                png.Encode(&iconBuf, res.Icon)
                b64Icon = base64.StdEncoding.EncodeToString(iconBuf.Bytes())
            }

            pingout = append(pingout, Response {
                Data: ResponseData {
                    res.VersionName,
                    res.ProtocolVersion,
                    res.OnlinePlayers,
                    res.MaxPlayers,
                    res.SamplePlayers,
                    res.DescriptionText(),
                    b64Icon,
                    res.PreviewsChat,
                    res.EnforcesSecureChat,
                },
                IP: ip,
                Port: port,
            })

        }()

        if i >= 500 {
            break
        }
    }

    fmt.Printf("IPs: %d\n", i)


}

(its really bad ik)

the ips file is from mat-1's server ip list/dump

maybe you can reproduce the issue with this
image

@dreamscached
Copy link
Owner

Thank you for reporting and providing data.

@terrifictable
Copy link
Author

ok, so it appears that all servers that cause this panic are from: craftserve.pl

@dreamscached dreamscached added this to the Next release milestone Dec 21, 2022
@dreamscached dreamscached self-assigned this Dec 21, 2022
@dreamscached
Copy link
Owner

Could you provide exact IPs that caused this error? I tried running tests on IPs you sent but so far none could help reproduce the issue.

@dreamscached dreamscached added the investigating We are working on figuring this out label Dec 22, 2022
@dreamscached
Copy link
Owner

dreamscached commented Dec 22, 2022

Actually, managed to reproduce, it seems like a DDoS measure of some sort is used.

Testuj za darmo przez 24h! <nil> false false}
&{??? 0 0 1 [] Craftserve.pl - wydajny hosting Minecraft!
Testuj za darmo przez 24h! <nil> false false}
&{??? 0 0 1 [] Ochrona DDoS: Przekroczono limit polaczen. (1) <nil> false false}
&{??? 0 0 1 [] Ochrona DDoS: Przekroczono limit polaczen. (1) <nil> false false}
&{??? 0 0 1 [] Ochrona DDoS: Przekroczono limit polaczen. (1) <nil> false false}
panic: runtime error: slice bounds out of range [-1:]

goroutine 1 [running]:
github.com/dreamscached/minequery/v2.(*Pinger).ping17ReadStatusResponsePacketPayload(0xc00006c100?, {0x598320, 0xc000014608})
        /home/dreamscached/Dokumenty/Vývoj/Projekty/dreamscached/minequery/ping_17.go:1841 +0x525
github.com/dreamscached/minequery/v2.(*Pinger).Ping17(0xc00006c100, {0x565026, 0xe}, 0x1?)
        /home/dreamscached/Dokumenty/Vývoj/Projekty/dreamscached/minequery/ping_17.go:1757 +0x27b
github.com/dreamscached/minequery/v2.Ping17(...)
        /home/dreamscached/Dokumenty/Vývoj/Projekty/dreamscached/minequery/ping_17.go:1731
main.main()
        /home/dreamscached/Dokumenty/Vývoj/Projekty/dreamscached/minequery/main/main.go:11 +0x8b

Process finished with the exit code 2

For now I'd suggest setting a limit of retries/pings or somehow employ longer delays for this specific IP/subnet you experience issue with. While I'll implement a failsafe that will prevent panicking, I cannot ensure that MineQuery will not trigger any anti-DDoS and alike measures.

@dreamscached dreamscached added good first issue Good for newcomers and removed investigating We are working on figuring this out labels Dec 22, 2022
dreamscached added a commit that referenced this issue Dec 22, 2022
@dreamscached dreamscached linked a pull request Dec 22, 2022 that will close this issue
dreamscached added a commit that referenced this issue Dec 22, 2022
@dreamscached
Copy link
Owner

The issue has been resolved, use v2.3.1 in your Go module which contains fix patch.

@terrifictable
Copy link
Author

The issue has been resolved, use v2.3.1 in your Go module which contains fix patch.

thank you for resolving the problem so quickly :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working good first issue Good for newcomers
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants