2018-08-13 07:48:32 +00:00
|
|
|
package mongodb
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/binary"
|
|
|
|
"math/rand"
|
|
|
|
|
2018-08-15 07:17:18 +00:00
|
|
|
osm "git.loafle.net/overflow/service_matcher-go"
|
2018-08-13 07:48:32 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
MONGO_OP_REQUEST uint32 = 2004
|
|
|
|
MONGO_OP_REPLY uint32 = 1
|
|
|
|
MONGO_FCNAME string = "admin.$cmd"
|
|
|
|
MONGO_ELEMENT string = "ismaster"
|
|
|
|
)
|
|
|
|
|
|
|
|
var MONGO_REQUEST_ID uint32
|
|
|
|
|
|
|
|
type MsgHeader struct {
|
|
|
|
MessageLength uint32
|
|
|
|
RequestId uint32
|
|
|
|
ResponseTo uint32
|
|
|
|
OpCode uint32
|
|
|
|
}
|
|
|
|
|
|
|
|
type OP_request struct {
|
|
|
|
Header MsgHeader
|
|
|
|
Flags uint32
|
|
|
|
FullCollectionName [11]byte
|
|
|
|
NumberToSkip uint32
|
|
|
|
NumberToReturn int32
|
|
|
|
DocumentLength uint32
|
|
|
|
Type_ uint8
|
|
|
|
Element [9]byte
|
|
|
|
Value uint8
|
|
|
|
_ uint8
|
|
|
|
}
|
|
|
|
|
|
|
|
type OP_reply struct {
|
|
|
|
Header MsgHeader
|
|
|
|
ResponseFlags int32
|
|
|
|
CursorID int64
|
|
|
|
StartingFrom int32
|
|
|
|
NumberReturned int32
|
|
|
|
Documents [512]byte
|
|
|
|
}
|
|
|
|
|
|
|
|
type MongoDBMatcher struct {
|
2018-08-15 07:17:18 +00:00
|
|
|
osm.Matchers
|
|
|
|
meta osm.Metadata
|
2018-08-13 07:48:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (m *MongoDBMatcher) Key() string {
|
|
|
|
return "MONGODB"
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *MongoDBMatcher) Name() string {
|
|
|
|
return "MongoDB"
|
|
|
|
}
|
|
|
|
|
2018-08-15 07:17:18 +00:00
|
|
|
func (m *MongoDBMatcher) Meta() osm.Metadata {
|
2018-08-13 07:48:32 +00:00
|
|
|
return m.meta
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *MongoDBMatcher) IsPrePacket() bool {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *MongoDBMatcher) HasResponse(index int) bool {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2018-08-15 07:17:18 +00:00
|
|
|
func (m *MongoDBMatcher) IsError(info osm.MatchInfo, index int, packet *osm.Packet) bool {
|
2018-08-13 07:48:32 +00:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2018-08-15 07:17:18 +00:00
|
|
|
func (m *MongoDBMatcher) Match(info osm.MatchInfo, index int, packet *osm.Packet) error {
|
2018-08-13 07:48:32 +00:00
|
|
|
|
2018-09-03 06:42:56 +00:00
|
|
|
if packet == nil || !packet.Valid() {
|
2018-08-15 07:17:18 +00:00
|
|
|
return osm.NoPacketReceivedError()
|
2018-08-13 07:48:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
reader := new(bytes.Buffer)
|
2018-09-03 06:42:56 +00:00
|
|
|
reader.Write(packet.Bytes())
|
2018-08-13 07:48:32 +00:00
|
|
|
|
|
|
|
reply := OP_reply{}
|
|
|
|
if err := binary.Read(reader, binary.LittleEndian, &reply); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if uint32(packet.Len) != reply.Header.MessageLength {
|
2018-08-15 07:17:18 +00:00
|
|
|
return osm.NotMatchedError()
|
2018-08-13 07:48:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if reply.Header.ResponseTo != MONGO_REQUEST_ID {
|
2018-08-15 07:17:18 +00:00
|
|
|
return osm.NotMatchedError()
|
2018-08-13 07:48:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if reply.Header.OpCode != MONGO_OP_REPLY {
|
2018-08-15 07:17:18 +00:00
|
|
|
return osm.NotMatchedError()
|
2018-08-13 07:48:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2018-08-15 07:17:18 +00:00
|
|
|
func NewMatcher() osm.Matcher {
|
2018-08-13 07:48:32 +00:00
|
|
|
|
|
|
|
mm := &MongoDBMatcher{}
|
2018-08-15 07:17:18 +00:00
|
|
|
mm.meta = osm.NewMetadata()
|
2018-08-13 07:48:32 +00:00
|
|
|
|
|
|
|
tempBuf := new(bytes.Buffer)
|
|
|
|
binary.Write(tempBuf, binary.BigEndian, OP_request{})
|
|
|
|
|
|
|
|
var fcn [11]byte
|
|
|
|
copy(fcn[:], MONGO_FCNAME)
|
|
|
|
|
|
|
|
var elem [9]byte
|
|
|
|
copy(elem[:], MONGO_ELEMENT)
|
|
|
|
|
|
|
|
MONGO_REQUEST_ID = rand.Uint32()
|
|
|
|
m := OP_request{
|
|
|
|
Header: MsgHeader{
|
|
|
|
MessageLength: uint32(len(tempBuf.Bytes())),
|
|
|
|
RequestId: MONGO_REQUEST_ID,
|
|
|
|
ResponseTo: 0,
|
|
|
|
OpCode: MONGO_OP_REQUEST,
|
|
|
|
},
|
|
|
|
Flags: 0,
|
|
|
|
FullCollectionName: fcn,
|
|
|
|
NumberToSkip: 0,
|
|
|
|
NumberToReturn: -1,
|
|
|
|
DocumentLength: 16,
|
|
|
|
Type_: 0x08,
|
|
|
|
Element: elem,
|
|
|
|
Value: 1,
|
|
|
|
}
|
|
|
|
writer := new(bytes.Buffer)
|
|
|
|
binary.Write(writer, binary.LittleEndian, m)
|
|
|
|
|
2018-08-15 07:17:18 +00:00
|
|
|
mm.AddPacket(osm.NewPacket(writer.Bytes(), writer.Len()))
|
2018-08-13 07:48:32 +00:00
|
|
|
|
|
|
|
return mm
|
|
|
|
}
|