package notify import ( "net" "time" ) const ( MSG_SYS MessageType = iota MSG_SYS_WAIT MSG_SYS_REPLY // Deprecated: legacy RSA key-exchange control message. MSG_KEY_CHANGE MSG_ASYNC MSG_SYNC_ASK MSG_SYNC_REPLY ) type MessageType uint8 type NetType uint8 const ( NET_SERVER NetType = iota NET_CLIENT ) type MsgVal []byte type TransferMsg struct { ID uint64 Key string Value MsgVal Type MessageType } type Message struct { NetType LogicalConn *LogicalConn // Deprecated: ClientConn aliases LogicalConn for compatibility. ClientConn *ClientConn TransportConn *TransportConn ServerConn Client TransferMsg Time time.Time inboundConn net.Conn } type WaitMsg struct { TransferMsg Time time.Time Reply chan Message scope string //Ctx context.Context } type messageLogicalTransferSender interface { sendLogical(*LogicalConn, TransferMsg) (WaitMsg, error) } type messageInboundTransferSender interface { sendTransferInbound(*LogicalConn, *TransportConn, net.Conn, TransferMsg) error } func (m *Message) Reply(value MsgVal) (err error) { logical := messageLogicalConnSnapshot(m) transport := messageTransportConnSnapshot(m) reply := TransferMsg{ ID: m.ID, Key: m.Key, Value: value, Type: m.Type, } if reply.Type == MSG_SYNC_ASK { reply.Type = MSG_SYNC_REPLY } if reply.Type == MSG_SYS_WAIT { reply.Type = MSG_SYS_REPLY } if m.NetType == NET_SERVER { if m.inboundConn != nil && logical != nil { server := logical.Server() if server == nil { return transportDetachedErrorForPeer(logical, transport) } sender, _ := server.(messageInboundTransferSender) if sender == nil { return transportDetachedErrorForPeer(logical, transport) } return sender.sendTransferInbound(logical, transport, m.inboundConn, reply) } if transport != nil { _, err = transport.sendTransfer(reply) return } if logical == nil { return transportDetachedErrorForPeer(nil, transport) } server := logical.Server() if server == nil { return transportDetachedErrorForPeer(logical, transport) } sender, _ := server.(messageLogicalTransferSender) if sender == nil { return transportDetachedErrorForPeer(logical, transport) } _, err = sender.sendLogical(logical, reply) } if m.NetType == NET_CLIENT { _, err = m.ServerConn.send(reply) } return } func (m *Message) ReplyObj(value interface{}) (err error) { data, err := encode(value) if err != nil { return err } return m.Reply(data) } func hydrateServerMessagePeerFields(message Message) Message { if message.LogicalConn == nil { message.LogicalConn = logicalConnFromClient(message.ClientConn) } if message.ClientConn == nil { message.ClientConn = message.LogicalConn.compatClientConn() } if message.TransportConn == nil && message.LogicalConn != nil { message.TransportConn = message.LogicalConn.CurrentTransportConn() } return message } func messageLogicalConnSnapshot(message *Message) *LogicalConn { if message == nil { return nil } if message.LogicalConn != nil { return message.LogicalConn } return logicalConnFromClient(message.ClientConn) } func messageTransportConnSnapshot(message *Message) *TransportConn { if message == nil { return nil } if message.TransportConn != nil { return message.TransportConn } logical := messageLogicalConnSnapshot(message) if logical == nil { return nil } return logical.CurrentTransportConn() }