Diff
Not logged in

Differences From Artifact [d34a198814]:

To Artifact [1a50ef0aeb]:


12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
..
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.
//
// Please review the Licences for the specific language governing permissions and limitations
// relating to use of the SAFE Network Software.

use common::{BootstrapDenyReason, Core, ExternalReachability, Message, NameHash, Priority, Socket,
             State};
use main::PeerId;
use mio::{Poll, PollOpt, Ready, Token};
use rust_sodium::crypto::box_::PublicKey;
use std::any::Any;
use std::cell::RefCell;
use std::mem;
use std::net::SocketAddr;
use std::rc::Rc;

pub type Finish = Box<FnMut(&mut Core,
                            &Poll,
                            Token,
                            Result<(Socket, SocketAddr, PeerId),
                                   (SocketAddr, Option<BootstrapDenyReason>)>)>;

pub struct TryPeer {
    token: Token,
    peer: SocketAddr,
    socket: Socket,
    request: Option<(Message, Priority)>,
    finish: Finish,
}

impl TryPeer {
    pub fn start(core: &mut Core,
                 poll: &Poll,
                 peer: SocketAddr,
                 our_pk: PublicKey,
                 name_hash: NameHash,
                 ext_reachability: ExternalReachability,
                 finish: Finish)
                 -> ::Res<Token> {
        let socket = Socket::connect(&peer)?;
        let token = core.get_new_token();

        poll.register(&socket,
                      token,
                      Ready::error() | Ready::hup() | Ready::writable(),
                      PollOpt::edge())?;

        let state = TryPeer {
            token: token,
            peer: peer,
            socket: socket,
            request: Some((Message::BootstrapRequest(our_pk, name_hash, ext_reachability), 0)),
            finish: finish,
        };

        let _ = core.insert_state(token, Rc::new(RefCell::new(state)));

        Ok(token)
    }

    fn write(&mut self, core: &mut Core, poll: &Poll, msg: Option<(Message, Priority)>) {
        if self.socket.write(poll, self.token, msg).is_err() {
            self.handle_error(core, poll, None);
        }
    }

    fn read(&mut self, core: &mut Core, poll: &Poll) {
        match self.socket.read::<Message>() {
            Ok(Some(Message::BootstrapGranted(peer_pk))) => {
                let _ = core.remove_state(self.token);
                let token = self.token;
                let socket = mem::replace(&mut self.socket, Socket::default());
                let data = (socket, self.peer, PeerId(peer_pk));
                (*self.finish)(core, poll, token, Ok(data));
            }
            Ok(Some(Message::BootstrapDenied(reason))) => {
                self.handle_error(core, poll, Some(reason))
            }
            Ok(None) => (),
            Ok(Some(_)) | Err(_) => self.handle_error(core, poll, None),
................................................................................
        self.terminate(core, poll);
        let token = self.token;
        let peer = self.peer;
        (*self.finish)(core, poll, token, Err((peer, reason)));
    }
}

impl State for TryPeer {
    fn ready(&mut self, core: &mut Core, poll: &Poll, kind: Ready) {
        if kind.is_error() {
            return self.handle_error(core, poll, None);
        } else if kind.is_writable() || kind.is_readable() {
            if kind.is_writable() {
                let req = self.request.take();
                self.write(core, poll, req);







|
<

<






|
|
|
|
|

|



|
|


|



|


|













|








|






|
|



|







 







|







12
13
14
15
16
17
18
19

20

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
..
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.
//
// Please review the Licences for the specific language governing permissions and limitations
// relating to use of the SAFE Network Software.

use common::{BootstrapDenyReason, Core, ExternalReachability, Message, NameHash, Priority, Socket,
             State, Uid};

use mio::{Poll, PollOpt, Ready, Token};

use std::any::Any;
use std::cell::RefCell;
use std::mem;
use std::net::SocketAddr;
use std::rc::Rc;

pub type Finish<UID> = Box<FnMut(&mut Core,
                                 &Poll,
                                 Token,
                                 Result<(Socket, SocketAddr, UID),
                                        (SocketAddr, Option<BootstrapDenyReason>)>)>;

pub struct TryPeer<UID: Uid> {
    token: Token,
    peer: SocketAddr,
    socket: Socket,
    request: Option<(Message<UID>, Priority)>,
    finish: Finish<UID>,
}

impl<UID: Uid> TryPeer<UID> {
    pub fn start(core: &mut Core,
                 poll: &Poll,
                 peer: SocketAddr,
                 our_uid: UID,
                 name_hash: NameHash,
                 ext_reachability: ExternalReachability,
                 finish: Finish<UID>)
                 -> ::Res<Token> {
        let socket = Socket::connect(&peer)?;
        let token = core.get_new_token();

        poll.register(&socket,
                      token,
                      Ready::error() | Ready::hup() | Ready::writable(),
                      PollOpt::edge())?;

        let state = TryPeer {
            token: token,
            peer: peer,
            socket: socket,
            request: Some((Message::BootstrapRequest(our_uid, name_hash, ext_reachability), 0)),
            finish: finish,
        };

        let _ = core.insert_state(token, Rc::new(RefCell::new(state)));

        Ok(token)
    }

    fn write(&mut self, core: &mut Core, poll: &Poll, msg: Option<(Message<UID>, Priority)>) {
        if self.socket.write(poll, self.token, msg).is_err() {
            self.handle_error(core, poll, None);
        }
    }

    fn read(&mut self, core: &mut Core, poll: &Poll) {
        match self.socket.read::<Message<UID>>() {
            Ok(Some(Message::BootstrapGranted(peer_uid))) => {
                let _ = core.remove_state(self.token);
                let token = self.token;
                let socket = mem::replace(&mut self.socket, Socket::default());
                let data = (socket, self.peer, peer_uid);
                (*self.finish)(core, poll, token, Ok(data));
            }
            Ok(Some(Message::BootstrapDenied(reason))) => {
                self.handle_error(core, poll, Some(reason))
            }
            Ok(None) => (),
            Ok(Some(_)) | Err(_) => self.handle_error(core, poll, None),
................................................................................
        self.terminate(core, poll);
        let token = self.token;
        let peer = self.peer;
        (*self.finish)(core, poll, token, Err((peer, reason)));
    }
}

impl<UID: Uid> State for TryPeer<UID> {
    fn ready(&mut self, core: &mut Core, poll: &Poll, kind: Ready) {
        if kind.is_error() {
            return self.handle_error(core, poll, None);
        } else if kind.is_writable() || kind.is_readable() {
            if kind.is_writable() {
                let req = self.request.take();
                self.write(core, poll, req);