Skip to content

Instantly share code, notes, and snippets.

@hsnks100
Last active October 6, 2021 02:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hsnks100/bdc2ae211e3c91380e10785c70120922 to your computer and use it in GitHub Desktop.
Save hsnks100/bdc2ae211e3c91380e10785c70120922 to your computer and use it in GitHub Desktop.
같은 일을 하는 golang 서버와 공격 클라이언트
package main
import (
"fmt"
"log"
"net"
"time"
)
func worker(id int, jobs <-chan int, results chan<- uint64) {
for j := range jobs {
_ = j
conn, err := net.Dial("tcp", "112.170.25.154:3333")
if nil != err {
log.Println(err)
}
go func() {
data := make([]byte, 4096)
for {
n, err := conn.Read(data)
// atomic.AddUint64(&ops, uint64(n))
// atomic.AddUint64(&cnt, 1)
if err != nil {
log.Println(err)
return
}
if n == 5 {
results <- 1
// conn.Close()
// break
}
// log.Println("Server send : ", data[:n])
}
}()
send := []byte{0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
send = append(send, []byte{0x99, 0x99, 0x99, 0x99, 0x99}...)
conn.Write(send)
}
}
func main() {
nn := make(chan uint64, 10000)
start := time.Now()
sockets := uint64(1000)
go func() {
sum := uint64(0)
for {
select {
case i := <-nn:
sum += i
if sum == sockets*1 {
duration := time.Since(start)
fmt.Println(sum, duration)
}
}
}
}()
jobs := make(chan int, 10000)
for w := 1; w <= 5; w++ {
go worker(w, jobs, nn)
}
for i := uint64(0); i < sockets; i++ {
jobs <- int(i)
}
for {
}
}
#pragma once
#include <inttypes.h>
#include <memory.h>
#pragma pack(push, 1)
typedef struct PKT_HDRtag
{
int32_t ServiceCode; // 서비스코드
int32_t ResultCode; // 리턴 코드
int32_t DataLen; // 데이터 길이
uint32_t Checksum; // 헤더 체크섬, iServiceCode ^ iResultCode ^ iDataLen
uint8_t body[0];
} PKT_HDR;
typedef struct Body_ {
char szKey[32]; // bno_resolution_bitrate
uint64_t frameNumber;
uint8_t frameType; // 'A' or 'V'
uint8_t Frame[0]; // 프레임 데이터
} Body;
#pragma pack(pop)
package main
import (
"bytes"
"encoding/binary"
_ "fmt"
"net"
log "github.com/sirupsen/logrus"
)
import "C"
/*
#cgo CFLAGS: -I./
#define CGO
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include "cheader.h"
*/
import "C"
type Session struct {
socket net.Conn
}
func (thiz *Session) Handler(splitterSocket net.Conn) {
thiz.socket = splitterSocket
data := make([]byte, 4096)
headerPacket := C.PKT_HDR{}
headerSize := 4 + 4 + 4 + 4 // C.sizeof_PKT_HDR
needBytes := headerSize
step := 1
var netBuffer bytes.Buffer
sendChannel := make(chan []byte, 1500)
doClose := make(chan bool)
go func(conn net.Conn) {
for {
select {
case msg := <-sendChannel:
if _, err := conn.Write(msg); err != nil {
log.Error("[writer] ", err, len(sendChannel))
// return
} else {
log.Infof("================ CHANNEL WRITE OK[%d] ===================", len(msg))
}
log.Info("woww")
case <-doClose:
log.Info("================ CHANNEL WRITER END ===================")
return
}
}
}(splitterSocket)
for {
n, err := thiz.socket.Read(data) // 서버에서 받은 데이터를 읽음
if err != nil {
log.Error("================== Socket Error ==================")
log.Error(err)
close(doClose)
splitterSocket.Close()
return
}
// fmt.Println("받은 데이터:\n", hex.Dump(data[:n]))
netBuffer.Write(data[:n])
// PKT_HDR 프로토콜 처리하는 부분
for netBuffer.Len() >= needBytes {
if step == 1 {
bb := make([]byte, needBytes)
_, err := netBuffer.Read(bb)
if err != nil {
}
_ = binary.Read(bytes.NewBuffer(bb), binary.LittleEndian, &headerPacket)
step = 2
needBytes = int(headerPacket.DataLen) // 다음 받을 바이트 수
} else if step == 2 {
bb := make([]byte, needBytes)
_, err := netBuffer.Read(bb)
if err != nil {
}
step = 1
needBytes = headerSize
log.Infof("len(bb): %d", len(bb))
sendChannel <- bb
}
}
}
}
package main
import (
"fmt"
"sync"
// "mime/multipart"
"net"
"os"
"runtime/debug"
"time"
"github.com/jinzhu/configor"
"github.com/nareix/joy4/format"
log "github.com/sirupsen/logrus"
)
/*
*/
import "C"
var Config = struct {
RedisUrl string `required:"true"`
IpifyUrl string `required:"true"`
Port uint `required:"true"`
Message string `required:"true"`
}{}
var ip string
var adminPort string
var wait sync.WaitGroup
func sendKeepAlive(ticker *time.Ticker) {
defer wait.Done()
for {
select {
case <-ticker.C:
{
}
// do stuff
}
}
}
func init() {
format.RegisterAll()
}
func main() {
wait.Add(2)
configor.Load(&Config, "config.yml")
log.SetFormatter(&log.TextFormatter{})
log.SetReportCaller(true)
file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err == nil {
log.SetOutput(file)
} else {
log.Info("Failed to log to file, using default stderr")
}
defer func() {
if r := recover(); r != nil {
log.Infoln(string(debug.Stack()))
}
}()
log.Infoln("START: ", Config.Message)
// getRedis()
ticker := time.NewTicker(5 * time.Second)
go sendKeepAlive(ticker)
log.Println("======================= START!!")
go startServer()
//goroutine 종료를 기다림
wait.Wait()
fmt.Println("exit!!")
}
func startServer() {
defer wait.Done()
ln, err := net.Listen("tcp", "0.0.0.0:"+"3333") // TCP 프로토콜에 8000 포트로 연결을 받음
if err != nil {
fmt.Println(err)
return
}
defer ln.Close() // main 함수가 끝나기 직전에 연결 대기를 닫음
for {
conn, err := ln.Accept() // 클라이언트가 연결되면 TCP 연결을 리턴
if err != nil {
fmt.Println(err)
continue
}
// defer conn.Close() // main 함수가 끝나기 직전에 TCP 연결을 닫음
s := Session{conn}
log.Info("======================= Accept!!!!!")
// defer conn.Close() // main 함수가 끝나기 직전에 TCP 연결을 닫음
go s.Handler(conn) // 패킷을 처리할 함수를 고루틴으로 실행
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment