Exemplo n.º 1
0
func udpServer(port string, toRecorder chan Measurement, toWebsocket chan Measurement) {
	udpAddr, err := net.ResolveUDPAddr("udp4", "0.0.0.0:"+port)
	if err != nil {
		log.Fatal(err)
	}

	conn, err := net.ListenUDP("udp", udpAddr)
	if err != nil {
		log.Fatal(err)
	}

	log.Printf("fn=udpServer listening=true port=%s\n", config.Port)

	for {
		var buf [512]byte
		n, _, err := conn.ReadFromUDP(buf[0:])
		if err != nil {
			log.Fatal(err)
		}

		payload := buf[0:n]
		var m Measurement
		err = msgpack.Unmarshal(payload, &m)
		if err != nil {
			log.Fatal(err)
		}

		toRecorder <- m
		toWebsocket <- m
	}
}
Exemplo n.º 2
0
// verifyChallengeResponse is a kademlia.ResponseFunc, hence the elaborate signature
// remote is the room requester
// c is the challenge issuer, and also the verifier
func (c *client) verifyChallengeResponse(remote *kademlia.RemoteNode, token string, source kademlia.NodeID, data interface{}) {
	defer delete(c.Network.AwaitingResponse, token)
	defer delete(c.Network.ExtraInfo, token)

	response, ok := data.(string)
	if !ok {
		// shit
	}

	var answer answerPacket
	err := msgpack.Unmarshal([]byte(response), &answer)

	if err != nil {
		// shit - TODO
	}

	chatRoomID, ok := c.Network.ExtraInfo[token].(string)
	if !ok {
		// shit - TODO
	}
	chatRoom := c.chatroomsID[chatRoomID]

	valid := chatRoom.groupPrivateKey.Group.Verify([]byte(chatRoomID), sha1.New(), []byte(answer.ChallengeAnswer))

	if valid {
		// send group private key to user
		groupPriv := pem.EncodeToMemory(&pem.Block{Type: "GROUP PRIVATE KEY", Bytes: chatRoom.groupPrivateKey.Marshal()})

		r := c.Network.Node.GetNode(source)
		if r == nil {
			// shit
		}

		address := *remote.Address
		address.Port = answer.Port

		chatRoom.participants[string(source)] = &address

		msg := validChallengeResponse{chatRoomID, groupPriv, chatRoom.Name, c.port, chatRoom.participants}
		message, _ := kademlia.NewMessage()
		message.MessageType = "GROUP_PRIVATE_KEY"
		message.SourceID = c.Network.Node.ID
		message.Token = token
		message.InsertMessage(msg)

		kademlia.SendMsg(c.Network.Connection, remote.Address, message)

		chatRoom.trustedPeers = append(chatRoom.trustedPeers, r)
		return
	}

	message, _ := kademlia.NewMessage()
	message.MessageType = "FAILED_CHALLENGE"
	message.SourceID = c.Network.Node.ID
	message.Token = token

	kademlia.SendMsg(c.Network.Connection, remote.Address, message)

}
Exemplo n.º 3
0
func (dht *Kademlia) findNodeResponseHandler(remote *RemoteNode, token string, source NodeID, data interface{}) {
	defer delete(dht.AwaitingResponse, token)
	defer delete(dht.ExtraInfo, token)
	defer func() { remote.lastResponded = time.Now() }()

	// handle the data received
	p, _ := data.(string)
	byteArrayT := []byte(p)
	var remoteNodes []*RemoteNode
	msgpack.Unmarshal(byteArrayT, &remoteNodes)

	t, ok := dht.ExtraInfo[token]
	if !ok {
		// do something
		panic("Nothing found in ExtraInfo. Weird")
	}

	target, ok := t.(NodeID)
	if !ok {
		panic(fmt.Sprintf("t is supposed to be a NodeID. It is %T instead", t))
	}

	// here we use a simple trick - not scalable for larger scale DHTs, but for small networks it works well
	// basically it looks for the remote nodes that this node already knows about.
	// the problem starts coming in when you have more than 160 nodes I guess.
	var unseen []*RemoteNode = make([]*RemoteNode, 0)
	for _, r := range remoteNodes {
		if string(r.ID) == string(dht.Node.ID) {
			continue // skip anything that is itself
		}

		//check if node already exists. If not, send a new message with the target in mind
		_, seen := dht.Node.AddressToNode[r.Address.String()]

		if !seen {
			unseen = append(unseen, r)
		}

		if string(r.ID) == string(target) {
			ch, ok := dht.ResultChan[token]
			if !ok {
				panic("No Result chan available to send the resulting node to chan")
			}
			ch <- r

			return // bailout
		}
	}

	for _, remote := range unseen {
		dht.FindNode(remote, target)
	}
	log.Println("Done with Find Node Response Handler")
	return

}
Exemplo n.º 4
0
func (l *Lobby) Listen() {
	for message := range l.messages {
		switch MessageType(message.Message) {
		case MESSAGE_CHAT:
			var chat ChatMsg
			if err := msgpack.Unmarshal(message.Message, &chat); err == nil {
				l.Broadcast(nil, ChatMessage(message.Player, chat.Message))
			}
		}
	}
}
Exemplo n.º 5
0
// PurgeCache Will pull all the analytics data from the
// cache and drop it to a storage engine, in this case a CSV file
func (c CSVPurger) PurgeCache() {
	curtime := time.Now()
	fname := fmt.Sprintf("%s%d-%s-%d-%d-%d.csv", config.AnalyticsConfig.CSVDir, curtime.Year(), curtime.Month().String(), curtime.Day(), curtime.Hour(), curtime.Minute())

	ferr := os.MkdirAll(config.AnalyticsConfig.CSVDir, 0777)
	if ferr != nil {
		log.Error(ferr)
	}
	outfile, _ := os.Create(fname)
	defer outfile.Close()
	writer := csv.NewWriter(outfile)

	var headers = []string{"METHOD", "PATH", "SIZE", "UA", "DAY", "MONTH", "YEAR", "HOUR", "RESPONSE", "APINAME", "APIVERSION"}

	err := writer.Write(headers)
	if err != nil {
		log.Error("Failed to write file headers!")
		log.Error(err)
	} else {
		KeyValueMap := c.Store.GetKeysAndValues()
		keys := []string{}

		for k, v := range KeyValueMap {
			keys = append(keys, k)
			decoded := AnalyticsRecord{}
			err := msgpack.Unmarshal([]byte(v), &decoded)
			if err != nil {
				log.Error("Couldn't unmarshal analytics data:")
				log.Error(err)
			} else {
				toWrite := []string{
					decoded.Method,
					decoded.Path,
					strconv.FormatInt(decoded.ContentLength, 10),
					decoded.UserAgent,
					strconv.Itoa(decoded.Day),
					decoded.Month.String(),
					strconv.Itoa(decoded.Year),
					strconv.Itoa(decoded.Hour),
					strconv.Itoa(decoded.ResponseCode),
					decoded.APIName,
					decoded.APIVersion}
				err := writer.Write(toWrite)
				if err != nil {
					log.Error("File write failed!")
					log.Error(err)
				}
			}
		}
		writer.Flush()
		c.Store.DeleteKeys(keys)
	}
}
Exemplo n.º 6
0
func (c *client) processPackets() {
	for pack := range c.packets {
		var msg Message
		err := msgpack.Unmarshal(pack.bytes, &msg)
		if err != nil {
			// do something
			log.Printf("FAILED TO UNMARSHAL")
			continue
		}

		c.messages <- msg
	}
}
Exemplo n.º 7
0
func (dht *Kademlia) storeResponse(remote *RemoteNode, token string, source NodeID, data interface{}) {
	p, _ := data.(string)
	byteArrayP := []byte(p)

	var m map[string]interface{}
	msgpack.Unmarshal(byteArrayP, &m)

	for k, v := range m {
		dht.LocalStore(k, v)
	}

	message, _ := NewMessage()
	message.MessageType = "STORE_RESPONSE"
	message.SourceID = dht.Node.ID
	message.Message = "OK"

	SendMsg(dht.Connection, remote.Address, message)
}
Exemplo n.º 8
0
func (dht *Kademlia) processPackets() {
	// packets are all Messages as a byte array. processPacket() basically verifies this, and errors out if weird shit packets comes in
	for pack := range dht.packets {
		var msg Message
		err := msgpack.Unmarshal(pack.bytes, &msg)
		if err != nil {
			// do something
			log.Printf("Failed to unmarshal message in packet.")
			continue
		}

		//check and see if node exists
		remote := dht.Node.GetOrCreateNode(msg.SourceID, pack.returnAddress.String())
		dht.pendingEnvelopes[msg.Token] = remote

		dht.requests <- msg
	}
}
Exemplo n.º 9
0
func (self *MemdClient) Get(key string, v interface{}) error {
	item, err := self.client.Get(key)

	if err != nil {
		return err
	}

	if item.Flags&4 != 0 {
		err := msgpack.Unmarshal(item.Value, &v)
		if err != nil {
			err = errors.New(fmt.Sprintf("Failed to decode value: %s", err))
			return err
		}
		return nil
	}

	v = item.Value
	return nil
}
Exemplo n.º 10
0
func (self *MemdClient) GetMulti(
	keys []string,
	makeContainer func() interface{},
) (map[string]interface{}, error) {
	items, err := self.client.GetMulti(keys)
	if err != nil {
		return nil, err
	}

	ret := make(map[string]interface{})
	for k, item := range items {
		v := makeContainer()
		err := msgpack.Unmarshal(item.Value, v)
		if err != nil {
			continue
		}
		ret[k] = v
	}

	return ret, nil
}
Exemplo n.º 11
0
// PurgeCache will pull the data from the in-memory store and drop it into the specified MongoDB collection
func (m *MongoPurger) PurgeCache() {
	if m.dbSession == nil {
		log.Info("Not connected to analytics store, connecting...")
		m.Connect()
		m.PurgeCache()
	} else {
		analyticsCollection := m.dbSession.DB("").C(config.AnalyticsConfig.MongoCollection)
		KeyValueMap := m.Store.GetKeysAndValues()

		if len(KeyValueMap) > 0 {
			keys := make([]interface{}, len(KeyValueMap), len(KeyValueMap))
			keyNames := make([]string, len(KeyValueMap), len(KeyValueMap))

			i := 0
			for k, v := range KeyValueMap {
				keyNames[i] = k
				decoded := AnalyticsRecord{}
				err := msgpack.Unmarshal([]byte(v), &decoded)
				if err != nil {
					log.Error("Couldn't unmarshal analytics data:")
					log.Error(err)
				} else {
					keys[i] = interface{}(decoded)
				}
				i++
			}

			err := analyticsCollection.Insert(keys...)
			if err != nil {
				log.Error("Problem inserting to mongo collection")
				log.Error(err)
			} else {
				m.Store.DeleteKeys(keyNames)
			}
		}
	}

}
Exemplo n.º 12
0
func MessageType(message []byte) int {
	var mt Msg
	mt.MessageType = MESSAGE_INVALID
	msgpack.Unmarshal(message, &mt)
	return mt.MessageType
}
Exemplo n.º 13
0
func (c *client) receiveGroupPrivateKey(remote *kademlia.RemoteNode, token string, source kademlia.NodeID, data interface{}) {
	// this is the last step of all the pingponging.  Hence the cleanup
	defer delete(c.Network.AwaitingResponse, token)
	defer delete(c.Network.ExtraInfo, token)

	response, ok := data.(string)
	if !ok {
		//shit
	}
	asBytes := []byte(response)

	var valid validChallengeResponse
	err := msgpack.Unmarshal(asBytes, &valid)

	if err != nil {
		//shit
	}

	chatRoomIDIface, ok := c.Network.ExtraInfo[token]
	if !ok { // means it's been cleaned up. This request shouldn't have happened
		c.ui <- "...Network error. ExtraInfo has no key. This usually means this is a duplicate request"
		return
	}
	chatRoomID, ok := chatRoomIDIface.(string)
	if !ok {
		panic("chatroomID not a string??!")
	}
	chatRoom, ok := c.chatroomsID[chatRoomID]
	if !ok {
		c.ui <- "...No chatroom found"
		return
	}

	// start decoding and unmarshalling the private key
	block, _ := pem.Decode(valid.PrivateKey)
	if block == nil {
		c.ui <- "Block is not a pem"
		return
	}

	groupPriv, success := chatRoom.groupPrivateKey.Unmarshal(chatRoom.groupPublicKey, block.Bytes)
	if !success {
		c.ui <- "...Unable to succesfully unmarshal private key"
		return
	}

	// apply them to the chatroom
	chatRoom.groupPrivateKey = groupPriv
	chatRoom.Name = valid.Name
	chatRoom.participants = valid.Participants

	// when the participants list is sent from the challenge issuer to the room requester,
	// the challenge issuer's own IP will be 0.0.0.0.
	// this will cause the challenge issuer to not receive the message if a message is sent from the room requester
	// so this fixes that
	sourceNode := c.Network.Node.GetNode(source)
	if sourceNode == nil {
		c.ui <- fmt.Sprintf("...No such remote for source: %#v", source)
		return
	}

	newAddress := *sourceNode.Address
	newAddress.Port = valid.Port

	lA := c.connection.LocalAddr()
	localAddr, _ := lA.(*net.UDPAddr)

	chatRoom.participants[string(source)] = &newAddress

	// fixes  it so that the local node is 0.0.0.0:xxxx - this is an issue only in OS X,  doesn't matter what the self-IP is for linux
	chatRoom.participants[string(c.Node.ID)] = localAddr

	c.chatroomsName[valid.Name] = chatRoom

	// store chatroom ID on kademlia
	c.Network.LocalStore(chatRoom.ID, c.Node.ID)
}
Exemplo n.º 14
0
func fnVMsgpackDecodeFn(buf []byte, ts *TestStruc) error {
	return vmsgpack.Unmarshal(buf, ts)
}
Exemplo n.º 15
0
func DecodeMsgPack(b []byte) (out map[string]interface{}) {
	_ = msgpack.Unmarshal(b, &out)
	return
}
Exemplo n.º 16
0
func (dht *Kademlia) findValueResponseHandler(remote *RemoteNode, token string, source NodeID, data interface{}) {
	defer delete(dht.AwaitingResponse, token)
	defer delete(dht.ExtraInfo, token)
	defer func() { remote.lastResponded = time.Now() }()

	log.Println("IN FIND_VALUE_RESPONSE. Token is ", token)

	// get target info
	t, ok := dht.ExtraInfo[token]
	if !ok {
		// do something
		panic("Nothing found in ExtraInfo. Weird")
	}
	target, ok := t.(string) // we can do this because all the keys are strings
	if !ok {
		panic("target key is supposed to be a string")
	}

	// unmarshal
	p, _ := data.(string)
	byteArrayP := []byte(p)
	var remoteNodes []*RemoteNode
	err := msgpack.Unmarshal(byteArrayP, &remoteNodes)

	if err != nil {
		// it's not a list of remotenodes - it's a nodeID
		var nid NodeID
		nidUnmarshallErr := msgpack.Unmarshal(byteArrayP, &nid)

		if nidUnmarshallErr != nil {
			log.Fatalf("data is not a nodeID. It is %#v(%T) Error: %s", data, data, nidUnmarshallErr)
			return
		}

		r := dht.Node.GetNode(nid)

		if r == nil {
			panic("remote not found")
		}

		r.hasKey[target] = true

		// this means it's not a list of remote nodes.
		ch, ok := dht.ResultChan[token]
		if !ok {
			panic("No Return Result Channel")
		}

		ch <- byteArrayP
		return
	}

	log.Println("Not found. Looking Iteratively")

	// if a list of remoteNodes is returned, that means this remote node doesn't have the key
	rN := dht.Node.GetNode(source)
	rN.hasKey[target] = false

	var unseen []*RemoteNode = make([]*RemoteNode, 0)
	for _, r := range remoteNodes {

		hasKey, ok := r.hasKey[target]
		if !ok {
			unseen = append(unseen, r)
			continue
		}
		if !hasKey {
			// has key but value = false
			continue
		}

		// else, query again to see if this remote really has it
		unseen = append(unseen, r)

	}

	for _, r := range unseen {
		dht.FindValue(r, target)
	}

}
Exemplo n.º 17
0
func (m msgpackEncoder) Unmarshal(data []byte, v interface{}) error {
	return msgpack.Unmarshal(data, v)
}
Exemplo n.º 18
0
func fnVMsgpackDecodeFn(buf []byte, ts interface{}) error {
	return vmsgpack.Unmarshal(buf, ts)
}
Exemplo n.º 19
0
// RequestRoom sends a message via the Kademlia network, looking for nodes with the chatroom ID
func (c *client) RequestRoom(ID string) {
	// find a node with the chatroom id first
	tmpRemote := c.Network.Node.GetNearestNode()
	log.Printf("Nearest Node is: %#v\n", tmpRemote.ID)

	if tmpRemote == nil {
		c.ui <- "...No remote node found" // typically because well, the client is not connected to the kademlia network.
		return
	}

	// issue FIND_VALUE
	token := c.Network.FindValue(tmpRemote, ID)
	ch, ok := c.Network.ResultChan[token]
	defer delete(c.Network.ResultChan, token) // clean up after oneself

	if !ok {
		c.ui <- "...No result channel created for room request"
		return
	}

	var id kademlia.NodeID
	tmp := <-ch
	asBytes, ok := tmp.([]byte)

	if !ok {
		panic("SHIT SHIT")
	}

	err := msgpack.Unmarshal(asBytes, &id)
	if err != nil {
		c.ui <- fmt.Sprintf("...Unable to unmarshal. Error was: %s", err)
		return
	}

	// found the ID? get the remoteNode so we can send it a message asking for a challenge
	remote := c.Network.Node.GetNode(id)

	// get the relevant room settings - member key
	memberFileName := fmt.Sprintf("keys/%s_member.pem", ID)
	memberPemData, err := ioutil.ReadFile(memberFileName)
	if err != nil {
		//shit
		c.ui <- fmt.Sprintf("...No pem file available for room request. It should be in keys/%s_member.pem", ID)
		return
	}

	block, _ := pem.Decode(memberPemData)
	if block == nil {
		// shit
		c.ui <- fmt.Sprintf("...block is not a pem encoded file. Check keys/%s_member.pem", ID)
	}
	if block.Type != "MEMBER PRIVATE KEY" {
		c.ui <- "...Incorrect pem type. Expected MEMBER PRIVATE KEY"
		return
	}

	// get the relevant room settings - public key
	publicFileName := fmt.Sprintf("chatrooms/%s_public.pem", ID)
	publicPemData, err := ioutil.ReadFile(publicFileName)
	if err != nil {
		// shit
		c.ui <- fmt.Sprintf("...No room publick pem file available. It should be in chatrooms/%s_public.pem", ID)
		return
	}

	publicBlock, _ := pem.Decode(publicPemData)
	if publicBlock == nil {
		//shit
		c.ui <- fmt.Sprintf("...Public block is not a pem encoded file. Check chatrooms/%s_public.pem", ID)
		return
	}
	if publicBlock.Type != "GROUP PUBLIC KEY" {
		c.ui <- "...Incorrect pem type. Expected GROUP PUBLIC KEY"
		return
	}

	// create a dummy chatroom. The dummy chatroom is required because to unmarshal the keys, a key is needed to begin with
	chatRoom := createChatroom()
	c.chatroomsID[ID] = chatRoom
	chatRoom.ID = ID

	group, success := chatRoom.groupPublicKey.Unmarshal(publicBlock.Bytes)
	if !success {
		c.ui <- "...Unable to unmarshal group public key"
		return
	}

	memberPriv, success := chatRoom.memberPrivateKey.Unmarshal(group, block.Bytes)
	if !success {
		c.ui <- "...Unable to unmarshal member private key"
		return
	}

	// settings that are important to the challenge - these are dummy keys which are required to unmarshal
	chatRoom.groupPublicKey = group
	chatRoom.memberPrivateKey = memberPriv

	// send message
	message, token := kademlia.NewMessage()
	message.MessageType = "REQUEST_ROOM"
	message.SourceID = c.Network.Node.ID
	message.Message = ID

	kademlia.SendMsg(c.Network.Connection, remote.Address, message)

	// register things with the token so the reply knows wtf is going on
	c.Network.AwaitingResponse[token] = time.Now()
	c.Network.ExtraInfo[token] = ID
}