Beispiel #1
0
func (k *Kademlia) DoFindValueIter(contact Contact, searchKey ID, chnl chan FindValueResult) string {
	// 	The recipient must return k triples if at all possible.
	//  It may only return fewer than k if it is returning all of the contacts that it has knowledge of.
	port_str := strconv.Itoa(int(contact.Port))
	client, err := rpc.DialHTTPPath("tcp", contact.Host.String()+":"+port_str, rpc.DefaultRPCPath+port_str)
	if err != nil {
		log.Fatal("DialHTTP: ", err)
	}
	defer client.Close()
	request := new(FindValueRequest)
	result := new(FindValueResult)
	request.MsgID = NewRandomID()
	request.Sender = k.SelfContact
	request.Key = searchKey
	err = client.Call("KademliaCore.FindValue", request, &result)
	if err != nil {
		log.Fatal("Call: ", err)
		return "ERR:DoFindValue call err"
	}
	if request.MsgID == result.MsgID {
		result.SenderContact = contact
		k.SelfTable.Update(contact)
		chnl <- *result
		return "OK: Findvalue"
	} else {
		return "ERR: FindValue: req.MsgID != res.MsgID"
	}
}
Beispiel #2
0
//-----------------------------------------------------------------//
func (k *Kademlia) DoFindNodeIter(contact Contact, searchKey ID, chnl chan FindNodeResult) string {
	// TODO: Implement
	// Warining:The recipient must return k triples if at all possible.
	//          It may only return fewer than k if it is returning all of the contacts that it has knowledge of.  -----FIXME
	port_str := strconv.Itoa(int(contact.Port))
	client, err := rpc.DialHTTPPath("tcp", contact.Host.String()+":"+port_str, rpc.DefaultRPCPath+port_str)
	if err != nil {
		return "DialHTTP:err"
	}
	defer client.Close()
	request := new(FindNodeRequest)
	result := new(FindNodeResult)
	request.MsgID = NewRandomID()
	request.Sender = k.SelfContact
	request.NodeID = searchKey
	err = client.Call("KademliaCore.FindNode", request, &result)
	if err != nil {
		return "ERR:DoFindValue call err"
	}
	if request.MsgID == result.MsgID {
		/* put returned contact into channel */
		result.SenderContact = contact
		chnl <- *result
		return "OK, Found Nodes"
	}
	return "ERR: FindNOde->req.MsgID!=res.MsgID"
	// If all goes well, return "OK: <output>", otherwise print "ERR: <messsage>"
}
Beispiel #3
0
func (k *Kademlia) DoGetVDO(contact Contact, vdoId ID) (string, error) {
	port_str := strconv.Itoa(int(contact.Port))
	client, err := rpc.DialHTTPPath("tcp", contact.Host.String()+":"+port_str, rpc.DefaultRPCPath+port_str)
	if err != nil {
		log.Fatal("DialHTTP: ", err)
	}
	defer client.Close()
	req := new(GetVDORequest)
	res := new(GetVDOResult)
	req.Sender = k.SelfContact
	req.MsgID = NewRandomID()
	req.VdoID = vdoId
	err = client.Call("KademliaCore.GetVDO", req, &res)
	if err != nil {
		log.Fatal("Call: ", err)
		return "ERR:Doping call err", nil
	}
	// If all goes well, return "OK: <output>", otherwise print "ERR: <messsage>"
	if req.MsgID == res.MsgID {
		k.SelfTable.Update(res.SenderContact)
		secret := UnvanishData(k, res.VDO)
		return string(secret), nil
	} else {
		return "ERR: req.MsgID != res.MsgID", nil
	}

}
Beispiel #4
0
func (k *Kademlia) DoFindNode(contact *Contact, searchKey ID) (string, FindNodeResult) {
	// TODO: Implement
	// Warining:The recipient must return k triples if at all possible.
	//          It may only return fewer than k if it is returning all of the contacts that it has knowledge of.  -----FIXME
	port_str := strconv.Itoa(int(contact.Port))
	client, err := rpc.DialHTTPPath("tcp", contact.Host.String()+":"+port_str, rpc.DefaultRPCPath+port_str)
	if err != nil {
		log.Fatal("DialHTTP: ", err)
	}
	defer client.Close()
	request := new(FindNodeRequest)
	result := new(FindNodeResult)
	request.MsgID = NewRandomID()
	request.Sender = k.SelfContact
	request.NodeID = searchKey
	err = client.Call("KademliaCore.FindNode", request, &result)
	if err != nil {
		log.Fatal("Call: ", err)
		return "ERR:DoFindNode call err", *result
	}
	if request.MsgID == result.MsgID {
		k.SelfTable.Update(*contact)
		//print the contacts
		fmt.Println("--------Closest Nodes to", searchKey.AsString(), "---------")
		for i := 0; i < len(result.Nodes); i++ {
			fmt.Println(result.Nodes[i].NodeID.AsString())
		}
		return "OK : FindNode", *result
	}
	return "ERR: FindNOde->req.MsgID!=res.MsgID", *result
	// If all goes well, return "OK: <output>", otherwise print "ERR: <messsage>"
}
Beispiel #5
0
func Test_Proto_HTTP_Large_Timeout(t *testing.T) {
	t.Skip()
	srv := &httpTestServer{&baseTestServer{}}
	port, err := srv.listen()
	assert.NoError(t, err)
	srv.start()
	defer srv.Stop()

	client, err := rpc.DialHTTPPath("tcp",
		fmt.Sprintf("127.0.0.1:%d", port), "/v1/rpc")
	assert.NoError(t, err)
	defer client.Close()

	var res, res1 TestMessage
	req := TestMessage{
		"12345678910",
		[]byte(strings.Repeat("0", 1024*1024)),
	}
	err = client.Call("ServiceFixture.Ping", &req, &res)
	assert.NoError(t, err)
	assert.Equal(t, req, res)

	time.Sleep(time.Second)
	err = client.Call("ServiceFixture.Ping", &req, &res1)
	assert.NoError(t, err)
	assert.Equal(t, req, res1)
}
Beispiel #6
0
// This is the function to perform the RPC
func (k *Kademlia) DoPing(host net.IP, port uint16) string {
	// TODO: Implement
	//	dstHostPort := HostPortGenerator(host, port)
	port_str := strconv.Itoa(int(port))
	client, err := rpc.DialHTTPPath("tcp", host.String()+":"+port_str, rpc.DefaultRPCPath+port_str)
	if err != nil {
		log.Fatal("DialHTTP: ", err)
	}
	defer client.Close()
	ping := new(PingMessage)
	pong := new(PongMessage)
	ping.MsgID = NewRandomID()
	ping.Sender = k.SelfContact
	err = client.Call("KademliaCore.Ping", ping, &pong)
	if err != nil {
		log.Fatal("Call: ", err)
		return "ERR:Doping call err"
	}
	// If all goes well, return "OK: <output>", otherwise print "ERR: <messsage>"
	if pong.MsgID == ping.MsgID {
		k.SelfTable.Update(pong.Sender)
		return "OK: PONG"
	} else {
		return "ERR: PONG.MsgID != ping.MsgID"
	}

}
Beispiel #7
0
// Start starts an agreement on new instance.
func (p *Paxos) Start(seq int, v Value) {
	var clients []*rpc.Client
	for _, peer := range p.peers {
		addrAndPath := strings.Split(peer, "/")
		if len(addrAndPath) != 2 {
			panic(fmt.Sprintf("got: %v, want: ${HOSTNAME}:${PORT}/${RPC_PATH}", addrAndPath))
		}
		addr := addrAndPath[0]
		rpcPath := addrAndPath[1]
		client, err := rpc.DialHTTPPath("tcp", addr, rpcPath)
		if err == nil {
			clients = append(clients, client)
		} else {
			fmt.Printf("Error: %v\n", err)

			clients = append(clients, nil)
		}
	}

	p.maxSeq++
	for _, c := range clients {
		if c != nil {
			c.Go("Handler.OnReceiveProposal",
				&Request{
					FromID: p.ID(),
					Seq:    p.Max(),
				},
				&Response{}, nil)
		}
	}
}
Beispiel #8
0
/***
 * if the least recently used contact has response, then
 * ignore the new element. If the least recently used contact
 * doesn't have response, then delete it and add the new contact.
 */
