github.com/DARA-Project/GoDist-Scheduler@v0.0.0-20201030134746-668de4acea0d/examples/broadcastUDPHashRandom_test/broadcastUDPHashRandom.go (about) 1 package main 2 3 /* This example program tests Dara's ability to reliably replay a 4 * system with mulitple nodes communicating via UDP. The number of 5 * nodes in the system is set by the enviornment variable 6 * DARATESETPEERS. After beginning each peer resolves the UDP addresses 7 * and saves an MD5 Hash of its ID. 8 9 The algorithm for this program is thus. 10 11 1) Each node broadcasts its current MD5 hash starting at a RANDOM peer address 12 2) Each node waits to recieve a single hash 13 3) Upon recipt a nodes current hash = M55( hash + receivedHash) 14 4) Print the current hash + size 15 16 This algorithm has the advantage that any nondeterminism in the nodes 17 will cause the hashes that they compute to differ immidiatly, thereby 18 making the ouput of the program sensitive to every nondeterminisic 19 action. 20 21 This program is nondermanistic in the following ways 22 23 1) The order in which messages are placed on the network by any node. 24 2) The order in which messagesa are received from the network by all nodes. 25 3) The order in which each node sends it's messages 26 4) The order in which nodes process their messages. This refers to the 27 global order of all events. 28 29 */ 30 31 import ( 32 "fmt" 33 "os" 34 "net" 35 "log" 36 "strconv" 37 "crypto/md5" 38 "time" 39 "math/rand" 40 ) 41 42 const ( 43 BROADCASTS = 50 44 BUFSIZE = md5.Size 45 ) 46 47 var ( 48 logger *log.Logger 49 DaraPID int 50 DaraTestPeers int 51 conn *net.UDPConn 52 hash string 53 r *rand.Rand 54 ) 55 56 func main() { 57 logger = log.New(os.Stdout, "[INITALIZING]",log.Lshortfile) 58 ParseEnviornment() 59 SetupUDPNetworkConnections() 60 defer conn.Close() 61 logger.SetPrefix(fmt.Sprintf("[Peer %d] ",DaraPID)) 62 logger.Printf("DaraPID: %d\tDaraTestPeers:%d\n",DaraPID,DaraTestPeers) 63 64 65 rand.Seed(int64(time.Now().Nanosecond())) 66 r = rand.New(rand.NewSource(int64(time.Now().Nanosecond()))) 67 68 hashf := md5.New() 69 hash = string(hashf.Sum([]byte(fmt.Sprintf("%d",DaraPID)))) 70 logger.Printf("Hash:%x\n",hash) 71 72 time.Sleep(time.Second) 73 //Write 74 for i:= 0;i<BROADCASTS;i++ { 75 broadcast(hash) 76 newhash := readhashmsg() 77 hash = string(hashf.Sum([]byte(hash+newhash))) 78 } 79 } 80 81 func broadcast(h string) { 82 peerstart := (r.Int() % (DaraTestPeers+1)) 83 if peerstart == 0 { 84 peerstart = 1 85 } 86 var counter = 1 87 for i:=peerstart;counter<=DaraTestPeers;counter++{ 88 logger.Printf("BROADCASTING %d Peerstart %d\n",i,peerstart) 89 if i == DaraPID { 90 i = (i + 1) % (DaraTestPeers+1) 91 if i == 0 { 92 i=1 93 } 94 continue 95 } else { 96 peerAddrString := fmt.Sprintf(":666%d",i) 97 peerAddr, err := net.ResolveUDPAddr("udp",peerAddrString) 98 if err != nil { 99 logger.Panicf("Unable to resolve peer %s: %s",peerAddrString,err) 100 } 101 n, err := conn.WriteToUDP([]byte(h),peerAddr) 102 if err != nil { 103 logger.Panicf("Unable to write msg to peer %s",peerAddr.String()) 104 } 105 logger.Printf("Writing: %x\t To: %s\t Len: %d\t",h,peerAddr.String(),n) 106 i = (i + 1) % (DaraTestPeers+1) 107 if i == 0 { 108 i=1 109 } 110 } 111 time.Sleep(time.Millisecond) 112 } 113 } 114 115 func readhashmsg() string { 116 buf := make([]byte,BUFSIZE) 117 n, addr, err := conn.ReadFromUDP(buf) 118 if err != nil { 119 logger.Panicf("Error reading from udp %s",err.Error()) 120 } 121 logger.Printf("Received: %x From %s Len %d",buf[:n],addr.String(),n) 122 return string(buf) 123 } 124 125 func ParseEnviornment() { 126 var err error 127 DaraPIDString := os.Getenv("DARAPID") 128 if DaraPIDString == "" { 129 logger.Fatalf("DARAPID not set!") 130 } 131 DaraPID, err = strconv.Atoi(DaraPIDString) 132 if err != nil { 133 logger.Fatalf("DARAPID not a valid integer %s: %s",DaraPIDString,err.Error()) 134 } 135 136 DaraTESTPEERSString := os.Getenv("DARATESTPEERS") 137 if DaraTESTPEERSString == "" { 138 logger.Fatalf("DARATESTPEERS not set!") 139 } 140 DaraTestPeers, err = strconv.Atoi(DaraTESTPEERSString) 141 if err != nil { 142 logger.Fatalf("DARATESTPEERS not a valid integer %s: %s",DaraTESTPEERSString,err.Error()) 143 } 144 logger.Println("Done Parsing Enviornment") 145 return 146 } 147 148 func SetupUDPNetworkConnections() { 149 addrstring := fmt.Sprintf(":666%d",DaraPID) 150 addr, err := net.ResolveUDPAddr("udp",addrstring) 151 if err != nil { 152 logger.Fatal(err) 153 } 154 conn, err = net.ListenUDP("udp",addr) 155 if err != nil { 156 logger.Fatal(err) 157 } 158 logger.Println("Done Setting Up Network Connections") 159 } 160 161 162 163