📶 [WIP] RouterOS WinBox bruteforce
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
mtbf/thread.go

102 lines
2.3 KiB

2 years ago
package main
2 years ago
// thread.go: handling of worker threads
2 years ago
import (
"sync"
"time"
)
func init() {
registerParam("threads", 3, "how many threads to use")
registerParam("thread-delay-ms", 10, "separate threads at startup for this amount of ms")
// using a very high limit for now, but this should actually be set to -1
registerParam("task-max-deferrals", 30000, "how many deferrals are allowed for a single task. -1 to disable")
registerAlias("t", "threads")
}
2 years ago
// maxSafeThreads is a safeguard to prevent creation of too many threads at once.
const maxSafeThreads = 5000
// ThreadService creates, starts up and waits for all threads.
func ThreadService() {
numThreads := getParamInt("threads")
failIf(numThreads > maxSafeThreads, "too many threads (max %v)", maxSafeThreads)
log("thread", 1, "initializing %v threads", numThreads)
2 years ago
c := make(chan bool)
var wg sync.WaitGroup
for i := 1; i <= numThreads; i++ {
wg.Add(1)
go threadEntryPoint(c, i, &wg)
}
threadDelay := getParamDurationMS("thread-delay-ms")
log("thread", 0, "starting %v threads", numThreads)
for i := 1; i <= numThreads; i++ {
c <- true
if threadDelay > 0 {
time.Sleep(threadDelay)
}
}
2 years ago
2 years ago
wg.Wait()
log("thread", 1, "finished threads")
2 years ago
}
// threadEntryPoint is the main entrypoint for a work thread.
func threadEntryPoint(c chan bool, threadIdx int, wg *sync.WaitGroup) {
<-c
log("thread", 3, "starting loop for thread %v", threadIdx)
for threadWork(threadIdx) {
2 years ago
}
log("thread", 3, "exiting thread %v", threadIdx)
wg.Done()
}
// threadWork processes a single work item for a thread.
func threadWork(threadIdx int) bool {
task, delay := CreateTask(threadIdx)
2 years ago
if task == nil {
if delay > 0 {
log("thread", 3, "no work currently available, sleeping for %v in thread %v", delay, threadIdx)
2 years ago
time.Sleep(delay)
return true
} else {
log("thread", 2, "no more work for thread %v", threadIdx)
2 years ago
return false
}
}
log("thread", 4, "got task %v", task)
2 years ago
conn, err := NewConnection(task.e)
2 years ago
if err != nil {
2 years ago
task.EventWithParm(TE_NoResponse, err)
2 years ago
return true
}
task.Event(TN_Connected)
2 years ago
log("thread", 2, "trying %v", task)
2 years ago
res, err := TryLogin(task, conn)
if err != nil {
task.Event(TE_ProtocolError)
} else {
if res && err == nil {
task.EventWithParm(TE_Good, task.login)
2 years ago
} else {
2 years ago
task.Event(TE_Bad)
2 years ago
}
}
return true
}