Skip to content

Conversation

@NamsooCho
Copy link
Member

No description provided.

/// relay NatPingRequest/NatPingResponse to target peer
pub fn relay_nat_ping_packet(&self, addr: &SocketAddr, request: DhtRequest) -> IoFuture<()> {
let packet = DhtPacket::DhtRequest(request);
Box::new(self.tx.clone() // clone tx sender for 1 send only
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create method send_to as method send but with explicit addr-argument. Method send should use send_to inside it passing self.addr as addr.

// Create a channel for this peer
let (tx, rx) = mpsc::unbounded();
// Add or update an entry for this `Peer` in the connected client hashmap.
let client = node.borrow_mut().add_client(&addr, &packet, tx);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replace tx with tx_sink_c. You don't need to create let (tx, rx) = mpsc::unbounded();, pass tx into add_client, create let writer = rx future. Just use tx_sink_c.

.build()
;

let relay = rx_sink
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rename relay -> writer

@coveralls
Copy link

coveralls commented Feb 26, 2018

Pull Request Test Coverage Report for Build 388

  • 0 of 0 (NaN%) changed or added relevant lines in 0 files are covered.
  • 44 unchanged lines in 3 files lost coverage.
  • Overall coverage decreased (-1.5%) to 95.62%

Files with Coverage Reduction New Missed Lines %
toxcore/dht_new/codec.rs 3 93.18%
toxcore/dht_new/kbucket.rs 11 97.13%
toxcore/dht_new/packet.rs 30 95.26%
Totals Coverage Status
Change from base Build 377: -1.5%
Covered Lines: 4082
Relevant Lines: 4269

💛 - Coveralls

}

/// add new client entry in connected_clients hashmap
pub fn add_client(&mut self, addr: &SocketAddr, packet: &Option<DhtPacket>, tx: Tx) -> Client {
Copy link
Member

@kpp kpp Feb 26, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you actually need to add client? To create it? It worth to keep clients in tcp server, because TCP connection is stateful and we actually need to keep tx for each client to send the data into appropriate TCP connection linked to this client. On the other hand, we do have 1 UDP connection and we send data through it with the only one difference: addr arg.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch.
I was missing it.
UDP connection doesn't need to be saved.

}
client.clone()
} else {
let precomputed_key = encrypt_precompute(&pk, &self.sk);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling encrypt_precompute only once is a good performance optimization, but do we really need this optimization for now? We may do this optimization next PR

// Add or update an entry for this `Peer` in the connected client hashmap.
let client = node.borrow_mut().add_client(&addr, &packet, tx);

let _ = node.borrow_mut().handle_packet(&(addr, packet.unwrap()), client);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you pass &(addr, packet) by ref? Try to pass values by value.

pub mod kbucket;
pub mod packed_node;
pub mod codec;
pub mod dht_node;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it have to be named as dht_node while the next line is client? Shouldn't it be server?

/// socket address of peer
pub addr: SocketAddr,
/// tx split of channel to send packet to this peer via udp socket
pub tx: Tx,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say the server struct should store tx but not the client since it's shared between all clients. And the same for send/send_to methods.

if let DhtRequestPayload::NatPingResponse(nat_ping_resp_payload) = packet.get_payload(&alice.sk).unwrap() {
assert_eq!(nat_ping_resp_payload.id, nat_req.id);
} else {
panic!("can not occur");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unreachable! :)

DhtPacket::NodesRequest(nodes_request) => nodes_request.pk,
DhtPacket::NodesResponse(nodes_response) => nodes_response.pk,
DhtPacket::DhtRequest(dht_request) => dht_request.spk,
_ => unreachable!("Received packet is not a DhtPacket"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually it's not unreachable because it depends on how this method is called, so panic is preferable in such cases.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But why we can't just get pk when we need it from the packet directly?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But why we can't just get pk when we need it from the packet directly?

How?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means that we should get it only after matching on packet kind but not before. So we can try to move the client inside the server and get exact client by pk from packet in each handle_* method if we need it. Not sure how exact it will look like though, but perhaps it worth to try.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good Idea.
But I would like to try this idea on next PR.:)

let handler = stream.for_each(move |(addr, packet)| {
let tx_c = tx.clone();
let pk = Server::get_pk(&packet.clone().unwrap());
let client = node.borrow_mut().create_client(&addr, pk, tx_c);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to me that server should take only packet and maybe socket address but not the whole client. It should manage clients inside so the user of server api wouldn't even know about it.

}

#[cfg(test)]
mod test {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mod tests

}
}

// handle_ping_resp()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You forgot to mark this function as #[test]

This was referenced Feb 27, 2018
pk: pk,
addr: addr,
precomputed_key: precomputed_key,
ping_id: 0xFFFFFFFFFFFFFFFF,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why oxfff?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because, can't set ping_id of Client to desired value.
So, can't check in test code.

Copy link
Member

@kpp kpp Feb 28, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But why did you chose such a value? Why not 0?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From implementing perspective, Client is useful for containing Tx(mpsc), SocketAddr, pk, ping_id,...
Current kbucket contains only SocektAddr, PublicKey.
Maybe It is better to extend kbucket.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From implementing perspective, Client is useful for containing Tx(mpsc), SocketAddr, pk, ping_id,...

And why does it contain ping_id? It's useless if you have new client for every packet.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it!!
Thanks for your comments.
I will try to remove Client struct.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No problem. It's not necessary have to be removed though. Just perhaps if it contains few fields we can just pass them as args.

Copy link
Member

@kpp kpp Mar 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good job, guys. @NamsooCho And please, don't init ping_id with 0xffff

let nat_res = NatPingResponse { id: random_u64() };
let nat_payload = DhtRequestPayload::NatPingResponse(nat_res);
let dht_req = DhtRequest::new(&client.precomputed_key, &client.pk, &client.pk, nat_payload.clone());
client.relay_nat_ping_packet(tx, &client.addr, dht_req).wait().unwrap();
Copy link
Member

@kpp kpp Feb 28, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why relay_nat_ping_packet?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is used both for nat_ping_request/response.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still do not understand why you used relay word here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the rpk is not same as this DHT node, it relay to proper DHT node.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resend?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

send?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

Function to handle incoming packets. If there is a response packet,
send back it to the peer.
*/
pub fn handle_packet(&mut self, packet: DhtUdpPacket) -> IoFuture<()>
Copy link
Member

@kpp kpp Feb 28, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A DhtUdpPacket is a tuple of (packet, addr). Please destructure it right in arg, so there will be no packet.1 or packet.0 calls.

@tox-rs tox-rs deleted a comment from NamsooCho Feb 28, 2018
"Crypto initialization failed."));
}

