diff --git a/peer/config.json b/peer/config.json index 28771f9..ffef812 100755 --- a/peer/config.json +++ b/peer/config.json @@ -1,6 +1,8 @@ { "ip": "127.0.0.1", - "port": "3001", + "port": "3007", + "restip": "127.0.0.1", + "restport": "3008", "serverip": "127.0.0.1", "serverport": "3000" } diff --git a/peer/connections.go b/peer/connections.go index 5c7dcf4..d9b5137 100644 --- a/peer/connections.go +++ b/peer/connections.go @@ -24,8 +24,16 @@ func acceptPeers(peer Peer) { newPeer.IP = getIPFromConn(conn) newPeer.Port = getPortFromConn(conn) newPeer.Conn = conn + /* + //ask to the peer, for the peer ID + resp, err := http.Get("http://" + newPeer.IP + ":" + newPeer.Port) + check(err) + color.Red("-----") + fmt.Println(resp) + //newPeer.ID = resp + */ peersList.Peers = append(peersList.Peers, newPeer) - go handleConn(conn) + go handleConn(conn, newPeer) } } func connectToPeer(peer Peer) { @@ -36,9 +44,9 @@ func connectToPeer(peer Peer) { } peer.Conn = conn peersList.Peers = append(peersList.Peers, peer) - go handleConn(conn) + go handleConn(conn, peer) } -func handleConn(conn net.Conn) { +func handleConn(conn net.Conn, connPeer Peer) { connRunning := true log.Println("handling conn: " + conn.RemoteAddr().String()) //reply to the conn, send the peerList @@ -66,10 +74,11 @@ func handleConn(conn net.Conn) { //color.Blue(string(buffer[0:bytesRead])) //msg = msg.createFromBytes([]byte(string(buffer[0:bytesRead]))) msg = msg.createFromBytes([]byte(newmsg)) - messageHandler(conn, msg) + messageHandler(connPeer, msg) } } //TODO add that if the peer closed is the p2p server, show a warning message at the peer log.Println("Peer: " + conn.RemoteAddr().String() + " connection closed") conn.Close() + //TODO delete the peer from the peersList } diff --git a/peer/main.go b/peer/main.go index 6390224..0fd503e 100644 --- a/peer/main.go +++ b/peer/main.go @@ -12,7 +12,7 @@ import ( ) type Peer struct { - ID string `json:"id"` + ID string `json:"id"` //in the future, this will be the peer hash IP string `json:"ip"` Port string `json:"port"` Role string `json:"role"` //client or server @@ -21,39 +21,42 @@ type Peer struct { var running bool var thisPeerID string +var runningPeer Peer func main() { //initialize some vars rand.Seed(time.Now().Unix()) running = true - var peer Peer color.Blue("Starting Peer") + //read configuration file readConfig("config.json") - peer.ID = strconv.Itoa(randInt(1, 1000)) //0 is reserved for server - peer.IP = config.IP - peer.Port = config.Port - peer.Role = "client" + runningPeer.ID = strconv.Itoa(randInt(1, 1000)) //0 is reserved for server + runningPeer.IP = config.IP + runningPeer.Port = config.Port + runningPeer.Role = "client" + + go runRestServer() //read flags, to know if is runned as p2p server if len(os.Args) > 1 { if os.Args[1] == "server" { color.Yellow("Running as p2p server") - peer.Role = "server" - peer.Port = config.ServerPort - peer.ID = "0" + runningPeer.Role = "server" + runningPeer.Port = config.ServerPort + runningPeer.ID = "0" } } - thisPeerID = peer.ID - peersList.PeerID = peer.ID - fmt.Println(peer) - peersList.Peers = append(peersList.Peers, peer) + thisPeerID = runningPeer.ID + peersList.PeerID = runningPeer.ID + fmt.Println(runningPeer) + peersList.Peers = append(peersList.Peers, runningPeer) fmt.Println(peersList) - if peer.Role == "server" { - go acceptPeers(peer) + if runningPeer.Role == "server" { + go acceptPeers(runningPeer) } - if peer.Role == "client" { + if runningPeer.Role == "client" { var newPeer Peer newPeer.IP = config.ServerIP newPeer.Port = config.ServerPort diff --git a/peer/messages.go b/peer/messages.go index eaf35ed..1c129ce 100644 --- a/peer/messages.go +++ b/peer/messages.go @@ -4,7 +4,6 @@ import ( "encoding/json" "fmt" "log" - "net" "time" "github.com/fatih/color" @@ -17,7 +16,7 @@ type Msg struct { PeersList PeersList `json:"peerslist"` } -func messageHandler(conn net.Conn, msg Msg) { +func messageHandler(peer Peer, msg Msg) { log.Println("[New msg]") log.Println(msg) @@ -31,10 +30,33 @@ func messageHandler(conn net.Conn, msg Msg) { color.Blue("newPeerslist") fmt.Println(msg.PeersList) - time.Sleep(1000 * time.Millisecond) - updatePeersList(conn, msg.PeersList) - propagatePeersList() + //time.Sleep(1000 * time.Millisecond) + updatePeersList(peer.Conn, msg.PeersList) + propagatePeersList(peer) printPeersList() + break + case "PeersList_Response": + color.Blue("newPeerslist") + fmt.Println(msg.PeersList) + + //time.Sleep(1000 * time.Millisecond) + updatePeersList(peer.Conn, msg.PeersList) + printPeersList() + break + case "MyID": + color.Blue("MyID") + fmt.Println(msg.Content) + color.Green(peer.Conn.RemoteAddr().String()) + peer.ID = msg.Content + searchPeerAndUpdate(peer) + + //time.Sleep(1000 * time.Millisecond) + /* + updatePeersList(peer.Conn, msg.PeersList) + propagatePeersList(peer) + */ + printPeersList() + break default: log.Println("Msg.Type not supported") break diff --git a/peer/peersList.go b/peer/peersList.go index c955ee1..6bb836c 100644 --- a/peer/peersList.go +++ b/peer/peersList.go @@ -30,6 +30,7 @@ func updatePeersList(conn net.Conn, newPeersList PeersList) { for _, peer := range newPeersList.Peers { if getIPPortFromConn(conn) == peer.IP+":"+peer.Port { peer.ID = newPeersList.PeerID + color.Yellow(peer.ID) } i := peerIsInPeersList(peer, peersList.Peers) if i == -1 { @@ -40,23 +41,50 @@ func updatePeersList(conn net.Conn, newPeersList PeersList) { } } } +func searchPeerAndUpdate(p Peer) { + for _, peer := range peersList.Peers { + color.Red(p.IP + ":" + p.Port) + color.Yellow(peer.IP + ":" + peer.Port) + if p.IP+":"+p.Port == peer.IP+":"+peer.Port { + peer.ID = p.ID + } + } +} //send the peersList to all the peers except the peer that has send the peersList -func propagatePeersList() { +func propagatePeersList(p Peer) { for _, peer := range peersList.Peers { if peer.Conn != nil { - var msg Msg - msg = msg.construct("PeersList", "here my peersList", peersList) - msgB := msg.toBytes() - _, err := peer.Conn.Write(msgB) - check(err) + if peer.ID != p.ID && p.ID != "" { + color.Yellow(peer.ID + " - " + p.ID) + var msg Msg + msg = msg.construct("PeersList", "here my peersList", peersList) + msgB := msg.toBytes() + _, err := peer.Conn.Write(msgB) + check(err) + } else { + //to the peer that has sent the peerList, we send our ID + /* + var msg Msg + var pl PeersList + msg = msg.construct("MyID", runningPeer.ID, pl) + msgB := msg.toBytes() + _, err := p.Conn.Write(msgB) + check(err) + */ + var msg Msg + msg = msg.construct("PeersList_Response", "here my peersList", peersList) + msgB := msg.toBytes() + _, err := peer.Conn.Write(msgB) + check(err) + } } } } func printPeersList() { fmt.Println("") color.Green("PEERSLIST:") - color.Green("thisPeerId: " + thisPeerID) + color.Green("runningPeer.ID: " + runningPeer.ID) for _, peer := range peersList.Peers { fmt.Println(peer) } diff --git a/peer/readConfig.go b/peer/readConfig.go index 0fdaf99..aeec87a 100755 --- a/peer/readConfig.go +++ b/peer/readConfig.go @@ -9,6 +9,8 @@ import ( type Config struct { IP string `json:"ip"` Port string `json:"port"` + RestIP string `json:"restip"` + RestPort string `json:"restport"` ServerIP string `json:"serverip"` ServerPort string `json:"serverport"` } diff --git a/peer/restServer.go b/peer/restServer.go new file mode 100644 index 0000000..dc171b6 --- /dev/null +++ b/peer/restServer.go @@ -0,0 +1,20 @@ +package main + +import ( + "log" + "net/http" + + "github.com/gorilla/handlers" +) + +func runRestServer() { + //run API + log.Println("server running") + log.Print("port: ") + log.Println(config.RestPort) + router := NewRouter() + headersOk := handlers.AllowedHeaders([]string{"X-Requested-With", "Access-Control-Allow-Origin"}) + originsOk := handlers.AllowedOrigins([]string{"*"}) + methodsOk := handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "OPTIONS"}) + log.Fatal(http.ListenAndServe(":"+config.RestPort, handlers.CORS(originsOk, headersOk, methodsOk)(router))) +} diff --git a/peer/restServerConfig.go b/peer/restServerConfig.go new file mode 100755 index 0000000..36a332e --- /dev/null +++ b/peer/restServerConfig.go @@ -0,0 +1,47 @@ +package main + +import ( + "log" + "net/http" + "time" + + "github.com/gorilla/mux" +) + +type Route struct { + Name string + Method string + Pattern string + HandlerFunc http.HandlerFunc +} + +func Logger(inner http.Handler, name string) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + start := time.Now() + + inner.ServeHTTP(w, r) + + log.Printf( + "%s\t%s\t%s\t%s", + r.Method, + r.RequestURI, + name, + time.Since(start), + ) + }) +} +func NewRouter() *mux.Router { + router := mux.NewRouter().StrictSlash(true) + for _, route := range routes { + var handler http.Handler + handler = route.HandlerFunc + handler = Logger(handler, route.Name) + + router. + Methods(route.Method). + Path(route.Pattern). + Name(route.Name). + Handler(handler) + } + return router +} diff --git a/peer/restServerRoutes.go b/peer/restServerRoutes.go new file mode 100755 index 0000000..afcd23f --- /dev/null +++ b/peer/restServerRoutes.go @@ -0,0 +1,22 @@ +package main + +import ( + "fmt" + "net/http" +) + +type Routes []Route + +var routes = Routes{ + Route{ + "Index", + "GET", + "/", + Index, + }, +} + +func Index(w http.ResponseWriter, r *http.Request) { + //ipFilter(w, r) + fmt.Fprintln(w, runningPeer.ID) +}