Skip to content

Commit

Permalink
Merge branch 'trunk' into feat_apkam_sync
Browse files Browse the repository at this point in the history
  • Loading branch information
gkc authored Oct 15, 2023
2 parents 359074f + 424e24c commit acb47ef
Show file tree
Hide file tree
Showing 10 changed files with 195 additions and 157 deletions.
4 changes: 4 additions & 0 deletions packages/at_root_server/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2.1.0
- feat: rate limiting when looking up non-existent atSigns
- feat: miscellaneous logging enhancements
- fix: removed unnecessary 10-second delay during normal startup
## 2.0.5
- upgrade persistence spec version
## 2.0.4
Expand Down
47 changes: 37 additions & 10 deletions packages/at_root_server/lib/src/client/at_root_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@ import 'package:at_persistence_root_server/at_persistence_root_server.dart';
import 'package:at_utils/at_logger.dart';
import 'package:at_commons/at_commons.dart';

enum RootClientState {listening,closing,closed}

/// Represents Root Server client instance which contains socket on which a connection got established
class RootClient {
late Socket _socket;
String? _address;
int? _port;
static final _keyStoreManager = KeystoreManagerImpl();
final _buffer = StringBuffer(capacity: 255);
int notFoundCount = 0;
late RootClientState state;

RootClient(Socket s) {
_socket = s;
Expand All @@ -20,6 +24,7 @@ class RootClient {
RootClientPool().add(this);
_socket.listen(_messageHandler,
onError: _errorHandler, onDone: _finishedHandler);
state = RootClientState.listening;
}

var logger = AtSignLogger('RootClient');
Expand All @@ -29,26 +34,43 @@ class RootClient {
/// @param - data : data received from client over the socket
Future<void> _messageHandler(data) async {
try {
logger.info('In root client _messagehandler');
logger.finest('${_address}:${_port} In root client _messagehandler');
var message = utf8.decode(data);
message = message.toLowerCase();
_buffer.append(message);
if (_buffer.getData()!.trim() == '@exit') {
var lookupPayload = _buffer.getData()!.trim();
if (lookupPayload == '@exit') {
_finishedHandler();
return;
} else {
if (_buffer.isEnd()) {
var result = await _keyStoreManager
.getKeyStore()
.get(_buffer.getData()!.trim());
logger.finer('result:${result}');
.get(lookupPayload);
logger.info('${_address}:${_port} Looked up: $lookupPayload | Found: $result');

if (result == null) {
notFoundCount++;
if (notFoundCount > 1) {
// If we've already had at least one lookup of a non-existent atSign
// then we will wait a few seconds before responding
await Future.delayed(Duration(seconds: 3));
}

if (notFoundCount > 2) {
// And if we've already had at least two lookups of a non-existent
// atSign then we will terminate the connection
_finishedHandler();
return;
}
}
result ??= 'null';
write(result + '\r\n@');
_buffer.clear();
}
}
} on Exception catch (exception) {
logger.severe(exception);
logger.severe('${_address}:${_port} _messageHandler | $exception');
_socket.destroy();
} catch (error) {
_errorHandler(error.toString());
Expand All @@ -59,16 +81,19 @@ class RootClient {
/// Return type - void
/// @param - error : error string
void _errorHandler(error) {
logger.severe('${_address}:${_port} Error: $error');
removeClient(this);
_socket.destroy();
if (state == RootClientState.listening) {
logger.severe('${_address}:${_port} Error: $error');
removeClient(this);
}
}

/// _finishedHandler close the client connection and remove from client pool
/// Return type - void
void _finishedHandler() {
logger.info('${_address}:${_port} Disconnected');
removeClient(this);
if (state == RootClientState.listening) {
logger.info('${_address}:${_port} Disconnected');
removeClient(this);
}
}

/// write - Writes received message to the client socket
Expand All @@ -83,7 +108,9 @@ class RootClient {
/// return type - void
/// @param - rootClient - Instance of RootClient
void removeClient(RootClient rootClient) {
state = RootClientState.closing;
rootClient._socket.destroy();
RootClientPool().remove(rootClient);
state = RootClientState.closed;
}
}
13 changes: 10 additions & 3 deletions packages/at_root_server/lib/src/server/at_root_server_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class RootServerImpl implements AtRootServer {
logger.info('Connection from '
'${socket.remoteAddress.address}:${socket.remotePort}');
var client = RootClient(socket);
logger.info('connection successful\n');
logger.info('connection successful');
client.write('@');
}

Expand Down Expand Up @@ -130,6 +130,9 @@ class RootServerImpl implements AtRootServer {
var certsAvailable = false;
// if certs are unavailable then retry max 10 minutes
while (true) {
if (retryCount > 0) {
sleep(Duration(seconds: 10));
}
try {
if (certsAvailable || retryCount > 60) {
break;
Expand All @@ -142,7 +145,6 @@ class RootServerImpl implements AtRootServer {
retryCount++;
logger.info('certs unavailable. Retry count ${retryCount}');
}
sleep(Duration(seconds: 10));
}
if (certsAvailable) {
SecureServerSocket.bind(InternetAddress.anyIPv4, port!, secCon)
Expand Down Expand Up @@ -178,7 +180,12 @@ class RootServerImpl implements AtRootServer {
serverSocket.listen((connection) {
_handle(AtClientConnectionImpl(connection));
}, onError: (error) {
logger.severe('rootServer Socket Error :' +
if (error is HandshakeException) {
// This is not unusual.
// See https://github.com/atsign-foundation/at_server/issues/1590
return;
}
logger.warning('ServerSocket stream error :' +
error.toString() +
'connecting to ' +
serverSocket.address.toString());
Expand Down
16 changes: 8 additions & 8 deletions packages/at_root_server/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: at_root_server
description: Root server implementation.
version: 2.0.5
version: 2.1.0
repository: https://github.com/atsign-foundation/at_server
homepage: https://atsign.dev
publish_to: none
Expand All @@ -9,12 +9,12 @@ environment:
sdk: '>=2.15.0 <4.0.0'

dependencies:
args: ^2.1.0
uuid: ^3.0.4
yaml: ^3.1.0
at_commons: 3.0.53
args: 2.4.2
uuid: 3.0.6
yaml: 3.1.2
at_commons: 3.0.56
at_utils: 3.0.15
at_server_spec: 3.0.13
at_server_spec: 3.0.15
at_persistence_root_server:
git:
url: https://github.com/atsign-foundation/at_server.git
Expand All @@ -25,6 +25,6 @@ dependencies:
dev_dependencies:
# Adding test_cov for generating the test coverage.
test_cov: ^1.0.1
lints: ^1.0.1
lints: ^2.1.1
test: ^1.24.6
coverage: ^1.0.3
coverage: ^1.6.3
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
-----BEGIN CERTIFICATE-----
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
zKZZcvGXtZETY04PlgVsaEhyQQ==
CAYGZ4EMAQIBMIIBBAYKKwYBBAHWeQIEAgSB9QSB8gDwAHUA2ra/az+1tiKfm8K7
XGvocJFxbLtRhIU0vaQ9MEjX+6sAAAGLMkgHnAAABAMARjBEAiBJCtlj5ouGTrqr
m8I1FnZCPJnk4uOG9Wfm1rvvQSvDgQIgQqdGTCznBiv6fLVcgDjMVRb6IFjP5vtM
kJrpW8YiDAwAdwDuzdBk1dsazsVct520zROiModGfLzs3sNRSFlGcR+1mwAAAYsy
SAeJAAAEAwBIMEYCIQCo5oE4c2AxnViVSVEiwn2oCu5yyxnKkW77C+9m37imagIh
AIh/FMzYY6xUTMtDOyUYC4h+MmuGzMI3KPV92Ehhq2PmMA0GCSqGSIb3DQEBCwUA
A4IBAQBROIAX48fzNSii3UxUTgGb6dQNe2B8MEJayN+/NOba3g7H68BgNBgaIF9+
IoC6JzCC3RcfebGPwEtRKveJNDT52pp2/GykUk0U+twnD8eCSvtjR3um55+ZO2O8
5bnNNwwAyZrVaR+3tfk3f6p7d1IdHuFcNHWIELqc3dW190mnOoPQIpp5pLv9PHBa
irZhXTrNmBJ+OL+QM57cA7tpKLr8JjqKo09s+MNvk6j6op1H/71/UlOKnBxWi/Fn
DznnWQX5MwJQ28lX9yOybbVwV58xdsL2nnuQXH488jBaCimiSVkCLbQE/9X6sNfr
MD97yFyDD9QETsvZC1TPxyIuHH9K
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
-----BEGIN CERTIFICATE-----
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
zKZZcvGXtZETY04PlgVsaEhyQQ==
CAYGZ4EMAQIBMIIBBAYKKwYBBAHWeQIEAgSB9QSB8gDwAHUA2ra/az+1tiKfm8K7
XGvocJFxbLtRhIU0vaQ9MEjX+6sAAAGLMkgHnAAABAMARjBEAiBJCtlj5ouGTrqr
m8I1FnZCPJnk4uOG9Wfm1rvvQSvDgQIgQqdGTCznBiv6fLVcgDjMVRb6IFjP5vtM
kJrpW8YiDAwAdwDuzdBk1dsazsVct520zROiModGfLzs3sNRSFlGcR+1mwAAAYsy
SAeJAAAEAwBIMEYCIQCo5oE4c2AxnViVSVEiwn2oCu5yyxnKkW77C+9m37imagIh
AIh/FMzYY6xUTMtDOyUYC4h+MmuGzMI3KPV92Ehhq2PmMA0GCSqGSIb3DQEBCwUA
A4IBAQBROIAX48fzNSii3UxUTgGb6dQNe2B8MEJayN+/NOba3g7H68BgNBgaIF9+
IoC6JzCC3RcfebGPwEtRKveJNDT52pp2/GykUk0U+twnD8eCSvtjR3um55+ZO2O8
5bnNNwwAyZrVaR+3tfk3f6p7d1IdHuFcNHWIELqc3dW190mnOoPQIpp5pLv9PHBa
irZhXTrNmBJ+OL+QM57cA7tpKLr8JjqKo09s+MNvk6j6op1H/71/UlOKnBxWi/Fn
DznnWQX5MwJQ28lX9yOybbVwV58xdsL2nnuQXH488jBaCimiSVkCLbQE/9X6sNfr
MD97yFyDD9QETsvZC1TPxyIuHH9K
-----END CERTIFICATE-----

-----BEGIN CERTIFICATE-----
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCfml6koDWy/ffT
kCb9gWbQIt7SXZi58KEvPjPTlCsXW+z2MkZvsIuamoHgJny1+7VjocBpfZtjjg3A
5BnrxkUbOc5BBo1L0ZBWfl3t61N0O1R2fO3inzGiOIjWDoqmeiQ6ll6RtJXGyQ0D
G2Rzm+VQtNvFmfeqp8K/HnxWq9oFqpR9qKmYCQyTJ5VeTH7YWLaId7mxHc8MT37p
JRQB72HVqzIqKnMyWhTURuPlqiEpvtAhOu3sg5BKAwGHUEqdBJQwIpTuMNl0dT0Z
Blz3sLe3EwjN3jQqtemApQMnszDWLUFCDrJOy5j5mPjI23q9DB9Cq8+SSerhYnmZ
MFtJJIYjAgMBAAECggEAC0d2C81Uri8bjgSAdObptKjaNWSu7+kNAxEyyW+Nsgtp
jiaUar0/yG/F4OjnZFcDBST/u5TIX/tAhpK4MDzlUly98kN7xdFsEWjBy5gXYD33
JJ6Ek0Dr2YqERRhm/QfhupA447Qu54r60+7iJPdt98uoQmk0owdTEH2fjOJ9OGwu
dhkXEA6R1JkPP4odpgNjKvEZ0OzVbKsajfrYkKqnVF3G7gUFGjRyeZde5QbbGghk
vPsjGA8FbMcWXB6en7kaPOwSbbp7GalyvGfjjiQMC0aS2TPkJ/QZdwWxvvuy3N8O
hp7FKIo1rlu2HvSn9qxR5j5XLFXXqN2GQQ+TsAmi+QKBgQC2vd1y63+SbgrEHcRl
Id8UuRK2H1lJGJM8cCH+v+zu6xd7w8PvV0m5ZEMHkDhFmxICknfLDXi2IYnWTm1u
7xL1vHMNn032+0zgxp9rHXI+YaU4hql+rf9EQYVV8gDw1P0m+UNRuTib0bsZJ0DH
0G7RK4E4BHYYJBa3GWKyvAs0aQKBgQDfld2qhPs8j5NjTqldY2WV2lLs2bnH5Loe
ikpiMrbcw6iP25xtg0JJeLOapYzS9+qVfU17aKrez+yZrNn5JibLXEKXpw2Cl9wI
iPpcnKncSIsvRz93rBGhZfjqONmV84otQtYOrd/OnI4rilit0iZ9gwUJxG/cbbER
3hT5r8PkqwKBgCPMEaM/aqAemlFMm3pMJk0C7B1tCqp8++qs9JvYsOskdlcyRCGQ
ccq1T0QeBkfsVpzWYE0QeIMFEuE+P8WpY4drwQX8HOOy2p51iikLfaOmsRzflDhS
kVynkR0C6RhEQMrvrTZHGEW90e7dd50swWiMIyX8Cb4045Y+jM0CdRdxAoGAcC7u
+OcedAWKK1LFsgD0cJsJ7qNUDxMZu8chiWHu1JgrlHrZYy1v7hNs8pRMM3KHNpiX
butWiNOE4JqVB+j3oCPbmeIM6lCt625nSF6m78tKYt953d7tPbE/kq4RpqZ61zjo
1JazbCSrRPd2hUijXWiG956jjdNP/CoVFi71uF8CgYBzRhDTelW+USb/pgIFJKr0
5fUDPgPF5M+EhfeGPDIcotIu/gHlDpFuxHR8ViTptfYF7L2p1C3TvJigCanNPwpH
lhatYkS/wdRBJDZCNPbKCKp843Ymec+yIrlHa2ZHXTe28vO+FHA2wzG74Yoyn/+c
1anN4xF+E2BOtK3RKQfxzA==
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCZiBO0qpgfgm90
PHw/V3+EcIucuDOLa0X7gsszNQwXc87Y0PdYXw+ZmJfqkWGSlZH4F3hU8E6oMyj8
oaUehjugVvYXu9Vm/qGe/9rwzaLaowNxoDZ3oF9lpq4j4xR2i7iMtBz5rsoqnGhb
5CgFAwanyEZz1QED3KuSuxrc2QvJrxBF8fuIB4GYD16dgV8XB8fb6MIvU4JWsHbs
OYNrgFeFy/0eDlB+tMTINcr+IetOB5JpM5vLekhe5RXQk68N+s2dd4X6GGdvilhZ
L77Etqq/KLWtgtnmsNux25OW+ojcoRjsIL6LUB2Zzf/uaeSyjYQsMGjt2tz+F0rt
we24px2jAgMBAAECggEACNtawlSyYI72aFmHlA0zeVZswhELmC1guiOkyULJfHOH
0+YqKVpCh3UlaQ4TTOYn/OHjD93/tkr36wBVitnqMqkRmp48BKxdHSkGs6wz4DJV
49t+3jki3QsCh2YgK2k1WkNBsKhZV/VHPUB/i9p4KycDOXITlD90qQr2Kmtdog11
FvEdnwLZ5eFIZY7pat20JL0WVh8ti14b98zg44Hfgq5+WIQfTZf5wO70rxb0thZ8
dn8/weUeZouKNWkzjvhOrWzv5IBWFbgFeBDReJbuhZ081d5TffK9xGPUaOuWIu1v
pGYJq1XhN6ce+ahYIQmCueJ/ninRiqkVMtxqWGr4kQKBgQDQmfzdZi6Cv95WZLJp
a3pgtb0Zoibej3PoK0jfrfu78mW68AIOlOAM7crphA9lhXEIkTTgXgJRpQeZAvJb
nLWZrKF+VtfO5WdSIE2RQFC4q2HBk0ka0giLjBk3xXkqYF/L7RyCozQK+BP1DINj
PJ49HWh5MTrPBnqGromHS/utjwKBgQC8asI0YOySF9odeNJHe32UfJ/TfWhXC49N
fAqMsRj3LScUm8Ga3L5TqrMWsjVLnXyW9WbnDCxr2NYrKtfWQJI9KvW4c5yw3gxr
BK4R+b1yG6Xsn8/ujSuyB2fuKbaFF5KEiC3wyatcbONCfV7HPzOvA/RMrzYJPXMn
vl29t73srQKBgQCUUpmotwolL9YgqdLuAFzwvOirfE+U+n1YvMZBPY178vwAsr1T
rumsZ7xa0+q6repURCNL0axmbyh61MyM9V1u2n+tvIQQea9AhvWAbTG4TSviHx7g
8izfRIt9y2y/A+25q2wVO4Q6tHBEUlRt0GFXZTyux6FgKOQgNaRWTmGy4wKBgCWD
+EEnn1MDbsl5eh0DiKCdI9GfYbwbMCBUd2FGDduBYQuoa6cjFr5f+aKmPxhcNid0
m1Wbxeh/Vz1nHWyqlLObLyvX0TYiMETKvMIVgNQMj0ALHgK4lx+ue9Ie+hmL9P9w
gf00mmsfvyxI/Csd+XN6jRULue2jD5+1NsMEp8tNAoGAX1eSxoDgNjDG6r8ECIva
VClNh7boSxpfC19LHvSn1Wr6rD0/KdBxQ/i4KdKpX2Lozj/qWnhh76+RaJuo0QPg
BhzvK5Z3YguK8s/tFbZ3+P0S7ooCCvImEyAh1gRutalsUkGaeBFi7muet6Q8u07+
QLbucwF1hh3IHniovRAWYIQ=
-----END PRIVATE KEY-----
Loading

0 comments on commit acb47ef

Please sign in to comment.