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 }
func getConnackMessage(conn io.Closer) (*message.ConnackMessage, error) { buf, err := getMessageBuffer(conn) if err != nil { //Log.Debugc(func() string{ return fmt.Sprintf("Receive error: %v", err)}) return nil, err } msg := message.NewConnackMessage() _, err = msg.Decode(buf) //Log.Debugc(func() string{ return fmt.Sprintf("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 }
// HandleConnection is for the broker to handle an incoming connection from a client func (this *Server) handleConnection(c io.Closer, atomic_id uint64) (err error) { if c == nil { return ErrInvalidConnectionType } defer func() { if err != nil { c.Close() } }() err = this.checkConfiguration() if err != nil { return err } conn, ok := c.(net.Conn) if !ok { return 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 { //Log.Debugc(func() string{ return fmt.Sprintf("request message: %s\nresponse message: %s\nerror : %v", mreq, resp, err)}) resp.SetReturnCode(cerr) resp.SetSessionPresent(false) writeMessage(conn, resp) } return err } c_id := string(req.ClientId()) c_hash := ClientHash{Name: c_id, Conn: &conn} // Authenticate the user, if error, return error and exit auth_info := auth.NewAuthInfo(req.Password(), req.ClientId(), atomic_id) if err = this.authMgr.Authenticate(string(req.Username()), auth_info); err != nil { Log.Infoc(func() string { return fmt.Sprintf("(%d/%s) client auth failed. username: %s, client_id: %s", atomic_id, c_id, req.Username(), c_id) }) resp.SetReturnCode(message.ErrBadUsernameOrPassword) resp.SetSessionPresent(false) writeMessage(conn, resp) time.Sleep(3 * time.Second) return err } if req.KeepAlive() == 0 { req.SetKeepAlive(minKeepAlive) } svc := &service{ id: atomic_id, client: false, keepAlive: int(req.KeepAlive()), connectTimeout: this.ConnectTimeout, ackTimeout: this.AckTimeout, timeoutRetries: this.TimeoutRetries, conn: conn, sessMgr: this.sessMgr, topicsMgr: this.topicsMgr, server: this, } ClientMapProcessor <- c_hash err = this.getSession(svc, req, resp) if err != nil { return err } resp.SetReturnCode(message.ConnectionAccepted) if err = writeMessage(c, resp); err != nil { return err } svc.inStat.increment(int64(req.Len())) svc.outStat.increment(int64(resp.Len())) if err := svc.start(c_id); err != nil { svc.stop() return err } //this.mu.Lock() //this.svcs = append(this.svcs, svc) //this.mu.Unlock() Log.Debugc(func() string { return fmt.Sprintf("(%s) client connected successfully.", svc.cid()) }) return nil }