Commit 16f93c37 authored by Anders Jensen Løvig's avatar Anders Jensen Løvig
Browse files

Server: Fix tally communication

parent 4d98753c
......@@ -32,6 +32,8 @@ var server struct {
Closed chan bool
Done chan bool
Connections map[string]*network.Conn
}
func init() {
......@@ -40,6 +42,8 @@ func init() {
os.Exit(0)
}
server.Connections = make(map[string]*network.Conn)
server.Mutex = sync.Mutex{}
server.Closed = make(chan bool, 1)
server.Done = make(chan bool, 1)
......@@ -71,10 +75,10 @@ func init() {
required := (servers / 2) + 1
config := &election.Config{
ServerID: election.UniqueID(serialNumber.String()),
Voters: 5,
Voters: 10,
Servers: servers,
RequiredServers: required,
Deadline: time.Now().Add(10 * time.Second),
Deadline: time.Now().Add(30 * time.Second),
CloseCallback: closeCallback,
TallyCallback: tallyCallback,
ResultCallback: resultCallback,
......@@ -108,7 +112,7 @@ var serverHandlers = map[string]network.MessageHandler{
if err != nil {
log.Println("Main: error:", err)
} else {
go server.Election.HandleTally("", &tally)
go server.Election.HandleTally(conn.SerialNumber(), &tally)
}
return nil
},
......@@ -125,7 +129,6 @@ func main() {
if err != nil {
log.Fatal("Main: fatal:", err)
}
log.Println("==================== Collecting ====================")
err = server.Election.Start()
if err != nil {
log.Fatal("Main: fatal:", err)
......@@ -151,6 +154,7 @@ func closeCallback(reason election.Reason) {
log.Println("Main: error:", err)
continue
}
server.Connections[address] = conn
connections++
err = conn.WriteMessage(msgClosed)
......@@ -168,19 +172,17 @@ func closeCallback(reason election.Reason) {
}
func tallyCallback(tally *election.Tally) {
log.Println("===================== Tallying =====================")
server.Election.HandleTally("", tally)
// err := server.Client.Broadcast(network.NewMessage(election.MsgTally, tally))
// if err != nil {
// log.Println("ERROR: " + err.Error())
// }
msgTally := network.NewMessage(election.MsgTally, tally)
// Connect to other servers
for _, conn := range server.Connections {
err := conn.WriteMessage(msgTally)
if err != nil {
log.Println("Main: error:", err)
}
}
}
func resultCallback(result *election.Result) {
log.Println("====================== Result ======================")
if result == nil {
log.Printf("Main: no votes received")
} else {
......
......@@ -98,8 +98,6 @@ func main() {
if err != nil {
log.Println("Main: error: ", err.Error())
}
time.Sleep(1 * time.Second) // Grace period
}
func inputVote() int64 {
......
......@@ -24,9 +24,10 @@ const (
type Reason string
const (
ReasonStarting = "starting election"
ReasonDeadline = "deadline reached"
ReasonVotes = "all votes received"
ReasonAgreement = "majority decided to end election"
ReasonAgreement = "majority agrees"
ReasonTally = "received enough tallies"
)
......@@ -162,7 +163,11 @@ func (election *Election) Start() error {
return errors.New("deadline is in the past")
}
election.Status.Phase = PhaseCollecting
log.Printf("Election: started with parameters:\n Voters: %d\n Servers: %d\n Required: %d\n Deadline %s\n",
election.Participants.Voters, election.Participants.Servers, election.Participants.RequiredServers,
election.Deadline)
election.nextPhase(ReasonStarting)
go func(election *Election) {
time.Sleep(time.Until(election.Deadline))
......@@ -176,16 +181,15 @@ func (election *Election) Start() error {
}
}(election)
log.Printf("Election: started with parameters:\n Voters: %d\n Servers: %d\n Required: %d\n Deadline %s\n",
election.Participants.Voters, election.Participants.Servers, election.Participants.RequiredServers,
election.Deadline)
return nil
}
func (election *Election) nextPhase(reason Reason) {
log.Println("Election: next phase because", reason)
switch election.Status.Phase {
case PhaseNotStarted:
log.Println("==================== Collecting ====================")
election.Status.Phase = PhaseCollecting
case PhaseCollecting:
election.Status.ClosedServers[election.ServerID] = true
election.closeCallback(reason)
......@@ -194,6 +198,7 @@ func (election *Election) nextPhase(reason Reason) {
// Else we have to wait for more servers to close
if len(election.Status.ClosedServers) < election.Participants.RequiredServers {
// Not enough servers to tally.
log.Println("====================== Closed ======================")
election.Status.Phase = PhaseClosed
n := election.Participants.RequiredServers - len(election.Status.ClosedServers)
log.Printf("Election: waiting for %d more servers to close\n", n)
......@@ -204,13 +209,22 @@ func (election *Election) nextPhase(reason Reason) {
case PhaseClosed:
// If the ballot box is empty we can go directly to result
if election.ballotBox.Size() != 0 {
log.Println("===================== Tallying =====================")
election.Status.Phase = PhaseTallying
tally := election.ballotBox.Tally()
election.Status.TalliedServers[election.ServerID] = true
err := election.tallyBox.Put(tally)
if err != nil {
panic(err) // This should never happen
}
election.tallyCallback(tally)
break
}
fallthrough
case PhaseTallying:
log.Println("====================== Result ======================")
election.Status.Phase = PhaseResult
result := election.createResults()
election.resultCallback(result)
......
......@@ -7,7 +7,6 @@ import (
"errors"
"fmt"
"log"
"net"
"sync"
"time"
)
......@@ -31,7 +30,7 @@ type Client struct {
// The boolean value indicates if the connection is closing. When all
// go-rountines associated with a connection has terminated the connection
// will be removed from connections.
connections map[net.Conn]bool
connections map[*Conn]bool
mutex sync.Mutex
config *Config
......@@ -43,7 +42,7 @@ func NewClient(config *Config) *Client {
tlsConfig := createClientConfig(config.RootPath, config.CertPath, config.KeyPath)
logName = "Client"
return &Client{
connections: make(map[net.Conn]bool),
connections: make(map[*Conn]bool),
mutex: sync.Mutex{},
config: config,
tlsConfig: tlsConfig,
......
......@@ -88,7 +88,7 @@ func createRootPool(rootPath string) *x509.CertPool {
func loadPEM(path string) []byte {
pem, err := ioutil.ReadFile(path)
if err != nil {
log.Fatal("fatal:", err)
log.Fatal("fatal: ", err)
}
return pem
}
......@@ -96,7 +96,7 @@ func loadPEM(path string) []byte {
func loadKeyPair(certPath, keyPath string) tls.Certificate {
crt, err := tls.LoadX509KeyPair(certPath, keyPath)
if err != nil {
log.Fatal("fatal: Failed to load server certificate and key:", err)
log.Fatal("fatal:", err)
}
return crt
}
......
......@@ -23,8 +23,7 @@ type Server struct {
/// Status of each connection.
// If true, then the connection is active na dif false,
// then the connection is closing.
connections map[net.Conn]bool
connections map[*Conn]bool
// The connection listener
listener net.Listener
......@@ -43,7 +42,7 @@ func NewServer(config *Config) *Server {
logName = "Server"
return &Server{
Client: Client{
connections: make(map[net.Conn]bool),
connections: make(map[*Conn]bool),
mutex: sync.Mutex{},
config: config,
tlsConfig: tlsConfig,
......@@ -55,7 +54,7 @@ func NewServer(config *Config) *Server {
MaxConstraintComparisions: 0,
},
},
connections: make(map[net.Conn]bool),
connections: make(map[*Conn]bool),
mutex: sync.Mutex{},
closing: false,
config: config,
......
#!/bin/bash
total=0
for i in $(seq 1 $1)
do
echo $i
r=$(($RANDOM % 2)); echo Voting $r
for i in config/cert/client/*.crt; do
[ -f "$i" ] || break
name=$(echo "$i" | cut -f 1 -d '.')
r=$(($RANDOM % 2))
total=$(($total + $r))
go run cmd/vote/main.go -v $r
echo $name: $r
go run cmd/vote/main.go -v $r --cert $name.crt --key $name.key
done
echo Total: $total
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment