Advertisement
Guest User

Untitled

a guest
Jun 22nd, 2017
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.61 KB | None | 0 0
  1. import (
  2.         "fmt"
  3.         "time"
  4.         "sync"
  5.         "rand"
  6. )
  7.  
  8. type Address struct {
  9.         IP   string
  10.         port int16
  11. }
  12.  
  13. func (addr Address) String() string {
  14.         return addr.IP + ":" + fmt.Sprintf("%d", addr.port)
  15. }
  16.  
  17. type Type int8
  18.  
  19. const (
  20.         CALL  Type = 0
  21.         REPLY Type = 1
  22.         ACK   Type = 2
  23.         NACK  Type = 3
  24. )
  25.  
  26. var DefaultAddr Address
  27.  
  28. var ACKPacket *Packet = &Packet{DefaultAddr, DefaultAddr, 1, ACK, 10, ""}
  29. var NACKPacket *Packet = &Packet{DefaultAddr, DefaultAddr, 1, NACK, 10, ""}
  30.  
  31. type Packet struct {
  32.         SRC Address
  33.         DST Address
  34.         TTL int16
  35.         Type
  36.         Size int64
  37.         Data string
  38. }
  39.  
  40. type Channel struct {
  41.         IN          chan Packet
  42.         OUT         chan Packet
  43.         State       chan bool
  44.         UP          bool
  45.         onWire      int64
  46.         onWireLock  sync.RWMutex
  47.         Bandwidth   int64
  48.         Delay       int64
  49.         Reliability float
  50. }
  51. type Link struct {
  52.         UP *Channel
  53.         DOWN Channel
  54. }
  55. type Links []Link                                                                                                                                  
  56.  
  57. type Route struct {
  58.         DST            *Address
  59.         NextHop        *Channel
  60.         TotDelay       int64
  61.         TotBandwidth   int64
  62.         TotReliability float
  63.         Hops           int
  64. }
  65. type Routes []Route
  66. type RoutingTable map[string]Routes
  67.  
  68. type Router struct {
  69.         Links
  70.         RoutingTable
  71. }
  72.  
  73.  
  74.  
  75. /*
  76.     (Channel) pkt
  77.     --> OUT -->
  78.     --> OUT -->
  79.     --> OUT --> PacketReceiver
  80.                 --> Routing()
  81.                         -->
  82.                         -->
  83.                         --> IN --> PacketSender --> OUT
  84.                         -->
  85.                         -->
  86. */
  87. func (ch *Channel) PacketSender() {
  88.         // send packet to OUT chan
  89.         send := func(pkt Packet) {
  90.                 // random packet loss (reliability based)
  91.                 if ch.Reliability < rand.Float() {
  92.                         return
  93.                 }      
  94.                
  95.                 // if link failed, reset onWire and don't send anything
  96.                 if ch.UP == false {
  97.                         ch.onWireLock.Lock()
  98.                         ch.onWire = 0
  99.                         ch.onWireLock.Unlock()
  100.                         return
  101.                 }      
  102.                
  103.                 // increase OnWire
  104.                 ch.onWireLock.Lock()
  105.                 ch.onWire += pkt.Size
  106.                 ch.onWireLock.Unlock()
  107.                
  108.                 // packet on wire for Delay nanoseconds
  109.                 time.Sleep(ch.Delay)
  110.                
  111.                 // wait for other end to accept it
  112.                 ch.OUT <- pkt
  113.                
  114.                 // decrease OnWire
  115.                 ch.onWireLock.Lock()
  116.                 ch.onWire -= pkt.Size
  117.                 ch.onWireLock.Unlock()
  118.         }      
  119.         check := func(size int64) bool {
  120.                 ch.onWireLock.RLock()
  121.                 defer ch.onWireLock.RUnlock()
  122.                
  123.                 // enough bandwidth to send?
  124.                 if ch.onWire+size <= ch.Bandwidth {
  125.                         return true
  126.                 }
  127.                 return false
  128.         }
  129.         go func() {
  130.                 for {  
  131.                         select {
  132.                         case pkt := <-ch.IN:
  133.                                 // wait until enough bandwidth
  134.                                 for {  
  135.                                         if check(pkt.Size) {
  136.                                                 break
  137.                                         }
  138.                                         // retry in 1ms
  139.                                         time.Sleep(1e6)
  140.                                 }
  141.                                 go send(pkt)
  142.                         case s := <-ch.State:
  143.                                 // link failed, stop accepting packets
  144.                                 if !s {
  145.                                         ch.UP = false
  146.                                         return
  147.                                 }
  148.                         }
  149.  
  150.                 }
  151.         }()
  152. }
  153. func (ch *Channel) PacketReceiver(routing chan *Packet) {
  154.         go func() {
  155.                 for {
  156.                         pkt := <-ch.OUT
  157.                         if ch.UP == false {
  158.                                 return
  159.                         }
  160.                         routing <- &pkt
  161.                 }
  162.         }()
  163. }
  164.  
  165. type Node struct {
  166.     Address
  167.     Link
  168. }
  169.  
  170. func (n *Node) Start(peers []*Node) chan bool {
  171.     quit1 := make(chan bool)
  172.     quit2 := make(chan bool)
  173.     sink  := make(chan *Packet)
  174.  
  175.     sinker := func() {
  176.         for {      
  177.             select {
  178.                 case <-quit1:
  179.                     quit2 <- true
  180.                     return
  181.                 case pkt := <-sink:
  182.                     fmt.Println(n.Address.String() + " | <- " + pkt.Data)
  183.             }
  184.         }
  185.     }
  186.     generator := func() {
  187.         ticker := time.NewTicker(1e9)
  188.         for {      
  189.             select {
  190.                 case <- quit2:
  191.                     return
  192.                 case <-ticker.C:
  193.                     if rand.Float() > 0.3 {
  194.                         i := rand.Intn(len(peers) - 1)
  195.                         pkt := new(Packet)
  196.                         pkt.SRC = n.Address
  197.                         pkt.DST = peers[i].Address
  198.                         pkt.Type = CALL
  199.                         pkt.TTL = 64
  200.                         pkt.Size = 16
  201.                         pkt.Data = "PING"
  202.  
  203.                         n.Link.UP.IN <- pkt
  204.                     }
  205.             }
  206.         }
  207.     }
  208.     go n.Link.UP.PacketSender()
  209.     go n.Link.DOWN.PacketReceiver(sink)
  210.     go sinker()
  211.     go generator()
  212.  
  213.     return quit1
  214. }
  215.  
  216. func mkChannel(bandwidth int64, delay int64, reliability float) Channel {
  217.     var ch Channel
  218.     ch.IN = make(chan Packet)
  219.     ch.OUT = make(chan Packet)
  220.     ch.State = make(chan bool)
  221.     ch.onWire = 0
  222.     ch.Bandwidth = bandwidth
  223.     ch.Delay = delay
  224.     ch.Reliability = reliability
  225.     ch.UP = true
  226.  
  227.     return ch
  228. }
  229.  
  230. func mkLink(up *Channel, down Channel) Link {
  231.     var link Link
  232.     link.UP = up
  233.     link.DOWN = down
  234.  
  235.     return link
  236. }
  237.  
  238. func main() {
  239.     tx := mkChannel(1e9, 2e9, 0.50)
  240.     rx := mkChannel(1e9, 1e9, 0.45)
  241.  
  242.     link1 := mkLink(&tx, rx)
  243.     link2 := mkLink(&rx, tx)
  244.  
  245.     n1 := Node(Address("127.0.0.1", 1000), link1)
  246.     n2 := Node(Address("127.0.0.1", 1001), link2)
  247.  
  248.     n1.Start()
  249.     n2.Start()
  250.  
  251.     time.Sleep(60 * 1e9)
  252. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement