sipaccountbase.h 12.6 KB
Newer Older
1
/*
2
 *  Copyright (C) 2014-2016 Savoir-faire Linux Inc.
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
 *
 *  Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
 */

#ifndef SIPACCOUNTBASE_H
#define SIPACCOUNTBASE_H

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "account.h"
29 30

#include "sip_utils.h"
31
#include "ip_utils.h"
32
#include "noncopyable.h"
33
#include "security/certstore.h"
Adrien Béraud's avatar
Adrien Béraud committed
34
#include "im/message_engine.h"
35 36

#include <pjsip/sip_types.h>
Edric Milaret's avatar
Edric Milaret committed
37
#include <opendht/value.h>
38

39
#include <array>
40 41
#include <vector>
#include <map>
42
#include <memory>
43

44
namespace ring {
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

namespace Conf {
    // SIP specific configuration keys
    const char *const INTERFACE_KEY = "interface";
    const char *const PORT_KEY = "port";
    const char *const PUBLISH_ADDR_KEY = "publishAddr";
    const char *const PUBLISH_PORT_KEY = "publishPort";
    const char *const SAME_AS_LOCAL_KEY = "sameasLocal";
    const char *const DTMF_TYPE_KEY = "dtmfType";
    const char *const SERVICE_ROUTE_KEY = "serviceRoute";
    const char *const PRESENCE_ENABLED_KEY = "presenceEnabled";
    const char *const PRESENCE_PUBLISH_SUPPORTED_KEY = "presencePublishSupported";
    const char *const PRESENCE_SUBSCRIBE_SUPPORTED_KEY = "presenceSubscribeSupported";
    const char *const PRESENCE_STATUS_KEY = "presenceStatus";
    const char *const PRESENCE_NOTE_KEY = "presenceNote";

    // TODO: write an object to store tls params which implement serializable
    const char *const TLS_KEY = "tls";
    const char *const TLS_PORT_KEY = "tlsPort";
    const char *const CERTIFICATE_KEY = "certificate";
    const char *const CALIST_KEY = "calist";
    const char *const CIPHERS_KEY = "ciphers";
    const char *const TLS_ENABLE_KEY = "enable";
    const char *const METHOD_KEY = "method";
    const char *const TIMEOUT_KEY = "timeout";
    const char *const TLS_PASSWORD_KEY = "password";
    const char *const PRIVATE_KEY_KEY = "privateKey";
    const char *const REQUIRE_CERTIF_KEY = "requireCertif";
    const char *const SERVER_KEY = "server";
    const char *const VERIFY_CLIENT_KEY = "verifyClient";
    const char *const VERIFY_SERVER_KEY = "verifyServer";

    const char *const STUN_ENABLED_KEY = "stunEnabled";
    const char *const STUN_SERVER_KEY = "stunServer";
79 80
    const char *const TURN_ENABLED_KEY = "turnEnabled";
    const char *const TURN_SERVER_KEY = "turnServer";
81 82 83
    const char *const TURN_SERVER_UNAME_KEY = "turnServerUserName";
    const char *const TURN_SERVER_PWD_KEY = "turnServerPassword";
    const char *const TURN_SERVER_REALM_KEY = "turnServerRealm";
84 85 86 87 88 89 90
    const char *const CRED_KEY = "credential";
    const char *const AUDIO_PORT_MIN_KEY = "audioPortMin";
    const char *const AUDIO_PORT_MAX_KEY = "audioPortMax";
    const char *const VIDEO_PORT_MIN_KEY = "videoPortMin";
    const char *const VIDEO_PORT_MAX_KEY = "videoPortMax";
}

91 92
typedef std::vector<pj_ssl_cipher> CipherArray;

93 94 95 96 97 98 99
class SIPVoIPLink;
class SIPCall;

/**
 * @file sipaccount.h
 * @brief A SIP Account specify SIP specific functions and object = SIPCall/SIPVoIPLink)
 */
100

101 102 103 104 105 106
enum class MatchRank {NONE, PARTIAL, FULL};

class SIPAccountBase : public Account {
public:
    constexpr static const char * const OVERRTP_STR = "overrtp";
    constexpr static const char * const SIPINFO_STR = "sipinfo";
107 108
    constexpr static unsigned MAX_PORT {65536};
    constexpr static unsigned HALF_MAX_PORT {MAX_PORT / 2};
109 110 111 112 113 114 115

