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 } }
// 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) }
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 }
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)) } } } }
// 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) } }
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 } }
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) }
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 } }
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 }
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 }
// 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) } } } }
func MessageType(message []byte) int { var mt Msg mt.MessageType = MESSAGE_INVALID msgpack.Unmarshal(message, &mt) return mt.MessageType }
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) }
func fnVMsgpackDecodeFn(buf []byte, ts *TestStruc) error { return vmsgpack.Unmarshal(buf, ts) }
func DecodeMsgPack(b []byte) (out map[string]interface{}) { _ = msgpack.Unmarshal(b, &out) return }
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) } }
func (m msgpackEncoder) Unmarshal(data []byte, v interface{}) error { return msgpack.Unmarshal(data, v) }
func fnVMsgpackDecodeFn(buf []byte, ts interface{}) error { return vmsgpack.Unmarshal(buf, ts) }
// 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 }