|  | @@ -19,12 +19,13 @@ import (
 | 
	
		
			
				|  |  |  	"os"
 | 
	
		
			
				|  |  |  	"sync"
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	"github.com/campoy/whispering-gophers/util"
 | 
	
		
			
				|  |  | +	"code.osinet.fr/fgm/whispering_gophers/util"
 | 
	
		
			
				|  |  |  )
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  var (
 | 
	
		
			
				|  |  | -	peerAddr = flag.String("peer", "", "peer host:port")
 | 
	
		
			
				|  |  | -	self     string
 | 
	
		
			
				|  |  | +	listenAddr = flag.String("listen", "", "peer host:port")
 | 
	
		
			
				|  |  | +	peerAddr   = flag.String("peer", "", "peer host:port")
 | 
	
		
			
				|  |  | +	self       string
 | 
	
		
			
				|  |  |  )
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  type Message struct {
 | 
	
	
		
			
				|  | @@ -35,7 +36,14 @@ type Message struct {
 | 
	
		
			
				|  |  |  func main() {
 | 
	
		
			
				|  |  |  	flag.Parse()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	l, err := util.Listen()
 | 
	
		
			
				|  |  | +	var l net.Listener
 | 
	
		
			
				|  |  | +	var err error
 | 
	
		
			
				|  |  | +	// Create a new listener using util.Listen and put it in a variable named l.
 | 
	
		
			
				|  |  | +	if *listenAddr == "" {
 | 
	
		
			
				|  |  | +		l, err = util.ListenOnFirstUsableInterface()
 | 
	
		
			
				|  |  | +	} else {
 | 
	
		
			
				|  |  | +		l, err = net.Listen("tcp4", *listenAddr)
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  |  	if err != nil {
 | 
	
		
			
				|  |  |  		log.Fatal(err)
 | 
	
		
			
				|  |  |  	}
 | 
	
	
		
			
				|  | @@ -54,13 +62,16 @@ func main() {
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -// TODO: create a global shared Peers instance
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +// Create a global shared Peers instance
 | 
	
		
			
				|  |  |  type Peers struct {
 | 
	
		
			
				|  |  |  	m  map[string]chan<- Message
 | 
	
		
			
				|  |  |  	mu sync.RWMutex
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +var peers = Peers{
 | 
	
		
			
				|  |  | +	m: make(map[string]chan<- Message),
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  // Add creates and returns a new channel for the given peer address.
 | 
	
		
			
				|  |  |  // If an address already exists in the registry, it returns nil.
 | 
	
		
			
				|  |  |  func (p *Peers) Add(addr string) <-chan Message {
 | 
	
	
		
			
				|  | @@ -93,9 +104,15 @@ func (p *Peers) List() []chan<- Message {
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func broadcast(m Message) {
 | 
	
		
			
				|  |  | -	for /* TODO: Range over the list of peers */ {
 | 
	
		
			
				|  |  | -		// TODO: Send a message to the channel, but don't block.
 | 
	
		
			
				|  |  | +	/* Range over the list of peers */
 | 
	
		
			
				|  |  | +	for i, peer := range peers.List() {
 | 
	
		
			
				|  |  | +		// Send a message to the channel, but don't block.
 | 
	
		
			
				|  |  |  		// Hint: Select is your friend.
 | 
	
		
			
				|  |  | +		select {
 | 
	
		
			
				|  |  | +		case peer <- m:
 | 
	
		
			
				|  |  | +		default:
 | 
	
		
			
				|  |  | +			log.Printf("Sending to peer %d would have blocked.\n", i)
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -110,8 +127,8 @@ func serve(c net.Conn) {
 | 
	
		
			
				|  |  |  			return
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -		// TODO: Launch dial in a new goroutine, to connect to the address in the message's Addr field.
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +		// Launch dial in a new goroutine, to connect to the address in the message's Addr field.
 | 
	
		
			
				|  |  | +		go dial(m.Addr)
 | 
	
		
			
				|  |  |  		fmt.Printf("%#v\n", m)
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -128,15 +145,24 @@ func readInput() {
 | 
	
		
			
				|  |  |  	if err := s.Err(); err != nil {
 | 
	
		
			
				|  |  |  		log.Fatal(err)
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | +	os.Exit(0)
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func dial(addr string) {
 | 
	
		
			
				|  |  | -	// TODO: If dialing self, return.
 | 
	
		
			
				|  |  | +	// If dialing self, return.
 | 
	
		
			
				|  |  | +	if addr == self {
 | 
	
		
			
				|  |  | +		return
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// Add the address to the peers map.
 | 
	
		
			
				|  |  | +	ch := peers.Add(addr)
 | 
	
		
			
				|  |  | +	// If you get a nil channel the peer is already connected, return.
 | 
	
		
			
				|  |  | +	if ch == nil {
 | 
	
		
			
				|  |  | +		return
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	// TODO: Add the address to the peers map.
 | 
	
		
			
				|  |  | -	// TODO: If you get a nil channel the peer is already connected, return.
 | 
	
		
			
				|  |  | -	// TODO: Remove the address from peers map when this function returns
 | 
	
		
			
				|  |  | -	//       (use defer).
 | 
	
		
			
				|  |  | +	// Remove the address from peers map when this function returns
 | 
	
		
			
				|  |  | +	defer peers.Remove(addr)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	c, err := net.Dial("tcp", addr)
 | 
	
		
			
				|  |  |  	if err != nil {
 |