mirror of
https://github.com/espressif/openthread.git
synced 2026-08-04 09:57:47 +00:00
[srp-server] choose different UDP port from previous on reboot (#6702)
This commit implements a mechanism to let an SRP server listen to a different UDP port on a reboot. - When an SRP server starts, it reads the UDP port used in the last time from Settings. Then the SRP server listens to the next port in the reserved range. - When SRP server successfully starts, store its UDP port in Settings.
This commit is contained in:
@@ -53,7 +53,7 @@ extern "C" {
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (122)
|
||||
#define OPENTHREAD_API_VERSION (123)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -72,6 +72,7 @@ enum
|
||||
OT_SETTINGS_KEY_ON_LINK_PREFIX = 0x000a, ///< On-link prefix for infrastructure link.
|
||||
OT_SETTINGS_KEY_SRP_ECDSA_KEY = 0x000b, ///< SRP client ECDSA public/private key pair.
|
||||
OT_SETTINGS_KEY_SRP_CLIENT_INFO = 0x000c, ///< The SRP client info (selected SRP server address).
|
||||
OT_SETTINGS_KEY_SRP_SERVER_INFO = 0x000d, ///< The SRP server info (UDP port).
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -98,6 +98,13 @@ void SettingsBase::SrpClientInfo::Log(Action aAction) const
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE && OPENTHREAD_CONFIG_SRP_SERVER_PORT_SWITCH_ENABLE
|
||||
void SettingsBase::SrpServerInfo::Log(Action aAction) const
|
||||
{
|
||||
otLogInfoCore("[settings] %s SrpServerInfo {port:%u}", ActionToString(aAction), GetPort());
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_LOG_UTIL && (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO)
|
||||
|
||||
#if OPENTHREAD_CONFIG_LOG_UTIL && (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_WARN)
|
||||
@@ -146,6 +153,7 @@ const char *SettingsBase::KeyToString(Key aKey)
|
||||
"OnLinkPrefix", // (10) kKeyOnLinkPrefix
|
||||
"SrpEcdsaKey", // (11) kKeySrpEcdsaKey
|
||||
"SrpClientInfo", // (12) kKeySrpClientInfo
|
||||
"SrpServerInfo", // (13) kKeySrpServerInfo
|
||||
};
|
||||
|
||||
static_assert(1 == kKeyActiveDataset, "kKeyActiveDataset value is incorrect");
|
||||
@@ -160,8 +168,9 @@ const char *SettingsBase::KeyToString(Key aKey)
|
||||
static_assert(10 == kKeyOnLinkPrefix, "kKeyOnLinkPrefix value is incorrect");
|
||||
static_assert(11 == kKeySrpEcdsaKey, "kKeySrpEcdsaKey value is incorrect");
|
||||
static_assert(12 == kKeySrpClientInfo, "kKeySrpClientInfo value is incorrect");
|
||||
static_assert(13 == kKeySrpServerInfo, "kKeySrpServerInfo value is incorrect");
|
||||
|
||||
static_assert(kLastKey == kKeySrpClientInfo, "kLastKey is not valid");
|
||||
static_assert(kLastKey == kKeySrpServerInfo, "kLastKey is not valid");
|
||||
|
||||
OT_ASSERT(aKey <= kLastKey);
|
||||
|
||||
@@ -432,6 +441,12 @@ void Settings::Log(Action aAction, Error aError, Key aKey, const void *aValue)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE && OPENTHREAD_CONFIG_SRP_SERVER_PORT_SWITCH_ENABLE
|
||||
case kKeySrpServerInfo:
|
||||
reinterpret_cast<const SrpServerInfo *>(aValue)->Log(aAction);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
// For any other keys, we do not want to include the value
|
||||
// in the log, so even if it is given we set `aValue` to
|
||||
|
||||
@@ -125,9 +125,10 @@ public:
|
||||
kKeyOnLinkPrefix = OT_SETTINGS_KEY_ON_LINK_PREFIX,
|
||||
kKeySrpEcdsaKey = OT_SETTINGS_KEY_SRP_ECDSA_KEY,
|
||||
kKeySrpClientInfo = OT_SETTINGS_KEY_SRP_CLIENT_INFO,
|
||||
kKeySrpServerInfo = OT_SETTINGS_KEY_SRP_SERVER_INFO,
|
||||
};
|
||||
|
||||
static constexpr Key kLastKey = kKeySrpClientInfo; ///< The last (numerically) enumerator value in `Key`.
|
||||
static constexpr Key kLastKey = kKeySrpServerInfo; ///< The last (numerically) enumerator value in `Key`.
|
||||
|
||||
/**
|
||||
* This structure represents the device's own network information for settings storage.
|
||||
@@ -677,6 +678,48 @@ public:
|
||||
#endif // OPENTHREAD_CONFIG_SRP_CLIENT_SAVE_SELECTED_SERVER_ENABLE
|
||||
#endif // OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
|
||||
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE && OPENTHREAD_CONFIG_SRP_SERVER_PORT_SWITCH_ENABLE
|
||||
/**
|
||||
* This structure represents the SRP server info.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class SrpServerInfo : private Clearable<SrpServerInfo>
|
||||
{
|
||||
friend class Settings;
|
||||
|
||||
public:
|
||||
static constexpr Key kKey = kKeySrpServerInfo; ///< The associated key.
|
||||
|
||||
/**
|
||||
* This method initializes the `SrpServerInfo` object.
|
||||
*
|
||||
*/
|
||||
void Init(void) { Clear(); }
|
||||
|
||||
/**
|
||||
* This method returns the server port number.
|
||||
*
|
||||
* @returns The server port number.
|
||||
*
|
||||
*/
|
||||
uint16_t GetPort(void) const { return Encoding::LittleEndian::HostSwap16(mPort); }
|
||||
|
||||
/**
|
||||
* This method sets the server port number.
|
||||
*
|
||||
* @param[in] aPort The server port number.
|
||||
*
|
||||
*/
|
||||
void SetPort(uint16_t aPort) { mPort = Encoding::LittleEndian::HostSwap16(aPort); }
|
||||
|
||||
private:
|
||||
void Log(Action aAction) const;
|
||||
|
||||
uint16_t mPort; // (in little-endian encoding)
|
||||
} OT_TOOL_PACKED_END;
|
||||
#endif // OPENTHREAD_CONFIG_SRP_SERVER_ENABLE && OPENTHREAD_CONFIG_SRP_SERVER_PORT_SWITCH_ENABLE
|
||||
|
||||
protected:
|
||||
explicit SettingsBase(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
|
||||
@@ -509,4 +509,9 @@
|
||||
"Service numbers are defined in `network_data_servcie.hpp` per spec"
|
||||
#endif
|
||||
|
||||
#ifdef OPENTHREAD_CONFIG_SRP_SERVER_UDP_PORT
|
||||
#error "OPENTHREAD_CONFIG_SRP_SERVER_UDP_PORT was removed. "\
|
||||
"You can make OPENTHREAD_CONFIG_SRP_SERVER_UDP_PORT_MIN = OPENTHREAD_CONFIG_SRP_SERVER_UDP_PORT_MAX to specify a static UDP port. "
|
||||
#endif
|
||||
|
||||
#endif // OPENTHREAD_CORE_CONFIG_CHECK_H_
|
||||
|
||||
@@ -46,13 +46,37 @@
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_SRP_SERVER_UDP_PORT
|
||||
* @def OPENTHREAD_CONFIG_SRP_SERVER_UDP_PORT_MIN
|
||||
*
|
||||
* Specifies the SRP Server UDP port, and use 0 for ephemeral port.
|
||||
* Specifies the min port number in the port range reserved for SRP server.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_SRP_SERVER_UDP_PORT
|
||||
#define OPENTHREAD_CONFIG_SRP_SERVER_UDP_PORT 0
|
||||
#ifndef OPENTHREAD_CONFIG_SRP_SERVER_UDP_PORT_MIN
|
||||
#define OPENTHREAD_CONFIG_SRP_SERVER_UDP_PORT_MIN 53535
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_SRP_SERVER_UDP_PORT_MAX
|
||||
*
|
||||
* Specifies the max port number in the port range reserved for SRP server.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_SRP_SERVER_UDP_PORT_MAX
|
||||
#define OPENTHREAD_CONFIG_SRP_SERVER_UDP_PORT_MAX 53554
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_SRP_SERVER_PORT_SWITCH_ENABLE
|
||||
*
|
||||
* Define to 1 to enable SRP server feature to save its own port in non-volatile settings.
|
||||
*
|
||||
* When enabled, the SRP server will save its port in the non-volatile settings. On a server
|
||||
* restart (e.g., due to a device reset) it will restore the port and change to a different one. The info is written to
|
||||
* Settings after the first service has been registered due to receiving an SRP Update.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_SRP_SERVER_PORT_SWITCH_ENABLE
|
||||
#define OPENTHREAD_CONFIG_SRP_SERVER_PORT_SWITCH_ENABLE 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -85,6 +85,7 @@ Server::Server(Instance &aInstance)
|
||||
, mOutstandingUpdatesTimer(aInstance, HandleOutstandingUpdatesTimer)
|
||||
, mServiceUpdateId(Random::NonCrypto::GetUint32())
|
||||
, mEnabled(false)
|
||||
, mHasRegisteredAnyService(false)
|
||||
{
|
||||
IgnoreError(SetDomain(kDefaultDomain));
|
||||
}
|
||||
@@ -420,6 +421,16 @@ void Server::CommitSrpUpdate(Error aError,
|
||||
{
|
||||
otLogInfoSrp("[server] add new host %s", aHost.GetFullName());
|
||||
AddHost(&aHost);
|
||||
#if OPENTHREAD_CONFIG_SRP_SERVER_PORT_SWITCH_ENABLE
|
||||
if (!mHasRegisteredAnyService)
|
||||
{
|
||||
Settings::SrpServerInfo info;
|
||||
|
||||
mHasRegisteredAnyService = true;
|
||||
info.SetPort(mSocket.mSockName.mPort);
|
||||
IgnoreError(Get<Settings>().Save(info));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Re-schedule the lease timer.
|
||||
@@ -438,13 +449,28 @@ exit:
|
||||
|
||||
void Server::Start(void)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
Error error = kErrorNone;
|
||||
uint16_t port = kUdpPortMin;
|
||||
|
||||
VerifyOrExit(!IsRunning());
|
||||
|
||||
SuccessOrExit(error = mSocket.Open(HandleUdpReceive, this));
|
||||
SuccessOrExit(error = mSocket.Bind(kUdpPort, OT_NETIF_THREAD));
|
||||
#if OPENTHREAD_CONFIG_SRP_SERVER_PORT_SWITCH_ENABLE
|
||||
{
|
||||
Settings::SrpServerInfo info;
|
||||
|
||||
if (Get<Settings>().Read(info) == kErrorNone)
|
||||
{
|
||||
port = info.GetPort() + 1;
|
||||
if (port < kUdpPortMin || port > kUdpPortMax)
|
||||
{
|
||||
port = kUdpPortMin;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
SuccessOrExit(error = mSocket.Open(HandleUdpReceive, this));
|
||||
SuccessOrExit(error = mSocket.Bind(port, OT_NETIF_THREAD));
|
||||
SuccessOrExit(error = PublishServerData());
|
||||
|
||||
otLogInfoSrp("[server] start listening on port %hu", mSocket.GetSockName().mPort);
|
||||
|
||||
@@ -78,8 +78,10 @@ class Server : public InstanceLocator, private NonCopyable
|
||||
public:
|
||||
enum : uint16_t
|
||||
{
|
||||
kUdpPort = OPENTHREAD_CONFIG_SRP_SERVER_UDP_PORT, ///< The SRP Server UDP listening port.
|
||||
kUdpPortMin = OPENTHREAD_CONFIG_SRP_SERVER_UDP_PORT_MIN, ///< The reserved min SRP Server UDP listening port.
|
||||
kUdpPortMax = OPENTHREAD_CONFIG_SRP_SERVER_UDP_PORT_MAX, ///< The reserved max SRP Server UDP listening port.
|
||||
};
|
||||
static_assert(kUdpPortMin <= kUdpPortMax, "invalid port range");
|
||||
|
||||
/**
|
||||
* The ID of SRP service update transaction.
|
||||
@@ -671,7 +673,8 @@ private:
|
||||
LinkedList<UpdateMetadata> mOutstandingUpdates;
|
||||
|
||||
ServiceUpdateId mServiceUpdateId;
|
||||
bool mEnabled;
|
||||
bool mEnabled : 1;
|
||||
bool mHasRegisteredAnyService : 1;
|
||||
};
|
||||
|
||||
} // namespace Srp
|
||||
|
||||
@@ -371,6 +371,11 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
bool Udp::IsPortReserved(uint16_t aPort)
|
||||
{
|
||||
return aPort == Tmf::kUdpPort || (kSrpServerPortMin <= aPort && aPort <= kSrpServerPortMax);
|
||||
}
|
||||
|
||||
void Udp::AddSocket(SocketHandle &aSocket)
|
||||
{
|
||||
SuccessOrExit(mSockets.Add(aSocket));
|
||||
@@ -417,7 +422,7 @@ uint16_t Udp::GetEphemeralPort(void)
|
||||
{
|
||||
mEphemeralPort = kDynamicPortMin;
|
||||
}
|
||||
} while (mEphemeralPort == Tmf::kUdpPort);
|
||||
} while (IsPortReserved(mEphemeralPort));
|
||||
|
||||
return mEphemeralPort;
|
||||
}
|
||||
|
||||
@@ -589,8 +589,14 @@ private:
|
||||
{
|
||||
kDynamicPortMin = 49152, ///< Service Name and Transport Protocol Port Number Registry
|
||||
kDynamicPortMax = 65535, ///< Service Name and Transport Protocol Port Number Registry
|
||||
kSrpServerPortMin =
|
||||
OPENTHREAD_CONFIG_SRP_SERVER_UDP_PORT_MIN, // The min port in the port range reserved for SRP server.
|
||||
kSrpServerPortMax =
|
||||
OPENTHREAD_CONFIG_SRP_SERVER_UDP_PORT_MAX, // The max port in the port range reserved for SRP server.
|
||||
};
|
||||
|
||||
static bool IsPortReserved(uint16_t aPort);
|
||||
|
||||
void AddSocket(SocketHandle &aSocket);
|
||||
void RemoveSocket(SocketHandle &aSocket);
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
|
||||
|
||||
+193
@@ -0,0 +1,193 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2021, The OpenThread Authors.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. Neither the name of the copyright holder nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
import ipaddress
|
||||
import logging
|
||||
import unittest
|
||||
|
||||
import command
|
||||
import thread_cert
|
||||
|
||||
# Test description:
|
||||
# This test verifies when an SRP server reboots, it will listen to a UDP port
|
||||
# that wasn't used in the last time.
|
||||
#
|
||||
# Topology:
|
||||
#
|
||||
# LEADER (SRP client) -- ROUTER (SRP server)
|
||||
#
|
||||
|
||||
CLIENT = 1
|
||||
SERVER = 2
|
||||
|
||||
REBOOT_TIMES = 25
|
||||
|
||||
|
||||
class SrpAutoStartMode(thread_cert.TestCase):
|
||||
USE_MESSAGE_FACTORY = False
|
||||
SUPPORT_NCP = False
|
||||
|
||||
TOPOLOGY = {
|
||||
CLIENT: {
|
||||
'name': 'SRP_CLIENT',
|
||||
'mode': 'rdn',
|
||||
},
|
||||
SERVER: {
|
||||
'name': 'SRP_SERVER',
|
||||
'mode': 'rdn',
|
||||
},
|
||||
}
|
||||
|
||||
def test(self):
|
||||
client = self.nodes[CLIENT]
|
||||
server = self.nodes[SERVER]
|
||||
|
||||
#
|
||||
# 0. Start the server & client devices.
|
||||
#
|
||||
|
||||
client.srp_server_set_enabled(False)
|
||||
client.start()
|
||||
self.simulator.go(5)
|
||||
self.assertEqual(client.get_state(), 'leader')
|
||||
|
||||
server.srp_server_set_enabled(True)
|
||||
server.start()
|
||||
self.simulator.go(5)
|
||||
self.assertEqual(server.get_state(), 'router')
|
||||
|
||||
#
|
||||
# 1. Enable auto start mode on client and check that server is used.
|
||||
#
|
||||
|
||||
self.assertEqual(client.srp_client_get_state(), 'Disabled')
|
||||
client.srp_client_enable_auto_start_mode()
|
||||
self.assertEqual(client.srp_client_get_auto_start_mode(), 'Enabled')
|
||||
self.simulator.go(2)
|
||||
self.assertEqual(client.srp_client_get_state(), 'Enabled')
|
||||
self.assertTrue(server.has_ipaddr(client.srp_client_get_server_address()))
|
||||
|
||||
#
|
||||
# 2. Reboot the server without any service registered. The server should
|
||||
# listen to the same port after the reboot.
|
||||
#
|
||||
old_port = server.get_srp_server_port()
|
||||
server.srp_server_set_enabled(False)
|
||||
server.reset()
|
||||
server.start()
|
||||
self.simulator.go(5)
|
||||
server.srp_server_set_enabled(True)
|
||||
self.simulator.go(5)
|
||||
self.assertEqual(old_port, server.get_srp_server_port())
|
||||
|
||||
#
|
||||
# 3. Register a service
|
||||
#
|
||||
client.srp_client_set_host_name('my-host')
|
||||
client.srp_client_set_host_address('2001::1')
|
||||
client.srp_client_add_service('my-service', '_ipps._tcp', 12345, 0, 0, ['abc', 'def=', 'xyz=XYZ'])
|
||||
self.simulator.go(5)
|
||||
self.check_host_and_service(server, client, '2001::1')
|
||||
|
||||
ports = [server.get_srp_server_port()]
|
||||
|
||||
# Reboot the SRP server several times
|
||||
for i in range(REBOOT_TIMES):
|
||||
#
|
||||
# 4. Disable server and check client is stopped/disabled.
|
||||
#
|
||||
old_port = server.get_srp_server_port()
|
||||
server.srp_server_set_enabled(False)
|
||||
server.reset()
|
||||
server.start()
|
||||
self.simulator.go(5)
|
||||
|
||||
#
|
||||
# 5. Enable server and check client starts again. Verify that the
|
||||
# server is using a different port, and the service have been
|
||||
# re-registered.
|
||||
#
|
||||
server.srp_server_set_enabled(True)
|
||||
self.simulator.go(5)
|
||||
self.assertEqual(client.srp_client_get_state(), 'Enabled')
|
||||
self.assertEqual(client.srp_client_get_server_address(), server.get_mleid())
|
||||
self.assertNotEqual(old_port, server.get_srp_server_port())
|
||||
self.check_host_and_service(server, client, '2001::1')
|
||||
ports.append(server.get_srp_server_port())
|
||||
logging.info(f'ports = {ports}')
|
||||
|
||||
def check_host_and_service(self, server, client, host_addr):
|
||||
# Check that we have properly registered host and service instance.
|
||||
# Originally used in test_srp_register_single_service.py.
|
||||
|
||||
client_services = client.srp_client_get_services()
|
||||
print(client_services)
|
||||
self.assertEqual(len(client_services), 1)
|
||||
client_service = client_services[0]
|
||||
|
||||
# Verify that the client possesses correct service resources.
|
||||
self.assertEqual(client_service['instance'], 'my-service')
|
||||
self.assertEqual(client_service['name'], '_ipps._tcp')
|
||||
self.assertEqual(int(client_service['port']), 12345)
|
||||
self.assertEqual(int(client_service['priority']), 0)
|
||||
self.assertEqual(int(client_service['weight']), 0)
|
||||
|
||||
# Verify that the client received a SUCCESS response for the server.
|
||||
self.assertEqual(client_service['state'], 'Registered')
|
||||
|
||||
server_services = server.srp_server_get_services()
|
||||
self.assertEqual(len(server_services), 1)
|
||||
server_service = server_services[0]
|
||||
|
||||
# Verify that the server accepted the SRP registration and stores
|
||||
# the same service resources.
|
||||
self.assertEqual(server_service['deleted'], 'false')
|
||||
self.assertEqual(server_service['instance'], client_service['instance'])
|
||||
self.assertEqual(server_service['name'], client_service['name'])
|
||||
self.assertEqual(int(server_service['port']), int(client_service['port']))
|
||||
self.assertEqual(int(server_service['priority']), int(client_service['priority']))
|
||||
self.assertEqual(int(server_service['weight']), int(client_service['weight']))
|
||||
# We output value of TXT entry as HEX string.
|
||||
print(server_service['TXT'])
|
||||
self.assertEqual(server_service['TXT'], ['abc', 'def=', 'xyz=58595a'])
|
||||
self.assertEqual(server_service['host'], 'my-host')
|
||||
|
||||
server_hosts = server.srp_server_get_hosts()
|
||||
print(server_hosts)
|
||||
self.assertEqual(len(server_hosts), 1)
|
||||
server_host = server_hosts[0]
|
||||
|
||||
self.assertEqual(server_host['deleted'], 'false')
|
||||
self.assertEqual(server_host['fullname'], server_service['host_fullname'])
|
||||
self.assertEqual(len(server_host['addresses']), 1)
|
||||
self.assertEqual(ipaddress.ip_address(server_host['addresses'][0]), ipaddress.ip_address(host_addr))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user