func getConnackMessage(conn io.Closer) (*message.ConnackMessage, error) { buf, err := getMessageBuffer(conn) if err != nil { //glog.Debugf("Receive error: %v", err) return nil, err } msg := message.NewConnackMessage() _, err = msg.Decode(buf) //glog.Debugf("Received: %s", msg) return msg, err }
// HandleConnection is for the broker to handle an incoming connection from a client func (this *Server) handleConnection(c io.Closer) (svc *service, err error) { if c == nil { return nil, ErrInvalidConnectionType } defer func() { if err != nil { c.Close() } }() err = this.checkConfiguration() if err != nil { return nil, err } conn, ok := c.(net.Conn) if !ok { return nil, ErrInvalidConnectionType } // To establish a connection, we must // 1. Read and decode the message.ConnectMessage from the wire // 2. If no decoding errors, then authenticate using username and password. // Otherwise, write out to the wire message.ConnackMessage with // appropriate error. // 3. If authentication is successful, then either create a new session or // retrieve existing session // 4. Write out to the wire a successful message.ConnackMessage message // Read the CONNECT message from the wire, if error, then check to see if it's // a CONNACK error. If it's CONNACK error, send the proper CONNACK error back // to client. Exit regardless of error type. conn.SetReadDeadline(time.Now().Add(time.Second * time.Duration(this.ConnectTimeout))) resp := message.NewConnackMessage() req, err := getConnectMessage(conn) if err != nil { if cerr, ok := err.(message.ConnackCode); ok { //glog.Debugf("request message: %s\nresponse message: %s\nerror : %v", mreq, resp, err) resp.SetReturnCode(cerr) resp.SetSessionPresent(false) writeMessage(conn, resp) } return nil, err } // Authenticate the user, if error, return error and exit if err = this.authMgr.Authenticate(string(req.Username()), string(req.Password())); err != nil { resp.SetReturnCode(message.ErrBadUsernameOrPassword) resp.SetSessionPresent(false) writeMessage(conn, resp) return nil, err } if req.KeepAlive() == 0 { req.SetKeepAlive(minKeepAlive) } svc = &service{ id: atomic.AddUint64(&gsvcid, 1), client: false, keepAlive: int(req.KeepAlive()), connectTimeout: this.ConnectTimeout, ackTimeout: this.AckTimeout, timeoutRetries: this.TimeoutRetries, conn: conn, sessMgr: this.sessMgr, topicsMgr: this.topicsMgr, } err = this.getSession(svc, req, resp) if err != nil { return nil, err } resp.SetReturnCode(message.ConnectionAccepted) if err = writeMessage(c, resp); err != nil { return nil, err } svc.inStat.increment(int64(req.Len())) svc.outStat.increment(int64(resp.Len())) if err := svc.start(); err != nil { svc.stop() return nil, err } //this.mu.Lock() //this.svcs = append(this.svcs, svc) //this.mu.Unlock() glog.Infof("(%s) server/handleConnection: Connection established.", svc.cid()) return svc, nil }