Skip to content

Commit

Permalink
Add debugging information for DenyIP and fix linting recommendations
Browse files Browse the repository at this point in the history
  • Loading branch information
zquestz committed Mar 28, 2019
1 parent 5cd297a commit 566547a
Show file tree
Hide file tree
Showing 10 changed files with 47 additions and 36 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -6,6 +6,9 @@
# The binary.
cashshuffle

# VSCode
.vscode

# Folders
_obj
_test
Expand Down
2 changes: 1 addition & 1 deletion cmd/main.go
Expand Up @@ -18,7 +18,7 @@ import (

const (
appName = "cashshuffle"
version = "0.6.15"
version = "0.6.16"
defaultPort = 1337
defaultWebSocketPort = 1338
defaultTorPort = 1339
Expand Down
4 changes: 4 additions & 0 deletions server/banned.go
Expand Up @@ -2,6 +2,7 @@ package server

import (
"errors"
"fmt"

"github.com/cashshuffle/cashshuffle/message"
)
Expand Down Expand Up @@ -72,6 +73,9 @@ func (pi *packetInfo) checkBlameMessage() error {
if blamer.pool.IsBanned(accused) {
blamer.pool.firstBan = accused
pi.tracker.increaseBanScore(accused.conn, false)
if debugMode {
fmt.Printf("[DenyIP] User blamed out of round: %s\n", accused.verificationKey)
}
pi.tracker.addDenyIPMatch(accused.conn, accused.pool, false)
pi.tracker.remove(accused.conn)
}
Expand Down
2 changes: 1 addition & 1 deletion server/broadcast.go
Expand Up @@ -101,7 +101,7 @@ func (pi *packetInfo) announceStart() {
}
}

func (pi *packetInfo) broadcastJoinedPool(p *playerData) {
func (pi *packetInfo) broadcastJoinedPool(p *PlayerData) {
m := message.Signed{
Packet: &message.Packet{
Number: p.number,
Expand Down
4 changes: 2 additions & 2 deletions server/messages.go
Expand Up @@ -42,7 +42,7 @@ func startPacketInfoChan(c chan *packetInfo) {

// processReceivedMessage reads the message and processes it.
func (pi *packetInfo) processReceivedMessage() error {
var player *playerData
var player *PlayerData
// If we are not tracking the connection yet, the user must be
// registering with the server.
if pi.tracker.playerByConnection(pi.conn) == nil {
Expand All @@ -54,7 +54,7 @@ func (pi *packetInfo) processReceivedMessage() error {
player = pi.tracker.playerByConnection(pi.conn)

// If a malicious client is connecting and disconnecting
// quickly it is possible that playerData will be nil.
// quickly it is possible that PlayerData will be nil.
// No need to return an error, just don't register them.
if player == nil {
return nil
Expand Down
6 changes: 3 additions & 3 deletions server/player_data.go
Expand Up @@ -7,8 +7,8 @@ import (
"github.com/cashshuffle/cashshuffle/message"
)

// playerData is data needed about each connection.
type playerData struct {
// PlayerData is data needed about each connection.
type PlayerData struct {
mutex sync.RWMutex
sessionID []byte
number uint32
Expand All @@ -23,7 +23,7 @@ type playerData struct {
}

// addBlame adds a verification key to the blamedBy map.
func (p *playerData) addBlame(verificationKey string) bool {
func (p *PlayerData) addBlame(verificationKey string) bool {
p.mutex.Lock()
defer p.mutex.Unlock()

Expand Down
24 changes: 12 additions & 12 deletions server/pool.go
Expand Up @@ -15,28 +15,28 @@ const (
type Pool struct {
num int
mutex sync.RWMutex
players map[uint32]*playerData
players map[uint32]*PlayerData
size int
amount uint64
firstBan *playerData
firstBan *PlayerData
version uint64
shuffleType message.ShuffleType
frozenSnapshot map[string]*playerData // vk > player
frozenSnapshot map[string]*PlayerData // vk > player
}

// newPool creates a new pool and enforces the rule that pools only exist
// with at least one player.
func newPool(num int, player *playerData, size int) *Pool {
func newPool(num int, player *PlayerData, size int) *Pool {
pool := &Pool{
num: num,
size: size,
mutex: sync.RWMutex{},
players: make(map[uint32]*playerData),
players: make(map[uint32]*PlayerData),
amount: player.amount,
firstBan: nil,
version: player.version,
shuffleType: player.shuffleType,
frozenSnapshot: make(map[string]*playerData),
frozenSnapshot: make(map[string]*PlayerData),
}
pool.AddPlayer(player)
return pool
Expand All @@ -52,7 +52,7 @@ func (pool *Pool) IsFrozen() bool {

// IsBanned returns true if the player has been banned by their pool.
// This assumes that only one ban will happen per pool.
func (pool *Pool) IsBanned(player *playerData) bool {
func (pool *Pool) IsBanned(player *PlayerData) bool {
pool.mutex.RLock()
defer pool.mutex.RUnlock()

Expand All @@ -69,7 +69,7 @@ func (pool *Pool) PlayerCount() int {
}

// AddPlayer attempts to place player in the pool and returns success boolean
func (pool *Pool) AddPlayer(player *playerData) bool {
func (pool *Pool) AddPlayer(player *PlayerData) bool {
pool.mutex.Lock()
defer pool.mutex.Unlock()

Expand Down Expand Up @@ -110,7 +110,7 @@ func (pool *Pool) AddPlayer(player *playerData) bool {

// RemovePlayer removes a player from the pool
// This method depends on the caller discard the pool if empty.
func (pool *Pool) RemovePlayer(player *playerData) {
func (pool *Pool) RemovePlayer(player *PlayerData) {
pool.mutex.Lock()
defer pool.mutex.Unlock()

Expand All @@ -119,7 +119,7 @@ func (pool *Pool) RemovePlayer(player *playerData) {

// PlayerFromSnapshot returns the user for the key or nil if they
// are not in the snapshot.
func (pool *Pool) PlayerFromSnapshot(verificationKey string) *playerData {
func (pool *Pool) PlayerFromSnapshot(verificationKey string) *PlayerData {
pool.mutex.RLock()
defer pool.mutex.RUnlock()

Expand All @@ -131,8 +131,8 @@ func (pool *Pool) PlayerFromSnapshot(verificationKey string) *playerData {

// takeSnapshot gets a static lookup of all players in the pool
// This method assumes the caller is holding the mutex.
func (pool *Pool) takeSnapshot() map[string]*playerData {
snapshot := make(map[string]*playerData)
func (pool *Pool) takeSnapshot() map[string]*PlayerData {
snapshot := make(map[string]*PlayerData)
for _, p := range pool.players {
snapshot[p.verificationKey] = p
}
Expand Down
6 changes: 3 additions & 3 deletions server/register.go
Expand Up @@ -9,7 +9,7 @@ import (

// registerClient registers a new session.
func (pi *packetInfo) registerClient() error {
var player *playerData
var player *PlayerData
if len(pi.message.Packet) == 1 {
signed := pi.message.Packet[0]

Expand All @@ -25,7 +25,7 @@ func (pi *packetInfo) registerClient() error {
}

if verificationKey != "" && registration != nil {
player = &playerData{
player = &PlayerData{
verificationKey: verificationKey,
conn: pi.conn,
blamedBy: make(map[string]interface{}),
Expand Down Expand Up @@ -54,7 +54,7 @@ func (pi *packetInfo) registerClient() error {
}

// registrationSuccess sends a registration success reply.
func (pi *packetInfo) registrationSuccess(p *playerData) error {
func (pi *packetInfo) registrationSuccess(p *PlayerData) error {
m := message.Signed{
Packet: &message.Packet{
Session: p.sessionID,
Expand Down
10 changes: 5 additions & 5 deletions server/stats_test.go
Expand Up @@ -10,7 +10,7 @@ import (

func TestTrackStats(t *testing.T) {
tracker := &Tracker{
connections: map[net.Conn]*playerData{
connections: map[net.Conn]*PlayerData{
&fakeConn{}: {},
&fakeConn{}: {},
&fakeConn{}: {},
Expand All @@ -24,7 +24,7 @@ func TestTrackStats(t *testing.T) {
pools: map[int]*Pool{
1: {
num: 1,
players: map[uint32]*playerData{
players: map[uint32]*PlayerData{
1: nil,
2: nil,
3: nil,
Expand All @@ -35,7 +35,7 @@ func TestTrackStats(t *testing.T) {
amount: 100,
shuffleType: 0,
version: 0,
frozenSnapshot: map[string]*playerData{
frozenSnapshot: map[string]*PlayerData{
"1": nil,
"2": nil,
"3": nil,
Expand All @@ -45,7 +45,7 @@ func TestTrackStats(t *testing.T) {
},
2: {
num: 2,
players: map[uint32]*playerData{
players: map[uint32]*PlayerData{
6: nil,
7: nil,
8: nil,
Expand All @@ -54,7 +54,7 @@ func TestTrackStats(t *testing.T) {
amount: 1000,
shuffleType: 1,
version: 1,
frozenSnapshot: map[string]*playerData{},
frozenSnapshot: map[string]*PlayerData{},
},
},
poolSize: 5,
Expand Down
22 changes: 13 additions & 9 deletions server/tracker.go
@@ -1,6 +1,7 @@
package server

import (
"fmt"
"net"
"sync"
"time"
Expand Down Expand Up @@ -31,7 +32,7 @@ const (
// Tracker is used to track connections to the server.
type Tracker struct {
banData map[string]*banData
connections map[net.Conn]*playerData
connections map[net.Conn]*PlayerData
verificationKeys map[string]net.Conn
mutex sync.RWMutex
denyIPMatch map[ipPair]time.Time
Expand Down Expand Up @@ -66,7 +67,7 @@ func NewTracker(poolSize int, shufflePort int, shuffleWebSocketPort int, torShuf
return &Tracker{
poolSize: poolSize,
banData: make(map[string]*banData),
connections: make(map[net.Conn]*playerData),
connections: make(map[net.Conn]*PlayerData),
verificationKeys: make(map[string]net.Conn),
denyIPMatch: make(map[ipPair]time.Time),
pools: make(map[int]*Pool),
Expand All @@ -78,7 +79,7 @@ func NewTracker(poolSize int, shufflePort int, shuffleWebSocketPort int, torShuf
}

// add adds a connection to the tracker.
func (t *Tracker) add(p *playerData) {
func (t *Tracker) add(p *PlayerData) {
t.mutex.Lock()
defer t.mutex.Unlock()

Expand Down Expand Up @@ -217,7 +218,7 @@ func (t *Tracker) cleanupBan(ip string) {
}

// playerByVerificationKey gets the player for a verification key.
func (t *Tracker) playerByVerificationKey(key string) *playerData {
func (t *Tracker) playerByVerificationKey(key string) *PlayerData {
t.mutex.RLock()
defer t.mutex.RUnlock()

Expand All @@ -229,7 +230,7 @@ func (t *Tracker) playerByVerificationKey(key string) *playerData {
}

// playerByConnection gets the player for a connection.
func (t *Tracker) playerByConnection(c net.Conn) *playerData {
func (t *Tracker) playerByConnection(c net.Conn) *PlayerData {
t.mutex.RLock()
defer t.mutex.RUnlock()

Expand All @@ -246,7 +247,7 @@ func (t *Tracker) generateSessionID() []byte {

// assignPool assigns a user to a pool.
// This method assumes the caller is holding the mutex.
func (t *Tracker) assignPool(p *playerData) {
func (t *Tracker) assignPool(p *PlayerData) {
pool := t.assignExistingPool(p)
if pool == nil {
t.assignNewPool(p)
Expand All @@ -256,7 +257,7 @@ func (t *Tracker) assignPool(p *playerData) {
// assignExistingPool finds an existing pool and places the player or returns
// nil if there is not an available slot
// This method assumes the caller is holding the mutex.
func (t *Tracker) assignExistingPool(p *playerData) *Pool {
func (t *Tracker) assignExistingPool(p *PlayerData) *Pool {
for _, pool := range t.pools {
if t.deniedByIPMatch(p.conn, pool) {
continue
Expand All @@ -271,7 +272,7 @@ func (t *Tracker) assignExistingPool(p *playerData) *Pool {

// assignNewPool assigns player to the lowest empty pool number >=1
// This method assumes the caller is holding the mutex.
func (t *Tracker) assignNewPool(player *playerData) {
func (t *Tracker) assignNewPool(player *PlayerData) {
num := firstPoolNum
for {
if _, ok := t.pools[num]; !ok {
Expand All @@ -285,13 +286,16 @@ func (t *Tracker) assignNewPool(player *playerData) {

// unassignPool removes a user from a pool.
// This method assumes the caller is holding the mutex.
func (t *Tracker) unassignPool(p *playerData) {
func (t *Tracker) unassignPool(p *PlayerData) {
// A passive player gets ban score and p2p ban because they never
// attempted to announce their verification key,
// are unblameable by other players,
// and probably caused the failure of a shuffle.
if p.isPassive {
t.increaseBanScore(p.conn, true)
if debugMode {
fmt.Printf("[DenyIP] Passive user disconnected: %s\n", p.verificationKey)
}
t.addDenyIPMatch(p.conn, p.pool, true)
}

Expand Down

0 comments on commit 566547a

Please sign in to comment.