// Handle switch connected event func (self *OFSwitch) switchConnected() { self.app.SwitchConnected(self) // Send new feature request self.Send(openflow13.NewFeaturesRequest()) // FIXME: This is too fragile. Create a periodic timer // Start the periodic echo request loop self.Send(openflow13.NewEchoRequest()) }
// Handle TCP connection from the switch func (c *Controller) handleConnection(conn net.Conn) { stream := util.NewMessageStream(conn, c) log.Println("New connection..") // Send ofp 1.3 Hello by default h, err := common.NewHello(4) if err != nil { return } stream.Outbound <- h for { select { // Send hello message with latest protocol version. case msg := <-stream.Inbound: switch m := msg.(type) { // A Hello message of the appropriate type // completes version negotiation. If version // types are incompatable, it is possible the // connection may be servered without error. case *common.Hello: if m.Version == openflow13.VERSION { log.Infoln("Received Openflow 1.3 Hello message") // Version negotiation is // considered complete. Create // new Switch and notifiy listening // applications. stream.Version = m.Version stream.Outbound <- openflow13.NewFeaturesRequest() } else { // Connection should be severed if controller // doesn't support switch version. log.Println("Received unsupported ofp version", m.Version) stream.Shutdown <- true } // After a vaild FeaturesReply has been received we // have all the information we need. Create a new // switch object and notify applications. case *openflow13.SwitchFeatures: log.Printf("Received ofp1.3 Switch feature response: %+v", *m) // Create a new switch and handover the stream NewSwitch(stream, m.DPID, c.app) // Let switch instance handle all future messages.. return // An error message may indicate a version mismatch. We // disconnect if an error occurs this early. case *openflow13.ErrorMsg: log.Warnf("Received ofp1.3 error msg: %+v", *m) stream.Shutdown <- true } case err := <-stream.Error: // The connection has been shutdown. log.Println(err) return case <-time.After(time.Second * 3): // This shouldn't happen. If it does, both the controller // and switch are no longer communicating. The TCPConn is // still established though. log.Warnln("Connection timed out.") return } } }