    /**
     * Constructor
     * @param accountID The account identifier
     */
    SIPAccountBase(const std::string& accountID);

116
    virtual ~SIPAccountBase();
117

118 119 120 121 122 123 124 125
    /**
     * Create incoming SIPCall.
     * @param[in] id The ID of the call
     * @return std::shared_ptr<T> A shared pointer on the created call.
     *      The type of this instance is given in template argument.
     *      This type can be any base class of SIPCall class (included).
     */
    virtual std::shared_ptr<SIPCall>
126
    newIncomingCall(const std::string& from) = 0;
127 128 129 130 131

    virtual bool isStunEnabled() const {
        return false;
    }

132
    virtual pj_str_t getStunServerName() const { return pj_str_t {nullptr, 0}; };
133 134 135 136 137 138 139

    virtual pj_uint16_t getStunPort() const { return 0; };

    virtual std::string getDtmfType() const {
        return dtmfType_;
    }

Adrien Béraud's avatar
Adrien Béraud committed
140 141 142 143 144 145
    /**
     * Determine if TLS is enabled for this account. TLS provides a secured channel for
     * SIP signalization. It is independant than the media encription provided by SRTP or ZRTP.
     */
    virtual bool isTlsEnabled() const {
        return false;
146 147 148
    }

    /**
149
     * Get the local interface name on which this account is bound.
150
     */
151 152
    const std::string& getLocalInterface() const {
        return interface_;
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
    }

    /**
     * Get the public IP address set by the user for this account.
     * If this setting is not provided, the local bound adddress
     * will be used.
     * @return std::string The public IPv4 or IPv6 address formatted in standard notation.
     */
    std::string getPublishedAddress() const {
        return publishedIpAddress_;
    }

    IpAddr getPublishedIpAddress() const {
        return publishedIp_;
    }

169
    void setPublishedAddress(const IpAddr& ip_addr);
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188

    /**
     * Get the published port, which is the port to be advertised as the port
     * for the chosen SIP transport.
     * @return pj_uint16 The port used for that account
     */
    pj_uint16_t getPublishedPort() const {
        return (pj_uint16_t) publishedPort_;
    }

    /**
     * Set the published port, which is the port to be advertised as the port
     * for the chosen SIP transport.
     * @pram port The port used by this account.
     */
    void setPublishedPort(pj_uint16_t port) {
        publishedPort_ = port;
    }

189 190 191 192 193 194 195 196 197
    /**
     * Get a flag which determine the usage in sip headers of either the local
     * IP address and port (_localAddress and localPort_) or to an address set
     * manually (_publishedAddress and publishedPort_).
     */
    bool getPublishedSameasLocal() const {
        return publishedSameasLocal_;
    }

Guillaume Roguez's avatar
Guillaume Roguez committed
198
    virtual sip_utils::KeyExchangeProtocol getSrtpKeyExchange() const = 0;
199

Adrien Béraud's avatar
Adrien Béraud committed
200
    virtual bool getSrtpFallback() const = 0;
201 202 203 204 205

    /**
     * Get the contact header for
     * @return pj_str_t The contact header based on account information
     */
206
    virtual pj_str_t getContactHeader(pjsip_transport* = nullptr) = 0;
207 208 209

    virtual std::string getToUri(const std::string& username) const = 0;

210 211 212 213 214 215 216 217 218 219 220 221
    /**
     * Socket port generators for media
     * Note: given ports are application wide, a port cannot be given again
     * by any account instances until it's released by the static method
     * releasePort().
     */
    uint16_t generateAudioPort() const;
#ifdef RING_VIDEO
    uint16_t generateVideoPort() const;
#endif
    static void releasePort(uint16_t port) noexcept;

222 223 224 225 226 227 228 229 230 231 232 233 234
    /**
     * @return pj_str_t , filled from the configuration
     * file, that can be used directly by PJSIP to initialize
     * an alternate UDP transport.
     */
    std::string getStunServer() const {
        return stunServer_;
    }

    void setStunServer(const std::string &srv) {
        stunServer_ = srv;
    }

235 236
    const IceTransportOptions getIceOptions() const noexcept override;

Adrien Béraud's avatar
Adrien Béraud committed
237 238 239 240 241 242 243 244 245 246 247
    virtual void sendTextMessage(const std::string& to, const std::map<std::string, std::string>& payloads, uint64_t id) = 0;

    virtual uint64_t sendTextMessage(const std::string& to,
                                     const std::map<std::string, std::string>& payloads) override {
        return messageEngine_.sendMessage(to, payloads);
    }