let (pk, sk) = gen_keypair();
Copy link
Member

@kpp kpp Feb 28, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have to get this info via args, because we want to start a node with the given keypair.

pub fn handle_packet(&mut self, packet: DhtUdpPacket) -> IoFuture<()>
{
let pk = Server::get_pk(&packet.1.clone());
let client = self.create_client(&packet.0, pk);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have a look at #33 . You logic is incorrect for BootstrapInfo packet

},
DhtPacket::PingResponse(packet) => {
debug!("Received ping response");
let client = self.get_client(&packet.pk);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not 100% for sure the client will be in cache

},
DhtPacket::NodesResponse(packet) => {
debug!("Received NodesResponse");
let client = self.get_client(&packet.pk);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not 100% for sure the client will be in cache

},
Ok(DhtRequestPayload::NatPingResponse(pl)) => {
debug!("Received nat ping response");
let client = self.get_client(&dr.spk);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not 100% for sure the client will be in cache

Client::new(precomputed_key, pk, addr.clone(), self.tx.clone())
}
/// get client from cache
pub fn get_client(&self, pk: &PublicKey) -> Option<Client> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

create_client const you almost zero CPU. Please, don't precache clients for now.

Copy link
Member Author

@NamsooCho NamsooCho Mar 6, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

send PingRequest to peer A with ping_id = 0x01.
send PingRequest to peer B with ping_id = 0x02.
received PingResponse from peer B -> handle_packet() need client.



/*!
Hold peer info. connected.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wtf

Copy link
Member

@kpp kpp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approve for now. There is a lot of TODOs, but the seems like a good start

@kpp kpp merged commit 09fb4ca into tox-rs:master Mar 6, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants