1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 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
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Copyright 2018 MaidSafe.net limited.
//
// This SAFE Network Software is licensed to you under the MIT license <LICENSE-MIT
// http://opensource.org/licenses/MIT> or the Modified BSD license <LICENSE-BSD
// https://opensource.org/licenses/BSD-3-Clause>, at your option. This file may not be copied,
// modified, or distributed except according to those terms. Please review the Licences for the
// specific language governing permissions and limitations relating to use of the SAFE Network
// Software.

use common::Uid;
use main::Config;
use mio::Token;
use net2::TcpBuilder;
use std::net::SocketAddr;

// ========================================================================================
//                                     ConnectionId
// ========================================================================================
#[derive(Debug, Clone, Copy)]
pub struct ConnectionId {
    pub active_connection: Option<Token>,
    pub currently_handshaking: usize,
}

// ========================================================================================
//                                   ConnectionInfoResult
// ========================================================================================
/// The result of a `Service::prepare_contact_info` call.
#[derive(Debug)]
pub struct ConnectionInfoResult<UID> {
    /// The token that was passed to `prepare_connection_info`.
    pub result_token: u32,
    /// The new contact info, if successful.
    pub result: ::Res<PrivConnectionInfo<UID>>,
}

// ========================================================================================
//                                     PrivConnectionInfo
// ========================================================================================
/// Contact info generated by a call to `Service::prepare_contact_info`.
#[derive(Debug)]
pub struct PrivConnectionInfo<UID> {
    #[doc(hidden)]
    pub id: UID,
    #[doc(hidden)]
    pub for_direct: Vec<SocketAddr>,
    #[doc(hidden)]
    pub for_hole_punch: Vec<SocketAddr>,
    #[doc(hidden)]
    pub hole_punch_socket: Option<TcpBuilder>,
}

impl<UID: Uid> PrivConnectionInfo<UID> {
    /// Use private connection info to create public connection info that can be shared with the
    /// peer.
    pub fn to_pub_connection_info(&self) -> PubConnectionInfo<UID> {
        PubConnectionInfo {
            for_hole_punch: self.for_hole_punch.clone(),
            for_direct: self.for_direct.clone(),
            id: self.id,
        }
    }
}

// ========================================================================================
//                                     PubConnectionInfo
// ========================================================================================
/// Contact info used to connect to another peer.
#[derive(Debug, Serialize, Deserialize)]
pub struct PubConnectionInfo<UID> {
    #[doc(hidden)]
    pub id: UID,
    #[doc(hidden)]
    pub for_hole_punch: Vec<SocketAddr>,
    #[doc(hidden)]
    pub for_direct: Vec<SocketAddr>,
}

impl<UID: Uid> PubConnectionInfo<UID> {
    /// Returns the `UID` of the node that created this connection info.
    pub fn id(&self) -> UID {
        self.id
    }
}

// ========================================================================================
//                                     ConfigWrapper
// ========================================================================================
#[derive(Default)]
pub struct ConfigWrapper {
    pub cfg: Config,
    pub is_modified_for_next_refresh: bool,
}

impl ConfigWrapper {
    pub fn new(cfg: Config) -> Self {
        Self {
            cfg,
            is_modified_for_next_refresh: false,
        }
    }

    pub fn check_for_update_and_mark_modified(&mut self, new_cfg: Config) {
        if self.cfg != new_cfg {
            self.cfg = new_cfg;
            self.is_modified_for_next_refresh = true;
        }
    }

    /// Checks if `ActiveConnection` refresh is needed.
    pub fn check_for_refresh_and_reset_modified(&mut self, new_cfg: Config) -> bool {
        let should_refresh = if self.cfg != new_cfg {
            self.cfg = new_cfg;
            true
        } else {
            self.is_modified_for_next_refresh
        };

        self.is_modified_for_next_refresh = false;
        should_refresh
    }
}