    virtual im::MessageStatus getMessageStatus(uint64_t id) const override {
        return messageEngine_.getStatus(id);
    }

248
    void onTextMessage(const std::string& from, const std::map<std::string, std::string>& payloads);
249

250 251 252
    /* Returns true if the username and/or hostname match this account */
    virtual MatchRank matches(const std::string &username, const std::string &hostname) const = 0;

253 254
    void connectivityChanged() override {};

255
protected:
256
    virtual void serialize(YAML::Emitter &out) override;
Adrien Béraud's avatar
Adrien Béraud committed
257
    virtual void serializeTls(YAML::Emitter &out);
258
    virtual void unserialize(const YAML::Node &node) override;
259

260
    virtual void setAccountDetails(const std::map<std::string, std::string> &details) override;
261

262
    virtual std::map<std::string, std::string> getAccountDetails() const override;
263

264 265 266 267
    /**
     * Retrieve volatile details such as recent registration errors
     * @return std::map< std::string, std::string > The account volatile details
     */
268
    virtual std::map<std::string, std::string> getVolatileAccountDetails() const override;
269

Adrien Béraud's avatar
Adrien Béraud committed
270 271 272 273
    virtual void setRegistrationState(RegistrationState state, unsigned code=0, const std::string& detail_str={}) override;

    im::MessageEngine messageEngine_;

274
    /**
275
     * Voice over IP Link contains a listener thread and calls
276
     */
277 278
    std::shared_ptr<SIPVoIPLink> link_;

279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
    /**
     * interface name on which this account is bound
     */
    std::string interface_ {"default"};

    /**
     * Flag which determine if localIpAddress_ or publishedIpAddress_ is used in
     * sip headers
     */
    bool publishedSameasLocal_ {true};

    /**
     * Published IP address, used only if defined by the user in account
     * configuration
     */
    IpAddr publishedIp_ {};

296
    std::string publishedIpAddress_ {};
297 298 299 300

    /**
     * Published port, used only if defined by the user
     */
301
    pj_uint16_t publishedPort_ {sip_utils::DEFAULT_SIP_PORT};
302

303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324
    /**
     * Determine if STUN public address resolution is required to register this account. In this case a
     * STUN server hostname must be specified.
     */
    bool stunEnabled_ {false};

    /**
     * The STUN server hostname (optional), used to provide the public IP address in case the softphone
     * stay behind a NAT.
     */
    std::string stunServer_ {};

    /**
     * Determine if TURN public address resolution is required to register this account. In this case a
     * TURN server hostname must be specified.
     */
    bool turnEnabled_ {false};

    /**
     * The TURN server hostname (optional), used to provide the public IP address in case the softphone
     * stay behind a NAT.
     */
325 326 327 328
    std::string turnServer_;
    std::string turnServerUserName_;
    std::string turnServerPwd_;
    std::string turnServerRealm_;
329

330 331 332 333
    std::string tlsCaListFile_;
    std::string tlsCertificateFile_;
    std::string tlsPrivateKeyFile_;
    std::string tlsPassword_;
334 335 336 337 338 339

    /**
     * DTMF type used for this account SIPINFO or RTP
     */
    std::string dtmfType_ {OVERRTP_STR};

340 341 342
    pj_status_t transportStatus_ {PJSIP_SC_TRYING};
    std::string transportError_ {};

343 344 345 346 347 348 349 350 351 352
    /*
     * Port range for audio RTP ports
     */
    std::pair<uint16_t, uint16_t> audioPortRange_ {16384, 32766};

    /**
     * Port range for video RTP ports
     */
    std::pair<uint16_t, uint16_t> videoPortRange_ {49152, (MAX_PORT) - 2};

353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386
    struct UsedPort {
        UsedPort() {};
        UsedPort(UsedPort&& o) : port_(o.port_) {
            o.port_ = 0;
        }
        UsedPort(in_port_t p) : port_(p) {
            if (port_)
                acquirePort(port_);
        };
        ~UsedPort() {
            if (port_)
                releasePort(port_);
        };
        UsedPort& operator=(UsedPort&& o) {
            if (port_)
                releasePort(port_);
            port_ = o.port_;
            o.port_ = 0;
            return *this;
        }
        UsedPort& operator=(in_port_t p) {
            if (port_)
                releasePort(port_);
            port_ = p;
            if (port_)
                acquirePort(port_);
            return *this;
        }
        explicit operator in_port_t() const { return port_; }
    private:
        in_port_t port_ {0};
        NON_COPYABLE(UsedPort);
    };

387
    static std::array<bool, HALF_MAX_PORT>& getPortsReservation() noexcept;
388 389
    static uint16_t acquirePort(uint16_t port);
    uint16_t getRandomEvenPort(const std::pair<uint16_t, uint16_t>& range) const;
390
    uint16_t acquireRandomEvenPort(const std::pair<uint16_t, uint16_t>& range) const;
391 392 393 394 395 396

private:
    NON_COPYABLE(SIPAccountBase);

};

397 398
} // namespace ring

399
#endif