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