func pingToRemove(bucket *[]Contact, contact *Contact, self *Contact) {
	ping := PingMessage{*self, NewRandomID()}
	var pong PongMessage
	remove := 0

	port_str := strconv.Itoa(int((*bucket)[0].Port))
	client, err := rpc.DialHTTPPath("tcp", Dest((*bucket)[0].Host, (*bucket)[0].Port), rpc.DefaultRPCPath+port_str)
	if err != nil {
		remove = 1
	}
	defer client.Close()
	err = client.Call("KademliaCore.Ping", ping, &pong)
	if err != nil {
		remove = 1
	}

	if remove == 1 {
		*bucket = (*bucket)[1:]
		*bucket = append(*bucket, *contact)
	} else {
		tmp := (*bucket)[0]
		*bucket = (*bucket)[1:]
		*bucket = append(*bucket, tmp)
	}
}
Beispiel #9
0
func main() {
	// By default, Go seeds its RNG with 1. This would cause every program to
	// generate the same sequence of IDs. Use the current nano time to
	// random numbers
	rand.Seed(time.Now().UnixNano())

	// Get the bind and connect connection strings from command-line arguments.
	flag.Parse()
	args := flag.Args()
	if len(args) != 2 {
		log.Fatal("Must be invoked with exactly two arguments!\n")
	}
	listenStr := args[0]
	firstPeerStr := args[1]

	// Create the Kademlia instance
	fmt.Printf("kademlia starting up!\n")
	kadem := kademlia.NewKademlia(listenStr)

	// Confirm our server is up with a PING request and then exit.
	// Your code should loop forever, reading instructions from stdin and
	// printing their results to stdout. See README.txt for more details.
	_, port, _ := net.SplitHostPort(firstPeerStr)
	client, err := rpc.DialHTTPPath("tcp", firstPeerStr, rpc.DefaultRPCPath+port)
	if err != nil {
		log.Fatal("DialHTTP: ", err)
	}

	ping := new(kademlia.PingMessage)
	ping.MsgID = kademlia.NewRandomID()
	ping.Sender = kadem.Routes.SelfContact
	var pong kademlia.PongMessage
	err = client.Call("KademliaCore.Ping", ping, &pong)
	if err != nil {
		log.Fatal("Call: ", err)
	}
	log.Printf("ping msgID: %s\n", ping.MsgID.AsString())
	log.Printf("pong msgID: %s\n", pong.MsgID.AsString())

	kadem.Routes.Update(&pong.Sender)

	in := bufio.NewReader(os.Stdin)
	quit := false
	for !quit {
		line, err := in.ReadString('\n')
		if err != nil {
			log.Fatal(err)
		}
		line = strings.TrimSpace(line)
		if line == "" {
			continue
		}
		resp := executeLine(kadem, line)
		if resp == "quit" {
			quit = true
		} else if resp != "" {
			fmt.Printf("%v\n", resp)
		}
	}
}
Beispiel #10
0
func (k *Kademlia) DoStore(contact *Contact, key ID, value []byte) string {
	// TODO: Implement
	// If all goes well, return "OK: <output>", otherwise print "ERR: <messsage>"
	port_str := strconv.Itoa(int(contact.Port))
	client, err := rpc.DialHTTPPath("tcp", contact.Host.String()+":"+port_str, rpc.DefaultRPCPath+port_str)
	if err != nil {
		log.Fatal("DialHTTP: ", err)
	}
	defer client.Close()
	storeRequest := new(StoreRequest)
	storeResult := new(StoreResult)
	storeRequest.MsgID = NewRandomID()
	storeRequest.Sender = k.SelfContact
	storeRequest.Key = key
	storeRequest.Value = value
	err = client.Call("KademliaCore.Store", storeRequest, &storeResult)
	if err != nil {
		log.Fatal("Call: ", err)
		return "ERR: Dostore call err"
	}
	// If all goes well, return "OK: <output>", otherwise print "ERR: <messsage>"
	if storeRequest.MsgID == storeResult.MsgID {
		k.SelfTable.Update(*contact)
		fmt.Println("\"", string(value), "\" stored in \"", contact.NodeID.AsString(), "\"")
		return "OK: Store"
	} else {
		return "ERR: storeRequest.MsgID != storeResult.MsgID"
	}
	return "ERR: Not implemented"
}
Beispiel #11
0
func sendQuery(c Contact, active *ConcurrMap, waitChan chan int, nodeChan chan Contact) {
	args := FindNodeRequest{c, NewRandomID(), c.NodeID}
	var reply FindNodeResult
	active.Lock()
	active.m[c.NodeID] = 1
	active.Unlock()

	port_str := strconv.Itoa(int(c.Port))
	client, err := rpc.DialHTTPPath("tcp", Dest(c.Host, c.Port), rpc.DefaultRPCPath+port_str)
	if err != nil {
		log.Fatal("DialHTTP", err)
		active.Lock()
		active.m[c.NodeID] = 0
		active.Unlock()
	}
	defer client.Close()
	err = client.Call("KademliaCore.FindNode", args, &reply)
	if err != nil {
		log.Fatal("Call: ", err)
		active.Lock()
		active.m[c.NodeID] = 0
		active.Unlock()
	}

	active.RLock()
	a := active.m[c.NodeID]
	active.RUnlock()
	if a == 1 {
		for _, node := range reply.Nodes {
			nodeChan <- node
		}
	}
	waitChan <- 1
}
Beispiel #12
0
func Benchmark_Proto_HTTP_Large(b *testing.B) {
	b.Skip()
	srv := &httpTestServer{&baseTestServer{}}
	port, err := srv.listen()
	assert.NoError(b, err)
	srv.start()
	defer srv.Stop()

	client, err := rpc.DialHTTPPath("tcp",
		fmt.Sprintf("127.0.0.1:%d", port), "/v1/rpc")
	assert.NoError(b, err)
	defer client.Close()

	b.Log(port, b.N)

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		b.StartTimer()
		var res TestMessage
		req := TestMessage{
			fmt.Sprintf("%d", i),
			[]byte(strings.Repeat("0", 1024*1024)),
		}
		err = client.Call("ServiceFixture.Ping", &req, &res)
		b.StopTimer()
		assert.NoError(b, err)
		assert.Equal(b, req, res)
		b.SetBytes(int64(len(req.Data) * 2))
	}
}
Beispiel #13
0
func BenchmarkRPCGet(b *testing.B) {
	b.StopTimer()
	client, _ := rpc.DialHTTPPath("tcp", "localhost:2000", "/rpc")
	b.StartTimer()
	var reply string
	for i := 0; i < b.N; i++ {
		client.Call("Responder.Get", "test", &reply)
	}
}
Beispiel #14
0
func (c *RPCClient) Connect() (err error) {
	if c.client == nil {
		c.client, err = rpc.DialHTTPPath(
			"tcp",
			c.endpoint.Host,
			c.endpoint.Path+"/rpc")
	}
	return
}
Beispiel #15
0
func NewRunner(rpcService string, port int) *Run {
	client, err := rpc.DialHTTPPath("tcp", fmt.Sprintf(":%d", port), "/")

	if err != nil {
		panic(err.Error())
	}
	return &Run{
		client:     client,
		rpcService: rpcService,
	}
}
Beispiel #16
0
func DialHTTPPath(network string, dialer Address, path string) (*Client, error) {
	client, err := rpc.DialHTTPPath(network, dialer.String(), path)
	if err != nil {
		return nil, err
	}

	return &Client{
		network: network,
		dialer:  dialer,
		mu:      new(sync.RWMutex),
		c:       client,
	}, nil
}
Beispiel #17
0
func MakePingCall(k *Kademlia, remoteHost net.IP, remotePort uint16) bool {
	var localContact *Contact
	var client *rpc.Client
	var remoteAddrStr string
	var err error

	localContact = &(k.ContactInfo)
	remoteAddrStr = remoteHost.String() + ":" + strconv.FormatUint(uint64(remotePort), 10)

	Printf("MakePingCall: From %s --> To %s:%d\n", k, Verbose, localContact.AsString(), remoteHost.String(), remotePort)

	ping := new(Ping)
	ping.MsgID = NewRandomID()
	ping.Sender = CopyContact(localContact)

	pong := new(Pong)

	//Dial the server
	if RunningTests == true {
		var portstr string = RpcPath + strconv.FormatInt(int64(remotePort), 10)
		Printf("test ping to rpcPath:%s\n", k, Verbose, portstr)
		client, err = rpc.DialHTTPPath("tcp", remoteAddrStr, portstr)
	} else {
		client, err = rpc.DialHTTP("tcp", remoteAddrStr)
	}
	if err != nil {
		Printf("Error: MakePingCall, DialHTTP, %s\n", k, Verbose, err)
		return false
	}

	//make rpc
	err = client.Call("Kademlia.Ping", ping, &pong)
	if err != nil {
		Printf("Error: MakePingCall, Call, %s\n", k, Verbose, err)
		return false
	}

	client.Close()

	//log.Printf("About to update with our pong...")
	//log.Printf("update buffer len: %d\n", len(k.UpdateChannel))
	//update the remote node contact information
	k.UpdateChannel <- pong.Sender
	//log.Printf("update buffer len: %d\n", len(k.UpdateChannel))
	//log.Printf("Stuffed out pong in the channel for the sender...")

	return true
}
Beispiel #18
0
func MakeStore(k *Kademlia, remoteContact *Contact, Key ID, Value []byte) bool {
	var client *rpc.Client
	var localContact *Contact
	var storeReq *StoreRequest
	var storeRes *StoreResult
	var remoteAddrStr string
	var remotePortStr string
	var err error

	localContact = &(k.ContactInfo)
	remoteAddrStr = remoteContact.Host.String() + ":" + strconv.Itoa(int(remoteContact.Port))
	dbg.Printf("MakeStore: From %s --> To %s\n", Verbose, localContact.AsString(), remoteContact.AsString())

	storeReq = new(StoreRequest)
	storeReq.MsgID = NewRandomID()
	storeReq.Sender = CopyContact(localContact)
	storeReq.Key = CopyID(Key)
	storeReq.Value = Value

	storeRes = new(StoreResult)

	remotePortStr = strconv.Itoa(int(remoteContact.Port))
	//Dial the server
	if RunningTests == true {
		//if we're running tests, need to DialHTTPPath
		var portstr string = RpcPath + remotePortStr
		client, err = rpc.DialHTTPPath("tcp", remoteAddrStr, portstr)
	} else {
		client, err = rpc.DialHTTP("tcp", remoteAddrStr)
	}
	if err != nil {
		Printf("Error: MakeStore, DialHTTP, %s\n", k, Verbose, err)
		return false
	}
	//make the rpc
	err = client.Call("Kademlia.Store", storeReq, &storeRes)
	if err != nil {
		Printf("Error: MakeStore, Call, %s\n", k, Verbose, err)
		return false
	}

	client.Close()

	//update the remote node contact information
	k.UpdateChannel <- *remoteContact

	return true
}
Beispiel #19
0
// dialRPCClient tries to establish a connection to the server in a safe manner
func (rpcClient *RPCClient) dialRPCClient() (*rpc.Client, error) {
	rpcClient.mu.Lock()
	defer rpcClient.mu.Unlock()
	// After acquiring lock, check whether another thread may not have already dialed and established connection
	if rpcClient.rpcPrivate != nil {
		return rpcClient.rpcPrivate, nil
	}
	rpc, err := rpc.DialHTTPPath("tcp", rpcClient.node, rpcClient.rpcPath)
	if err != nil {
		return nil, err
	} else if rpc == nil {
		return nil, errors.New("No valid RPC Client created after dial")
	}
	rpcClient.rpcPrivate = rpc
	return rpcClient.rpcPrivate, nil
}
Beispiel #20
0
func (server *Server) rpcCallback(subscribeArg *SubscribeArg) func(args ...interface{}) {
	return func(args ...interface{}) {
		client, connErr := rpc.DialHTTPPath("tcp", subscribeArg.ClientAddr, subscribeArg.ClientPath)
		defer client.Close()
		if connErr != nil {
			fmt.Errorf("Dialing", connErr)
		}
		clientArg := new(ClientArg)
		clientArg.Topic = subscribeArg.Topic
		clientArg.Args = args
		var reply bool
		err := client.Call(subscribeArg.ServiceMethod, clientArg, &reply)
		if err != nil {
			fmt.Errorf("Dialing", err)
		}
	}
}
Beispiel #21
0
func New(host, path, name string) *slave {
	// Connect to master
	cl, err := rpc.DialHTTPPath("tcp", host, path)
	if err != nil {
		return nil
	}

	// Register at master
	var result bool
	cl.Call("master.RegisterSlave", name, &result)
	if !result {
		return nil
	}

	return &slave{
		client: cl,
		name:   name,
	}
}
Beispiel #22
0
//calls the RPC function 'CreateCircuit' on the next DryMartini in the route
func MakeCircuitCreateCall(dm *DryMartini, nextNodeAddrStr string, encryptedArray [][]byte) bool {
	var client *rpc.Client
	var err error

	dbg.Printf("MakeCircuitCreateCall: %s\n", Verbose, nextNodeAddrStr)
	if kademlia.RunningTests == true {
		//log.Printf("Unimplemented\n")
		//panic(1)
		var nextNodePort string = strings.Split(nextNodeAddrStr, ":")[1]
		if nextNodePort == "" {
			dbg.Printf("error getting next port: MakeSendCall\n", ERRORS)
			return false
		}
		var portstr string = kademlia.RpcPath + nextNodePort
		dbg.Printf("test makeCircuitCreateCall to rpcPath:%s\n", Verbose, portstr)
		client, err = rpc.DialHTTPPath("tcp", nextNodeAddrStr, portstr)
	} else {
		client, err = rpc.DialHTTP("tcp", nextNodeAddrStr)
	}
	if err != nil {
		dbg.Printf("Error: MakeCircuitCreateCall, DialHTTP, %s\n", ERRORS, err)
		return false
	}

	//make rpc
	var req *CCRequest = new(CCRequest)
	req.EncryptedData = encryptedArray
	var res *CCResponse = new(CCResponse)

	err = client.Call("DryMartini.CreateCircuit", req, res)
	if err != nil {
		dbg.Printf("Error: CreateCircuit, Call, %s\n", ERRORS, err)
		return false
	}
	dbg.Printf("got DistributeSymm response: %s:%v\n", Verbose, nextNodeAddrStr, res.Success)

	client.Close()

	return res.Success
}
Beispiel #23
0
//makes a DryMartini.ServeDrink call on address with the Olive data, returning success and returned data if any
func MakeSendCall(dataLump Olive, nextNodeAddrStr string) (bool, []byte) {
	var client *rpc.Client
	var err error

	dbg.Printf("MakeSendCall:: next: %s!", Verbose, nextNodeAddrStr)
	if kademlia.RunningTests == true {
		//log.Printf("Unimplemented\n")
		//panic(1)
		var nextNodePort string = strings.Split(nextNodeAddrStr, ":")[1]
		if nextNodePort == "" {
			log.Printf("error getting next port: MakeSendCall\n")
			panic(1)
		}
		var portstr string = kademlia.RpcPath + nextNodePort
		log.Printf("test MakeSendCall to rpcPath:%s\n", portstr)
		client, err = rpc.DialHTTPPath("tcp", nextNodeAddrStr, portstr)
	} else {
		client, err = rpc.DialHTTP("tcp", nextNodeAddrStr)
	}
	if err != nil {
		log.Printf("Error: MakeSendCall, DialHTTP, %s\n", err)
		return false, nil
	}

	//make rpc
	var res *ServerResp = new(ServerResp)
	var req *ServerData = new(ServerData)
	req.Sent = dataLump

	err = client.Call("DryMartini.ServeDrink", req, res)
	if err != nil {
		log.Printf("Error: SendCall, Call, %s\n", err)
		return false, nil
	}
	dbg.Printf("got SendCall response: %s:%v\n", Verbose, nextNodeAddrStr, res.Success)

	client.Close()

	return res.Success, res.Data
}
Beispiel #24
0
func Test_Proto_HTTP(t *testing.T) {
	t.Skip()
	srv := &httpTestServer{&baseTestServer{}}
	port, err := srv.listen()
	assert.NoError(t, err)
	srv.start()
	defer srv.Stop()

	client, err := rpc.DialHTTPPath("tcp",
		fmt.Sprintf("127.0.0.1:%d", port), "/v1/rpc")
	assert.NoError(t, err)
	defer client.Close()

	var res TestMessage
	req := TestMessage{
		"12345678910",
		[]byte("mama myla ramu"),
	}
	err = client.Call("ServiceFixture.Ping", &req, &res)
	assert.NoError(t, err)
	assert.Equal(t, req, res)
}
Beispiel #25
0
func (client *Client) doSubscribe(topic string, fn interface{}, serverAddr, serverPath string, subscribeType SubscribeType) {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("Server not found -", r)
		}
	}()

	rpcClient, err := rpc.DialHTTPPath("tcp", serverAddr, serverPath)
	defer rpcClient.Close()
	if err != nil {
		fmt.Errorf("dialing:", err)
	}
	args := &SubscribeArg{client.address, client.path, PublishService, subscribeType, topic}
	reply := new(bool)
	err = rpcClient.Call(RegisterService, args, reply)
	if err != nil {
		fmt.Errorf("Register error:", err)
	}
	if *reply {
		client.eventBus.Subscribe(topic, fn)
	}
}
Beispiel #26
0
// Initialize new rpc client.
func newRPCClient(networkPath string) (StorageAPI, error) {
	// Input validation.
	if networkPath == "" || strings.LastIndex(networkPath, ":") == -1 {
		return nil, errInvalidArgument
	}

	// TODO validate netAddr and netPath.
	netAddr, netPath := splitNetPath(networkPath)

	// Dial minio rpc storage http path.
	rpcClient, err := rpc.DialHTTPPath("tcp", netAddr, storageRPCPath)
	if err != nil {
		return nil, err
	}

	// Initialize http client.
	httpClient := &http.Client{
		// Setting a sensible time out of 6minutes to wait for
		// response headers. Request is pro-actively cancelled
		// after 6minutes if no response was received from server.
		Timeout:   6 * time.Minute,
		Transport: http.DefaultTransport,
	}

	// Initialize network storage.
	ndisk := &networkStorage{
		netScheme:  "http", // TODO: fix for ssl rpc support.
		netAddr:    netAddr,
		netPath:    netPath,
		rpcClient:  rpcClient,
		httpClient: httpClient,
	}

	// Returns successfully here.
	return ndisk, nil
}
Beispiel #27
0
func TestServerRPC(t *testing.T) {
	hooksServerPort := 61322
	var addr = fmt.Sprintf(":%d", hooksServerPort)
	if os.Getenv("RUN_HOOKS") == "1" {
		server := NewServer(&run)
		fmt.Println("Running the server")
		server.Serve()
		defer server.Listener.Close()
		return
	}

	cmd := exec.Command(os.Args[0], "-test.run=TestServerRPC", fmt.Sprintf("-port=%d", hooksServerPort))
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.Env = append(os.Environ(), "RUN_HOOKS=1")

	go func() {
		err := cmd.Run()
		fmt.Println("Command exited with error " + err.Error())
	}()

	time.Sleep(2000 * time.Millisecond)
	client, err := rpc.DialHTTPPath("tcp", addr, "/")
	defer cmd.Process.Kill()
	defer client.Close()
	if err != nil {
		log.Fatal("dialing:", err)
	}

	testCases := []struct {
		Method string
		args   interface{}
		reply  interface{}
	}{
		{
			Method: "RunBeforeEach",
			args:   trans.Transaction{Name: "Test"},
			reply:  trans.Transaction{},
		},
		{
			Method: "RunBefore",
			args:   trans.Transaction{Name: "Test"},
			reply:  trans.Transaction{},
		},
		{
			Method: "RunBeforeValidation",
			args:   trans.Transaction{Name: "Test"},
			reply:  trans.Transaction{},
		},
		{
			Method: "RunBeforeEachValidation",
			args:   trans.Transaction{Name: "Test"},
			reply:  trans.Transaction{},
		},
		{
			Method: "RunAfterEach",
			args:   trans.Transaction{Name: "Test"},
			reply:  trans.Transaction{},
		},
		{
			Method: "RunAfter",
			args:   trans.Transaction{Name: "Test"},
			reply:  trans.Transaction{},
		},
	}

	for _, test := range testCases {
		args := test.args.(trans.Transaction)
		reply := test.reply.(trans.Transaction)
		method := test.Method
		err = client.Call("DummyRunner."+method, args, &reply)
		if err != nil {
			t.Errorf("rpc client failed to connect to server: %s", err.Error())
		}

		// DummyRunner will set the transaction to the value of the args variable.
		// See rpc.go for more detail.
		if reply.Name != "Test" {
			t.Errorf("RPC method %s was never invoked", method)
		}
	}

	// Testing for RunBeforeAll and RunAfter All
	allCases := []struct {
		Method string
		args   []*trans.Transaction
	}{
		{
			Method: "RunBeforeAll",
			args:   []*trans.Transaction{&trans.Transaction{Name: "Test"}},
		},
		{
			Method: "RunAfterAll",
			args:   []*trans.Transaction{&trans.Transaction{Name: "Test"}},
		},
	}

	for _, test := range allCases {
		args := test.args
		var reply []*trans.Transaction
		method := test.Method
		err = client.Call("DummyRunner."+method, args, &reply)
		if err != nil {
			t.Errorf("rpc client failed to connect to server: %s", err.Error())
		}

		// DummyRunner will set the transaction to the value of the args variable.
		// See rpc.go for more detail.
		if reply[0].Name != "Test" {
			t.Errorf("RPC method %s was never invoked", method)
		}
	}
}
Beispiel #28
0
//func MakeFindValue(k *Kademlia, remoteContact *Contact, Key ID, fvChan chan *FindValueCallResponse) (bool, []byte, *[]FoundNode) {
func MakeFindValueCall(k *Kademlia, remoteContact *Contact, Key ID, fvChan chan *FindStarCallResponse) {
	var findValueReq *FindValueRequest
	var findValueRes *FindValueResult
	var remoteAddrStr string
	var remotePortStr string
	var client *rpc.Client
	var localContact *Contact
	var resultSet *FindStarCallResponse
	var err error

	localContact = &(k.ContactInfo)
	remoteAddrStr = remoteContact.Host.String() + ":" + strconv.Itoa(int(remoteContact.Port))
	dbg.Printf("MakeFindValue[%s]: From %s --> To %s\n", Verbose, Key.AsString(), localContact.AsString(), remoteContact.AsString())

	findValueReq = new(FindValueRequest)
	findValueReq.MsgID = NewRandomID()
	findValueReq.Sender = CopyContact(localContact)
	findValueReq.Key = CopyID(Key)

	findValueRes = new(FindValueResult)

	resultSet = new(FindStarCallResponse)
	resultSet.ReturnedFVRes = findValueRes
	resultSet.ReturnedFNRes = nil
	resultSet.Responder = remoteContact.ContactToFoundNode()
	resultSet.Responded = false

	remotePortStr = strconv.Itoa(int(remoteContact.Port))
	//Dial the server
	if RunningTests == true {
		//if we're running tests, need to DialHTTPPath
		var portstr string = RpcPath + remotePortStr
		//log.Printf("test FindNodeValue to rpcPath:%s\n", portstr)
		client, err = rpc.DialHTTPPath("tcp", remoteAddrStr, portstr)
	} else {
		client, err = rpc.DialHTTP("tcp", remoteAddrStr)
	}
	if err != nil {
		dbg.Printf("Error: MakeFindValueCall, DialHTTP, %s\n", Verbose, err)
		fvChan <- resultSet
		return
	}

	//make rpc
	err = client.Call("Kademlia.FindValue", findValueReq, &findValueRes)
	if err != nil {
		Printf("Error: MakeFindValue, Call, %s\n", k, Verbose, err)
		fvChan <- resultSet
		return
	}

	//Mark the result as being good
	resultSet.Responded = true

	fvChan <- resultSet
	client.Close()

	//update the remote node contact information
	k.UpdateChannel <- *remoteContact

	return
}
Beispiel #29
0
//Makes a FindNodeCall on remoteContact. returns list of KClosest nodes on that contact, and the id of the remote node
//REVIEW
//George: On the ground that this should be an asynchronous call, I modified the definition of the function
//func MakeFindNodeCall(localContact *Contact, remoteContact *Contact, NodeChan chan *FindNodeCallResponse) (*FindNodeResult, bool) {
func MakeFindNodeCall(k *Kademlia, remoteContact *Contact, searchKey ID, NodeChan chan *FindStarCallResponse) {
	var fnRequest *FindNodeRequest
	var fnResult *FindNodeResult
	var remoteAddrStr string
	var remotePortStr string
	var client *rpc.Client
	var resultSet *FindStarCallResponse
	var err error
	var localContact *Contact

	localContact = &(k.ContactInfo)
	remoteAddrStr = remoteContact.Host.String() + ":" + strconv.Itoa(int(remoteContact.Port))
	dbg.Printf("MakeFindNodeCall: From %s --> To %s\n", Verbose, localContact.AsString(), remoteContact.AsString())

	fnRequest = new(FindNodeRequest)
	fnRequest.MsgID = NewRandomID()
	fnRequest.Sender = CopyContact(localContact)
	fnRequest.NodeID = CopyID(searchKey)

	fnResult = new(FindNodeResult)

	resultSet = new(FindStarCallResponse)
	resultSet.ReturnedFNRes = fnResult
	resultSet.ReturnedFVRes = nil
	resultSet.Responder = remoteContact.ContactToFoundNode()
	resultSet.Responded = false

	remotePortStr = strconv.Itoa(int(remoteContact.Port))
	//Dial the server
	if RunningTests == true {
		//if we're running tests, need to DialHTTPPath
		var portstr string = RpcPath + remotePortStr
		//log.Printf("test FindNodeCall to rpcPath:%s\n", portstr)
		client, err = rpc.DialHTTPPath("tcp", remoteAddrStr, portstr)
	} else {
		client, err = rpc.DialHTTP("tcp", remoteAddrStr)
	}
	if err != nil {
		dbg.Printf("Error: MakeFindNodeCall, DialHTTP, %s\n", Verbose, err)
		NodeChan <- resultSet
		return
	}

	err = client.Call("Kademlia.FindNode", fnRequest, &fnResult)
	if err != nil {
		Printf("Error: MakeFindNodeCall, Call, %s\n", k, Verbose, err)
		NodeChan <- resultSet
		return
	}

	//if you get any nodes update you kbuckets with them
	//Jack: REVIEW: I'm not sure if we do want to update on only
	//'heard of' nodes. Only when we make direct contact no?
	//Also look at similar block in MakeFindValueCall
	/*
		for _, node := range fnResult.Nodes {
			k.UpdateChannel <- *(node.FoundNodeToContact())
		}*/

	// Mark the result as being good
	resultSet.Responded = true

	NodeChan <- resultSet
	client.Close()

	//update the remote node contact information
	k.UpdateChannel <- *remoteContact

	return
}