1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.waarp.openr66.protocol.networkhandler;
21
22 import io.netty.bootstrap.Bootstrap;
23 import io.netty.channel.Channel;
24 import io.netty.channel.ChannelFuture;
25 import io.netty.channel.ChannelId;
26 import io.netty.channel.ChannelPipelineException;
27 import io.netty.channel.group.ChannelGroup;
28 import io.netty.channel.group.DefaultChannelGroup;
29 import io.netty.util.Timeout;
30 import io.netty.util.TimerTask;
31 import org.waarp.common.crypto.ssl.WaarpSslUtility;
32 import org.waarp.common.database.DbAdmin;
33 import org.waarp.common.digest.FilesystemBasedDigest;
34 import org.waarp.common.future.WaarpLock;
35 import org.waarp.common.logging.SysErrLogger;
36 import org.waarp.common.logging.WaarpLogger;
37 import org.waarp.common.logging.WaarpLoggerFactory;
38 import org.waarp.common.lru.ConcurrentUtility;
39 import org.waarp.common.lru.SynchronizedLruCache;
40 import org.waarp.common.utility.WaarpNettyUtil;
41 import org.waarp.common.utility.WaarpShutdownHook;
42 import org.waarp.common.utility.WaarpSystemUtil;
43 import org.waarp.openr66.context.ErrorCode;
44 import org.waarp.openr66.context.R66Result;
45 import org.waarp.openr66.context.R66Session;
46 import org.waarp.openr66.context.task.exception.OpenR66RunnerErrorException;
47 import org.waarp.openr66.database.data.DbHostAuth;
48 import org.waarp.openr66.protocol.configuration.Configuration;
49 import org.waarp.openr66.protocol.exception.OpenR66ProtocolBlackListedException;
50 import org.waarp.openr66.protocol.exception.OpenR66ProtocolNetworkException;
51 import org.waarp.openr66.protocol.exception.OpenR66ProtocolNoConnectionException;
52 import org.waarp.openr66.protocol.exception.OpenR66ProtocolNoDataException;
53 import org.waarp.openr66.protocol.exception.OpenR66ProtocolNoSslException;
54 import org.waarp.openr66.protocol.exception.OpenR66ProtocolNotAuthenticatedException;
55 import org.waarp.openr66.protocol.exception.OpenR66ProtocolPacketException;
56 import org.waarp.openr66.protocol.exception.OpenR66ProtocolRemoteShutdownException;
57 import org.waarp.openr66.protocol.exception.OpenR66ProtocolSystemException;
58 import org.waarp.openr66.protocol.localhandler.LocalChannelReference;
59 import org.waarp.openr66.protocol.localhandler.RetrieveRunner;
60 import org.waarp.openr66.protocol.localhandler.packet.AuthentPacket;
61 import org.waarp.openr66.protocol.localhandler.packet.ConnectionErrorPacket;
62 import org.waarp.openr66.protocol.networkhandler.packet.NetworkPacket;
63 import org.waarp.openr66.protocol.networkhandler.ssl.NetworkSslServerHandler;
64 import org.waarp.openr66.protocol.networkhandler.ssl.NetworkSslServerInitializer;
65 import org.waarp.openr66.protocol.utils.ChannelUtils;
66 import org.waarp.openr66.protocol.utils.R66Future;
67
68 import java.net.ConnectException;
69 import java.net.InetAddress;
70 import java.net.InetSocketAddress;
71 import java.net.SocketAddress;
72 import java.util.Enumeration;
73 import java.util.Set;
74 import java.util.concurrent.ConcurrentHashMap;
75 import java.util.concurrent.TimeUnit;
76 import java.util.concurrent.locks.ReentrantLock;
77
78 import static org.waarp.common.utility.WaarpShutdownHook.*;
79 import static org.waarp.openr66.context.R66FiniteDualStates.*;
80 import static org.waarp.openr66.protocol.configuration.Configuration.*;
81
82
83
84
85 public class NetworkTransaction {
86
87
88
89 private static final WaarpLogger logger =
90 WaarpLoggerFactory.getLogger(NetworkTransaction.class);
91
92
93
94
95 private static final WaarpLock emptyLock = new WaarpLock();
96
97
98
99 private static final ReentrantLock lockOfLock = new ReentrantLock();
100
101
102
103 private static final SynchronizedLruCache<Integer, WaarpLock>
104 reentrantLockOnSocketAddressConcurrentHashMap =
105 new SynchronizedLruCache<Integer, WaarpLock>(20000, 180000);
106
107
108
109
110 private static final ConcurrentHashMap<Integer, NetworkChannelReference>
111 networkChannelShutdownOnSocketAddressConcurrentHashMap =
112 new ConcurrentHashMap<Integer, NetworkChannelReference>();
113
114
115
116
117 private static final ConcurrentHashMap<Integer, NetworkChannelReference>
118 networkChannelBlacklistedOnInetSocketAddressConcurrentHashMap =
119 new ConcurrentHashMap<Integer, NetworkChannelReference>();
120
121
122
123
124
125 private static final ConcurrentHashMap<Integer, NetworkChannelReference>
126 networkChannelOnSocketAddressConcurrentHashMap =
127 new ConcurrentHashMap<Integer, NetworkChannelReference>();
128
129
130
131
132 private static final ConcurrentHashMap<String, ClientNetworkChannels>
133 clientNetworkChannelsPerHostId =
134 new ConcurrentHashMap<String, ClientNetworkChannels>();
135
136
137
138 private static final ConcurrentHashMap<Integer, RetrieveRunner>
139 retrieveRunnerConcurrentHashMap =
140 new ConcurrentHashMap<Integer, RetrieveRunner>();
141
142 private final Bootstrap clientBootstrap;
143 private final Bootstrap clientSslBootstrap;
144 private ChannelGroup networkChannelGroup;
145
146 public NetworkTransaction() {
147 clearPreviousStates();
148 networkChannelGroup = new DefaultChannelGroup("NetworkChannels",
149 Configuration.configuration.getSubTaskGroup()
150 .next());
151 Configuration.configuration.setupLimitHandler();
152 clientBootstrap = new Bootstrap();
153 if (Configuration.configuration.isUseNOSSL() &&
154 Configuration.configuration.getHostId() != null) {
155 final NetworkServerInitializer networkServerInitializer =
156 new NetworkServerInitializer(false);
157 WaarpNettyUtil.setBootstrap(clientBootstrap,
158 Configuration.configuration.getNetworkWorkerGroup(),
159 (int) Configuration.configuration.getTimeoutCon(),
160 configuration.getBlockSize() + 64, false);
161 clientBootstrap.handler(networkServerInitializer);
162 }
163 clientSslBootstrap = new Bootstrap();
164 if (Configuration.configuration.isUseSSL() &&
165 Configuration.configuration.getHostSslId() != null) {
166 final NetworkSslServerInitializer networkSslServerInitializer =
167 new NetworkSslServerInitializer(true);
168 WaarpNettyUtil.setBootstrap(clientSslBootstrap,
169 Configuration.configuration.getNetworkWorkerGroup(),
170 (int) Configuration.configuration.getTimeoutCon(),
171 configuration.getBlockSize() + 64, false);
172 clientSslBootstrap.handler(networkSslServerInitializer);
173 } else {
174 if (Configuration.configuration.isWarnOnStartup()) {
175 logger.warn("No SSL support configured");
176 } else {
177 logger.info("No SSL support configured");
178 }
179 }
180 }
181
182 private final void clearPreviousStates() {
183 if (WaarpSystemUtil.isJunit()) {
184 for (final NetworkChannelReference ncr : networkChannelOnSocketAddressConcurrentHashMap.values()) {
185 if (ncr.channel != null &&
186 ncr.channel.hasAttr(NetworkServerHandler.REUSABLE_AUTH_KEY)) {
187 logger.debug("DEBUG clear {}",
188 ncr.channel.attr(NetworkServerHandler.REUSABLE_AUTH_KEY)
189 .get());
190 ncr.channel.attr(NetworkServerHandler.REUSABLE_AUTH_KEY).set(null);
191 }
192 }
193 for (final ClientNetworkChannels cnc : clientNetworkChannelsPerHostId.values()) {
194 for (final NetworkChannelReference ncr : cnc.getNetworkChannelReferences()) {
195 if (ncr.channel != null &&
196 ncr.channel.hasAttr(NetworkServerHandler.REUSABLE_AUTH_KEY)) {
197 logger.debug("DEBUG clear {}", ncr.channel.attr(
198 NetworkServerHandler.REUSABLE_AUTH_KEY).get());
199 ncr.channel.attr(NetworkServerHandler.REUSABLE_AUTH_KEY).set(null);
200 }
201 }
202 }
203 }
204 }
205
206 public static String hashStatus() {
207 final StringBuilder partial =
208 new StringBuilder("NetworkTransaction: [InShutdown: ");
209 partial.append(
210 networkChannelShutdownOnSocketAddressConcurrentHashMap.size())
211 .append(" Blacklisted: ").append(
212 networkChannelBlacklistedOnInetSocketAddressConcurrentHashMap.size())
213 .append("\n RetrieveRunner: ")
214 .append(retrieveRunnerConcurrentHashMap.size())
215 .append(" ClientNetworkChannels: ")
216 .append(clientNetworkChannelsPerHostId.size());
217 int nb = 0;
218 for (final ClientNetworkChannels clientNetworkChannels : clientNetworkChannelsPerHostId.values()) {
219 nb += clientNetworkChannels.size();
220 }
221 partial.append(" Sum of ClientNetworkChannels NetworkClients: ").append(nb);
222 nb = 0;
223 for (final NetworkChannelReference ncr : networkChannelOnSocketAddressConcurrentHashMap.values()) {
224 nb += ncr.nbLocalChannels();
225 partial.append("\n NetworkChannels: ").append(ncr.toString());
226 }
227 partial.append("\n NetworkChannels: ")
228 .append(networkChannelOnSocketAddressConcurrentHashMap.size())
229 .append(" LockOnSocketAddress: ")
230 .append(reentrantLockOnSocketAddressConcurrentHashMap.size())
231 .append(" Sum of NetworkChannels LocalClients: ").append(nb)
232 .append("] ");
233 return partial.toString();
234 }
235
236 private static WaarpLock getLockNCR(final SocketAddress sa) {
237 final int key = sa.hashCode();
238 final WaarpLock value =
239 reentrantLockOnSocketAddressConcurrentHashMap.get(key);
240 if (value != null) {
241 reentrantLockOnSocketAddressConcurrentHashMap.updateTtl(key);
242 }
243 return value;
244 }
245
246 private static void addLockNCR(final SocketAddress sa, final WaarpLock lock) {
247 reentrantLockOnSocketAddressConcurrentHashMap.put(sa.hashCode(), lock);
248 }
249
250 private static void addNCR(final NetworkChannelReference ncr) {
251 networkChannelOnSocketAddressConcurrentHashMap.put(ncr.getSocketHashCode(),
252 ncr);
253 }
254
255 private static NetworkChannelReference removeNCR(
256 final NetworkChannelReference ncr) {
257 return networkChannelOnSocketAddressConcurrentHashMap.remove(
258 ncr.getSocketHashCode());
259 }
260
261 private static NetworkChannelReference getNCR(final SocketAddress sa) {
262 return networkChannelOnSocketAddressConcurrentHashMap.get(sa.hashCode());
263 }
264
265 private static boolean containsNCR(final SocketAddress address) {
266 return networkChannelOnSocketAddressConcurrentHashMap.containsKey(
267 address.hashCode());
268 }
269
270 private static void addShutdownNCR(final NetworkChannelReference ncr) {
271 networkChannelShutdownOnSocketAddressConcurrentHashMap.put(
272 ncr.getSocketHashCode(), ncr);
273 }
274
275 private static NetworkChannelReference removeShutdownNCR(
276 final NetworkChannelReference ncr) {
277 return networkChannelShutdownOnSocketAddressConcurrentHashMap.remove(
278 ncr.getSocketHashCode());
279 }
280
281 private static boolean containsShutdownNCR(
282 final NetworkChannelReference ncr) {
283 return networkChannelShutdownOnSocketAddressConcurrentHashMap.containsKey(
284 ncr.getSocketHashCode());
285 }
286
287 private static boolean containsShutdownNCR(final SocketAddress sa) {
288 return networkChannelShutdownOnSocketAddressConcurrentHashMap.containsKey(
289 sa.hashCode());
290 }
291
292 private static NetworkChannelReference getShutdownNCR(
293 final SocketAddress sa) {
294 return networkChannelShutdownOnSocketAddressConcurrentHashMap.get(
295 sa.hashCode());
296 }
297
298 private static void addBlacklistNCR(final NetworkChannelReference ncr) {
299 networkChannelBlacklistedOnInetSocketAddressConcurrentHashMap.put(
300 ncr.getAddressHashCode(), ncr);
301 }
302
303 private static NetworkChannelReference removeBlacklistNCR(
304 final NetworkChannelReference ncr) {
305 return networkChannelBlacklistedOnInetSocketAddressConcurrentHashMap.remove(
306 ncr.getAddressHashCode());
307 }
308
309 private static boolean containsBlacklistNCR(
310 final NetworkChannelReference ncr) {
311 return networkChannelBlacklistedOnInetSocketAddressConcurrentHashMap.containsKey(
312 ncr.getAddressHashCode());
313 }
314
315 private static boolean containsBlacklistNCR(final SocketAddress address) {
316 return networkChannelBlacklistedOnInetSocketAddressConcurrentHashMap.containsKey(
317 address.hashCode());
318 }
319
320 private static NetworkChannelReference getBlacklistNCR(
321 final SocketAddress sa) {
322 final InetAddress address = ((InetSocketAddress) sa).getAddress();
323 if (address == null) {
324 return null;
325 }
326
327 return networkChannelBlacklistedOnInetSocketAddressConcurrentHashMap.get(
328 address.getHostAddress().hashCode());
329 }
330
331 private static WaarpLock getChannelLock(final SocketAddress socketAddress) {
332 lockOfLock.lock();
333 try {
334 if (socketAddress == null) {
335
336 logger.info("SocketAddress empty here !");
337 return emptyLock;
338 }
339 WaarpLock socketLock = getLockNCR(socketAddress);
340 if (socketLock == null) {
341 socketLock = new WaarpLock(true);
342 }
343
344 addLockNCR(socketAddress, socketLock);
345 return socketLock;
346 } finally {
347 lockOfLock.unlock();
348 }
349 }
350
351 private static void removeChannelLock() {
352 lockOfLock.lock();
353 try {
354 reentrantLockOnSocketAddressConcurrentHashMap.forceClearOldest();
355 } finally {
356 lockOfLock.unlock();
357 }
358 }
359
360
361
362
363
364
365
366
367
368
369 public final LocalChannelReference createConnectionWithRetry(
370 final SocketAddress socketAddress, final boolean isSSL,
371 final R66Future futureRequest) {
372 try {
373 return createConnectionWithRetryWithAuthenticationException(socketAddress,
374 isSSL,
375 futureRequest);
376 } catch (final OpenR66ProtocolNotAuthenticatedException e) {
377
378 return null;
379 }
380 }
381
382
383
384
385
386
387
388
389
390
391
392
393 public final LocalChannelReference createConnectionWithRetryWithAuthenticationException(
394 final SocketAddress socketAddress, final boolean isSSL,
395 final R66Future futureRequest)
396 throws OpenR66ProtocolNotAuthenticatedException {
397 LocalChannelReference localChannelReference = null;
398 for (int i = 0; i < Configuration.RETRYNB; i++) {
399 if (WaarpShutdownHook.isShutdownStarting()) {
400 logger.error("Cannot connect : Local system in shutdown");
401 break;
402 }
403 try {
404 localChannelReference =
405 createConnection(socketAddress, isSSL, futureRequest);
406 break;
407 } catch (final OpenR66ProtocolRemoteShutdownException e) {
408 logger.warn("Cannot connect : {}", e.getMessage());
409 logger.debug(e);
410 break;
411 } catch (final OpenR66ProtocolBlackListedException e) {
412 logger.error("Cannot connect : {}", e.getMessage());
413 logger.debug(e);
414 break;
415 } catch (final OpenR66ProtocolNoConnectionException e) {
416 logger.error("Cannot connect : {}", e.getMessage());
417 logger.debug(e);
418 break;
419 } catch (final OpenR66ProtocolNotAuthenticatedException e) {
420 logger.error("Cannot be authenticated : {}", e.getMessage());
421 logger.debug(e);
422 throw e;
423 } catch (final OpenR66ProtocolNetworkException e) {
424
425 logger.error("Cannot connect : {}. Will retry", e.getMessage());
426 logger.warn(e);
427 try {
428 Thread.sleep(Configuration.configuration.getDelayRetry());
429 } catch (final InterruptedException e1) {
430 SysErrLogger.FAKE_LOGGER.ignoreLog(e1);
431 }
432 }
433 }
434 if (localChannelReference != null) {
435 logger.info("Connected");
436 }
437 return localChannelReference;
438 }
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455 private LocalChannelReference createConnection(
456 final SocketAddress socketAddress, final boolean isSSL,
457 final R66Future futureRequest) throws OpenR66ProtocolNetworkException,
458 OpenR66ProtocolRemoteShutdownException,
459 OpenR66ProtocolNoConnectionException,
460 OpenR66ProtocolNotAuthenticatedException,
461 OpenR66ProtocolBlackListedException {
462 NetworkChannelReference networkChannelReference = null;
463 LocalChannelReference localChannelReference;
464 boolean ok = false;
465
466 final DbHostAuth auth =
467 isSSL? Configuration.configuration.getHostSslAuth() :
468 Configuration.configuration.getHostAuth();
469 if (!auth.isClient()) {
470 boolean valid = false;
471 for (int i = 0; i < Configuration.RETRYNB * 2; i++) {
472 if (Configuration.configuration.getConstraintLimitHandler()
473 .checkConstraintsSleep(i)) {
474 logger.info("Constraints exceeded: {}", i);
475 } else {
476 logger.debug("Constraints NOT exceeded");
477 valid = true;
478 break;
479 }
480 }
481 if (!valid) {
482
483 throw new OpenR66ProtocolNetworkException(
484 "Cannot connect to remote server due to local overload");
485 }
486 }
487 try {
488
489 networkChannelReference = createNewConnection(socketAddress, isSSL);
490 try {
491 localChannelReference =
492 Configuration.configuration.getLocalTransaction()
493 .createNewClient(networkChannelReference,
494 ChannelUtils.NOCHANNEL,
495 futureRequest, isSSL);
496 } catch (final NullPointerException e) {
497 throw new OpenR66ProtocolNetworkException(e);
498 }
499 ok = true;
500 } finally {
501 if (!ok && networkChannelReference != null) {
502 checkClosingNetworkChannel(networkChannelReference, null);
503 }
504 }
505 if (localChannelReference.getFutureValidateStartup().isSuccess()) {
506 sendValidationConnection(localChannelReference);
507 } else {
508 final OpenR66ProtocolNetworkException exc =
509 new OpenR66ProtocolNetworkException("Startup is invalid");
510 logger.info("Startup is Invalid", exc);
511 final R66Result finalValue =
512 new R66Result(exc, null, true, ErrorCode.ConnectionImpossible, null);
513 localChannelReference.invalidateRequest(finalValue);
514 localChannelReference.close();
515 throw exc;
516 }
517 return localChannelReference;
518 }
519
520
521
522
523
524
525
526
527
528
529
530
531 private NetworkChannelReference createNewConnection(
532 final SocketAddress socketServerAddress, final boolean isSSL)
533 throws OpenR66ProtocolNetworkException,
534 OpenR66ProtocolRemoteShutdownException,
535 OpenR66ProtocolBlackListedException,
536 OpenR66ProtocolNoConnectionException {
537 final WaarpLock socketLock = getChannelLock(socketServerAddress);
538 NetworkChannelReference networkChannelReference;
539 socketLock.lock();
540 try {
541 try {
542 networkChannelReference = getRemoteChannel(socketServerAddress);
543 } catch (final OpenR66ProtocolNoDataException e1) {
544 networkChannelReference = null;
545 }
546 if (networkChannelReference != null) {
547 networkChannelReference.use();
548 logger.info("Already Connected: {}", networkChannelReference);
549 return networkChannelReference;
550 }
551 logger.debug("NEW PHYSICAL CONNECTION REQUIRED");
552 ChannelFuture channelFuture = null;
553 for (int i = 0; i < Configuration.RETRYNB; i++) {
554 if (WaarpShutdownHook.isShutdownStarting()) {
555 throw new OpenR66ProtocolNoConnectionException(
556 "Local system in shutdown");
557 }
558 try {
559 if (isSSL) {
560 if (Configuration.configuration.getHostSslId() != null) {
561 channelFuture = clientSslBootstrap.connect(socketServerAddress);
562 } else {
563 throw new OpenR66ProtocolNoConnectionException("No SSL support");
564 }
565 } else {
566 channelFuture = clientBootstrap.connect(socketServerAddress);
567 }
568 } catch (final ChannelPipelineException e) {
569 throw new OpenR66ProtocolNoConnectionException(
570 "Cannot connect to remote server due to a channel exception");
571 }
572 WaarpNettyUtil.awaitOrInterrupted(channelFuture,
573 Configuration.configuration.getTimeoutCon());
574 if (channelFuture.isSuccess()) {
575 final Channel channel = channelFuture.channel();
576 if (isSSL &&
577 !NetworkSslServerHandler.isSslConnectedChannel(channel)) {
578 logger.info("KO CONNECT since SSL handshake is over");
579 channel.close();
580 throw new OpenR66ProtocolNoConnectionException(
581 "Cannot finish connect to remote server");
582 }
583 if (networkChannelGroup != null) {
584 networkChannelGroup.add(channel);
585 }
586 networkChannelReference =
587 new NetworkChannelReference(channel, socketLock, isSSL);
588 addNCR(networkChannelReference);
589 logger.info("New Real Connection: {}", networkChannelReference);
590 return networkChannelReference;
591 } else {
592 try {
593 Thread.sleep(Configuration.RETRYINMS);
594 } catch (final InterruptedException e) {
595 SysErrLogger.FAKE_LOGGER.ignoreLog(e);
596 }
597 if (!channelFuture.isDone()) {
598 throw new OpenR66ProtocolNoConnectionException(
599 "Cannot connect to remote server since received an " +
600 "interruption");
601 }
602 if (channelFuture.cause() instanceof ConnectException) {
603 logger.debug("KO CONNECT: {}", channelFuture.cause().getMessage());
604 throw new OpenR66ProtocolNoConnectionException(
605 channelFuture.cause().getMessage(), channelFuture.cause());
606 } else {
607 logger.debug("KO CONNECT but retry", channelFuture.cause());
608 }
609 }
610 }
611 if (channelFuture != null) {
612 throw new OpenR66ProtocolNetworkException(
613 "Cannot connect to remote server", channelFuture.cause());
614 } else {
615 throw new OpenR66ProtocolNetworkException(
616 "Cannot connect to remote server");
617 }
618 } finally {
619 socketLock.unlock();
620 }
621 }
622
623
624
625
626
627
628
629
630
631
632 public static LocalChannelReference createConnectionFromNetworkChannelStartup(
633 final NetworkChannelReference networkChannelReference,
634 final NetworkPacket startupPacket, final boolean fromSsl) {
635 logger.debug("Startup {}", startupPacket);
636 final Channel channel = networkChannelReference.channel();
637 try {
638 return Configuration.configuration.getLocalTransaction().createNewClient(
639 networkChannelReference, startupPacket.getRemoteId(), null, fromSsl);
640 } catch (final OpenR66ProtocolRemoteShutdownException e1) {
641 logger.info("Will Close Local from Network Channel");
642 WaarpSslUtility.closingSslChannel(channel);
643 startupPacket.clear();
644 } catch (final OpenR66ProtocolNoConnectionException e1) {
645 logger.error(
646 "Cannot create LocalChannel for: " + startupPacket + " due to " +
647 e1.getMessage());
648 final ConnectionErrorPacket error = new ConnectionErrorPacket(
649 "Cannot connect to localChannel since cannot create it", null);
650 NetworkServerHandler.writeError(channel, startupPacket.getRemoteId(),
651 startupPacket.getLocalId(), error);
652 checkClosingNetworkChannel(networkChannelReference, null);
653 startupPacket.clear();
654 }
655 return null;
656 }
657
658
659
660
661
662
663
664
665
666 private void sendValidationConnection(
667 final LocalChannelReference localChannelReference)
668 throws OpenR66ProtocolNetworkException,
669 OpenR66ProtocolNotAuthenticatedException {
670 if (localChannelReference.getServerHandler()
671 .validateAuthenticationReuse()) {
672
673 return;
674 }
675 final AuthentPacket authent;
676
677 try {
678 final DbHostAuth auth =
679 localChannelReference.getNetworkServerHandler().isSsl()?
680 Configuration.configuration.getHostSslAuth() :
681 Configuration.configuration.getHostAuth();
682 authent = new AuthentPacket(Configuration.configuration.getHostId(
683 localChannelReference.getNetworkServerHandler().isSsl()),
684 FilesystemBasedDigest.passwdCrypt(
685 auth.getHostkey()),
686 localChannelReference.getLocalId());
687 } catch (final OpenR66ProtocolNoSslException e1) {
688 final R66Result finalValue = new R66Result(
689 new OpenR66ProtocolSystemException("No SSL support", e1),
690 localChannelReference.getSession(), true,
691 ErrorCode.ConnectionImpossible, null);
692 logger.error("Authent is Invalid due to no SSL: {}", e1.getMessage());
693 if (localChannelReference.getRemoteId()
694 .compareTo(ChannelUtils.NOCHANNEL) == 0) {
695 final ConnectionErrorPacket error = new ConnectionErrorPacket(
696 "Cannot connect to localChannel since SSL is not supported", null);
697 try {
698 ChannelUtils.writeAbstractLocalPacket(localChannelReference, error,
699 false);
700 } catch (final OpenR66ProtocolPacketException ignored) {
701
702 }
703 }
704 localChannelReference.invalidateRequest(finalValue);
705 localChannelReference.close();
706 throw new OpenR66ProtocolNetworkException(e1);
707 }
708 logger.debug("Will send request of connection validation");
709 localChannelReference.sessionNewState(AUTHENTR);
710 try {
711 ChannelUtils.writeAbstractLocalPacket(localChannelReference, authent,
712 false);
713 } catch (final OpenR66ProtocolPacketException e) {
714 final R66Result finalValue = new R66Result(
715 new OpenR66ProtocolSystemException("Wrong Authent Protocol", e),
716 localChannelReference.getSession(), true,
717 ErrorCode.ConnectionImpossible, null);
718 logger.error("Authent is Invalid due to protocol: {}", e.getMessage());
719 localChannelReference.invalidateRequest(finalValue);
720 if (!localChannelReference.getRemoteId().equals(ChannelUtils.NOCHANNEL)) {
721 final ConnectionErrorPacket error = new ConnectionErrorPacket(
722 "Cannot connect to localChannel since Authent Protocol is invalid",
723 null);
724 try {
725 ChannelUtils.writeAbstractLocalPacket(localChannelReference, error,
726 false);
727 } catch (final OpenR66ProtocolPacketException ignored) {
728
729 }
730 }
731 localChannelReference.close();
732 throw new OpenR66ProtocolNetworkException("Bad packet", e);
733 }
734 final R66Future future =
735 localChannelReference.getFutureValidateConnection();
736 if (future.isFailed()) {
737 logger.debug("Will close NETWORK channel since Future cancelled: {}",
738 future);
739 final R66Result finalValue = new R66Result(
740 new OpenR66ProtocolSystemException(
741 "Connection invalid during Authentication"),
742 localChannelReference.getSession(), true,
743 ErrorCode.ConnectionImpossible, null);
744 logger.info("Authent is Invalid due to: {} {}",
745 finalValue.getException().getMessage(), future.toString());
746 localChannelReference.invalidateRequest(finalValue);
747 if (!localChannelReference.getRemoteId().equals(ChannelUtils.NOCHANNEL)) {
748 final ConnectionErrorPacket error = new ConnectionErrorPacket(
749 "Cannot connect to localChannel with Out of Time", null);
750 try {
751 ChannelUtils.writeAbstractLocalPacket(localChannelReference, error,
752 false);
753 } catch (final OpenR66ProtocolPacketException ignored) {
754
755 }
756 }
757 localChannelReference.close();
758 throw new OpenR66ProtocolNotAuthenticatedException(
759 "Cannot validate connection: " + future.getResult(),
760 future.getCause());
761 }
762 }
763
764
765
766
767
768
769
770
771
772
773 public static NetworkChannelReference addNetworkChannel(final Channel channel,
774 final boolean isSsl)
775 throws OpenR66ProtocolRemoteShutdownException,
776 OpenR66ProtocolBlackListedException {
777 final SocketAddress socketAddress = channel.remoteAddress();
778 final WaarpLock socketLock = getChannelLock(socketAddress);
779 socketLock.lock();
780 try {
781 NetworkChannelReference nc = null;
782 try {
783 nc = getRemoteChannel(socketAddress);
784 } catch (final OpenR66ProtocolNoDataException ignored) {
785
786 }
787 if (nc == null) {
788
789 nc = new NetworkChannelReference(channel, socketLock, isSsl);
790 addNCR(nc);
791 }
792 return nc;
793 } finally {
794 socketLock.unlock();
795 }
796 }
797
798
799
800
801
802
803
804 public static void proposeShutdownNetworkChannel(
805 final SocketAddress socketAddress, final boolean isSSL) {
806 final WaarpLock lock = getChannelLock(socketAddress);
807 lock.lock(Configuration.WAITFORNETOP, TimeUnit.MILLISECONDS);
808 try {
809 logger.info("Seem Shutdown: {}", socketAddress);
810 if (containsShutdownNCR(socketAddress)) {
811
812 logger.debug("Already set as shutdown");
813 return;
814 }
815 if (containsBlacklistNCR(socketAddress)) {
816
817 logger.debug("Already set as blocked");
818 return;
819 }
820 if (containsNCR(socketAddress)) {
821
822 logger.debug("Still existing so shutdown is refused");
823 return;
824 }
825 logger.warn(
826 "This host address will be set as unavailable for 3xTIMEOUT since not reacheable multiple times: {}",
827 socketAddress);
828 final NetworkChannelReference networkChannelReference =
829 new NetworkChannelReference(socketAddress, lock, isSSL);
830 addShutdownNCR(networkChannelReference);
831 if (Configuration.configuration.isTimerCloseReady()) {
832 final R66ShutdownNetworkChannelTimerTask timerTask;
833 try {
834 timerTask =
835 new R66ShutdownNetworkChannelTimerTask(networkChannelReference,
836 false);
837 Configuration.configuration.getTimerClose().newTimeout(timerTask,
838 Configuration.configuration.getTimeoutCon(),
839 TimeUnit.MILLISECONDS);
840 } catch (final OpenR66RunnerErrorException e) {
841
842 }
843 }
844 } finally {
845 lock.unlock();
846 }
847 }
848
849
850
851
852
853
854 private static void shuttingDownNetworkChannelInternal(
855 final NetworkChannelReference networkChannelReference) {
856 logger.info("Shutdown: {}", networkChannelReference);
857 if (networkChannelReference != null &&
858 containsShutdownNCR(networkChannelReference)) {
859
860 logger.debug("Already set as shutdown");
861 return;
862 }
863 logger.debug("Set as shutdown");
864 if (networkChannelReference != null) {
865 addShutdownNCR(networkChannelReference);
866 if (!networkChannelReference.isShuttingDown) {
867 networkChannelReference.shutdownAllLocalChannels();
868 }
869 if (Configuration.configuration.isTimerCloseReady()) {
870 final R66ShutdownNetworkChannelTimerTask timerTask;
871 try {
872 timerTask =
873 new R66ShutdownNetworkChannelTimerTask(networkChannelReference,
874 false);
875 Configuration.configuration.getTimerClose().newTimeout(timerTask,
876 Configuration.configuration.getTimeoutCon(),
877 TimeUnit.MILLISECONDS);
878 } catch (final OpenR66RunnerErrorException e) {
879
880 }
881 }
882 }
883 }
884
885
886
887
888
889
890 public static void shuttingDownNetworkChannel(
891 final NetworkChannelReference networkChannelReference) {
892 shuttingDownNetworkChannelInternal(networkChannelReference);
893 }
894
895
896
897
898
899
900
901
902 public static boolean shuttingDownNetworkChannelBlackList(
903 final NetworkChannelReference networkChannelReference) {
904 shuttingDownNetworkChannelInternal(networkChannelReference);
905 if (!Configuration.configuration.isBlacklistBadAuthent()) {
906 return false;
907 }
908 if (containsBlacklistNCR(networkChannelReference)) {
909 return false;
910 }
911 addBlacklistNCR(networkChannelReference);
912 if (Configuration.configuration.isTimerCloseReady()) {
913 final R66ShutdownNetworkChannelTimerTask timerTask;
914 try {
915 timerTask =
916 new R66ShutdownNetworkChannelTimerTask(networkChannelReference,
917 true);
918 Configuration.configuration.getTimerClose().newTimeout(timerTask,
919 Configuration.configuration.getTimeoutCon() *
920 5,
921 TimeUnit.MILLISECONDS);
922 } catch (final OpenR66RunnerErrorException e) {
923
924 }
925 }
926 return true;
927 }
928
929
930
931
932
933
934 public static boolean isBlacklisted(final Channel channel) {
935 if (!Configuration.configuration.isBlacklistBadAuthent()) {
936 return false;
937 }
938 final SocketAddress address = channel.remoteAddress();
939 if (address == null) {
940 return false;
941 }
942
943 final NetworkChannelReference networkChannelReference =
944 getBlacklistNCR(address);
945 return networkChannelReference != null;
946 }
947
948
949
950
951
952
953
954 public static boolean isShuttingdownNetworkChannel(
955 final SocketAddress address) {
956 return !isAddressValid(address);
957 }
958
959
960
961
962
963
964
965
966 public static boolean shuttingdownNetworkChannelsPerHostID(
967 final String requester) {
968 if (requester == null) {
969 return false;
970 }
971 final ClientNetworkChannels clientNetworkChannels =
972 clientNetworkChannelsPerHostId.get(requester);
973 logger.debug("AddClient: shutdown previous exist? " +
974 (clientNetworkChannels != null) + " for :" + requester);
975 if (clientNetworkChannels != null) {
976 return clientNetworkChannels.shutdownAllNetworkChannels();
977 }
978 return false;
979 }
980
981
982
983
984
985
986
987 public static void addClient(
988 final NetworkChannelReference networkChannelReference,
989 final String requester) {
990 synchronized (clientNetworkChannelsPerHostId) {
991 if (networkChannelReference != null && requester != null) {
992 ClientNetworkChannels clientNetworkChannels =
993 clientNetworkChannelsPerHostId.get(requester);
994 if (clientNetworkChannels == null) {
995 clientNetworkChannels = new ClientNetworkChannels(requester);
996 clientNetworkChannelsPerHostId.put(requester, clientNetworkChannels);
997 }
998 clientNetworkChannels.add(networkChannelReference);
999 logger.debug("AddClient: add count? {} for {}",
1000 clientNetworkChannels.size(), requester);
1001 }
1002 }
1003 }
1004
1005 private static void removeClient(
1006 final NetworkChannelReference networkChannelReference,
1007 final String requester,
1008 final ClientNetworkChannels clientNetworkChannels) {
1009 if (networkChannelReference != null && clientNetworkChannels != null &&
1010 requester != null) {
1011 clientNetworkChannels.remove(networkChannelReference);
1012 logger.debug("removeClient: remove for :{} still {}", requester,
1013 clientNetworkChannels.size());
1014 if (clientNetworkChannels.isEmpty()) {
1015 clientNetworkChannelsPerHostId.remove(requester);
1016 }
1017 }
1018 }
1019
1020
1021
1022
1023
1024
1025 public static int getNumberClients(final String requester) {
1026 final ClientNetworkChannels clientNetworkChannels =
1027 clientNetworkChannelsPerHostId.get(requester);
1028 if (clientNetworkChannels != null) {
1029 return clientNetworkChannels.size();
1030 }
1031 return 0;
1032 }
1033
1034
1035
1036
1037
1038
1039 public static void closedNetworkChannel(
1040 final NetworkChannelReference networkChannelReference) {
1041 if (networkChannelReference == null) {
1042 return;
1043 }
1044 try {
1045 if (!networkChannelReference.isShuttingDown) {
1046 networkChannelReference.shutdownAllLocalChannels();
1047 }
1048 logger.debug("NC left: {}", networkChannelReference);
1049 removeNCR(networkChannelReference);
1050 if (networkChannelReference.clientNetworkChannels != null) {
1051 final String requester =
1052 networkChannelReference.clientNetworkChannels.getHostId();
1053 removeClient(networkChannelReference, requester,
1054 networkChannelReference.clientNetworkChannels);
1055 } else if (networkChannelReference.getHostId() != null) {
1056 final String requester = networkChannelReference.getHostId();
1057 final ClientNetworkChannels clientNetworkChannels =
1058 clientNetworkChannelsPerHostId.get(requester);
1059 if (clientNetworkChannels != null) {
1060 removeClient(networkChannelReference, requester,
1061 clientNetworkChannels);
1062 }
1063 }
1064 } finally {
1065 removeChannelLock();
1066 }
1067 }
1068
1069
1070
1071
1072
1073
1074 public static void closedNetworkChannel(final SocketAddress address) {
1075 if (address == null) {
1076 return;
1077 }
1078 final NetworkChannelReference networkChannelReference =
1079 networkChannelOnSocketAddressConcurrentHashMap.get(address.hashCode());
1080 closedNetworkChannel(networkChannelReference);
1081 }
1082
1083
1084
1085
1086
1087 private static class CloseFutureChannel implements TimerTask {
1088
1089 private static final Set<ChannelId> inCloseRunning =
1090 ConcurrentUtility.newConcurrentSet();
1091 private final NetworkChannelReference networkChannelReference;
1092
1093
1094
1095
1096
1097
1098 private CloseFutureChannel(
1099 final NetworkChannelReference networkChannelReference)
1100 throws OpenR66RunnerErrorException {
1101 if (!inCloseRunning.add(networkChannelReference.channel.id())) {
1102 throw new OpenR66RunnerErrorException("Already scheduled");
1103 }
1104 this.networkChannelReference = networkChannelReference;
1105 }
1106
1107 @Override
1108 public void run(final Timeout timeout) {
1109 final long time = networkChannelReference.shutdownAllowed();
1110 if (time > 0) {
1111 Configuration.configuration.getTimerClose().newTimeout(this, time,
1112 TimeUnit.MILLISECONDS);
1113 return;
1114 } else if (time == 0) {
1115 networkChannelReference.isShuttingDown = true;
1116 WaarpSslUtility.closingSslChannel(networkChannelReference.channel);
1117 }
1118 }
1119
1120 }
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131 public static int checkClosingNetworkChannel(
1132 final NetworkChannelReference networkChannelReference,
1133 final LocalChannelReference localChannelReference) {
1134 networkChannelReference.lock.lock(Configuration.WAITFORNETOP,
1135 TimeUnit.MILLISECONDS);
1136 try {
1137 logger.debug("Close con: {}", networkChannelReference);
1138 if (localChannelReference != null) {
1139 networkChannelReference.closeAndRemove(localChannelReference);
1140 }
1141 final int count = networkChannelReference.nbLocalChannels();
1142 if (count <= 0) {
1143 logger.debug("Will try to Close con: {}", networkChannelReference);
1144 final CloseFutureChannel cfc;
1145 try {
1146 cfc = new CloseFutureChannel(networkChannelReference);
1147 Configuration.configuration.getTimerClose().newTimeout(cfc,
1148 Configuration.configuration.getTimeoutCon() *
1149 2,
1150 TimeUnit.MILLISECONDS);
1151 } catch (final OpenR66RunnerErrorException ignored) {
1152
1153 } catch (final IllegalStateException ignored) {
1154
1155 }
1156 } else {
1157 networkChannelReference.use();
1158 logger.debug("Ignore shutdown after checking");
1159 }
1160 logger.debug("NC left: {}", networkChannelReference);
1161 return count;
1162 } finally {
1163 networkChannelReference.lock.unlock();
1164 }
1165 }
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175 public static int nbAttachedConnection(final SocketAddress address,
1176 final String host) {
1177 if (logger.isDebugEnabled()) {
1178 logger.debug("nbAttachedConnection: {}:{}",
1179 networkChannelOnSocketAddressConcurrentHashMap.containsKey(
1180 address.hashCode()), getNumberClients(host));
1181 }
1182 return (networkChannelOnSocketAddressConcurrentHashMap.containsKey(
1183 address.hashCode())? 1 : 0) + getNumberClients(host);
1184 }
1185
1186
1187
1188
1189
1190
1191 private static boolean isAddressValid(final SocketAddress address) {
1192 if (WaarpShutdownHook.isShutdownStarting()) {
1193 logger.debug("IS IN SHUTDOWN");
1194 return false;
1195 }
1196 if (address == null) {
1197 logger.debug("ADDRESS IS NULL");
1198 return false;
1199 }
1200 try {
1201 final NetworkChannelReference networkChannelReference =
1202 getRemoteChannel(address);
1203 logger.debug("IS IN SHUTDOWN: {}",
1204 networkChannelReference.isShuttingDown);
1205 return !networkChannelReference.isShuttingDown;
1206 } catch (final OpenR66ProtocolRemoteShutdownException e) {
1207 logger.debug("ALREADY IN SHUTDOWN");
1208 return false;
1209 } catch (final OpenR66ProtocolNoDataException e) {
1210 logger.debug("NOT FOUND SO NO SHUTDOWN");
1211 return true;
1212 } catch (final OpenR66ProtocolBlackListedException e) {
1213 logger.warn("BLACK LISTED HOST");
1214 return false;
1215 }
1216 }
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230 private static NetworkChannelReference getRemoteChannel(
1231 final SocketAddress address)
1232 throws OpenR66ProtocolRemoteShutdownException,
1233 OpenR66ProtocolNoDataException,
1234 OpenR66ProtocolBlackListedException {
1235 if (WaarpShutdownHook.isShutdownStarting()) {
1236 logger.debug("IS IN SHUTDOWN");
1237 throw new OpenR66ProtocolRemoteShutdownException(
1238 "Local Host already in shutdown");
1239 }
1240 if (address == null) {
1241 logger.debug("ADDRESS IS NULL");
1242 throw new OpenR66ProtocolRemoteShutdownException(
1243 "Cannot connect to remote server since address is not specified");
1244 }
1245 NetworkChannelReference nc = getShutdownNCR(address);
1246 if (nc != null) {
1247 logger.debug("HOST STILL IN SHUTDOWN STATUS: {}", address);
1248 throw new OpenR66ProtocolRemoteShutdownException(
1249 "Remote Host already in shutdown");
1250 }
1251 nc = getBlacklistNCR(address);
1252 if (nc != null) {
1253 logger.debug("HOST IN BLACKLISTED STATUS: {}", address);
1254 throw new OpenR66ProtocolBlackListedException(
1255 "Remote Host is blacklisted");
1256 }
1257 nc = getNCR(address);
1258 if (nc != null && (nc.isShuttingDown || !nc.channel().isActive())) {
1259 logger.debug("HOST IS DisActive: {}", address);
1260 throw new OpenR66ProtocolRemoteShutdownException(
1261 "Remote Host is disActive");
1262 }
1263 if (nc == null) {
1264 throw new OpenR66ProtocolNoDataException("Channel not found");
1265 }
1266 return nc;
1267 }
1268
1269
1270
1271
1272
1273
1274 public static NetworkChannelReference getImmediateNetworkChannel(
1275 final Channel channel) {
1276 if (channel.remoteAddress() != null) {
1277 return getNCR(channel.remoteAddress());
1278 }
1279 return null;
1280 }
1281
1282
1283
1284
1285 private static class R66ShutdownNetworkChannelTimerTask implements TimerTask {
1286 private static final Set<ChannelId> inShutdownRunning =
1287 ConcurrentUtility.newConcurrentSet();
1288 private static final Set<ChannelId> inBlacklistedRunning =
1289 ConcurrentUtility.newConcurrentSet();
1290
1291
1292
1293 private final NetworkChannelReference ncr;
1294 private final boolean isBlacklisted;
1295
1296
1297
1298
1299
1300
1301 private R66ShutdownNetworkChannelTimerTask(
1302 final NetworkChannelReference ncr, final boolean blackListed)
1303 throws OpenR66RunnerErrorException {
1304 if (blackListed) {
1305 if (!inBlacklistedRunning.add(ncr.channel.id())) {
1306 throw new OpenR66RunnerErrorException("Already scheduled");
1307 }
1308 } else {
1309 if (ncr.channel != null && !inShutdownRunning.add(ncr.channel.id())) {
1310 throw new OpenR66RunnerErrorException("Already scheduled");
1311 }
1312 }
1313 this.ncr = ncr;
1314 isBlacklisted = blackListed;
1315 }
1316
1317 @Override
1318 public void run(final Timeout timeout) {
1319 if (isBlacklisted) {
1320 logger.debug("Will remove Blacklisted for : {}", ncr);
1321 removeBlacklistNCR(ncr);
1322 inBlacklistedRunning.remove(ncr.channel.id());
1323 return;
1324 }
1325 logger.debug("Will remove Shutdown for : {}", ncr);
1326 if (ncr.channel != null && ncr.channel.isActive()) {
1327 WaarpSslUtility.closingSslChannel(ncr.channel);
1328 }
1329 removeShutdownNCR(ncr);
1330 if (ncr.channel != null) {
1331 inShutdownRunning.remove(ncr.channel.id());
1332 }
1333 }
1334 }
1335
1336
1337
1338
1339 public static int getRetrieveRunnerActive() {
1340 return Configuration.configuration.getRetrieveRunnerGroup()
1341 .getActiveCount();
1342 }
1343
1344
1345
1346
1347
1348
1349 public static void runRetrieve(final R66Session session) {
1350 final RetrieveRunner retrieveRunner = new RetrieveRunner(session);
1351 retrieveRunnerConcurrentHashMap.put(
1352 session.getLocalChannelReference().getLocalId(), retrieveRunner);
1353 Configuration.configuration.getRetrieveRunnerGroup()
1354 .execute(retrieveRunner);
1355 }
1356
1357
1358
1359
1360
1361
1362 public static void stopRetrieve(
1363 final LocalChannelReference localChannelReference) {
1364 final RetrieveRunner retrieveRunner =
1365 retrieveRunnerConcurrentHashMap.remove(
1366 localChannelReference.getLocalId());
1367 if (retrieveRunner != null) {
1368 retrieveRunner.stopRunner();
1369 }
1370 }
1371
1372
1373
1374
1375
1376
1377 public static void normalEndRetrieve(
1378 final LocalChannelReference localChannelReference) {
1379 retrieveRunnerConcurrentHashMap.remove(localChannelReference.getLocalId());
1380 }
1381
1382
1383
1384
1385 public final void closeAll() {
1386 closeAll(true);
1387 }
1388
1389
1390
1391
1392 public final void closeAll(final boolean quickShutdown) {
1393 logger.debug("close All Network Channels");
1394 if (!Configuration.configuration.isServer()) {
1395 if (shutdownHook != null) {
1396 shutdownHook.launchFinalExit();
1397 }
1398 }
1399 if (networkChannelGroup != null) {
1400 WaarpNettyUtil.awaitOrInterrupted(networkChannelGroup.close());
1401 networkChannelGroup = null;
1402 }
1403 try {
1404 Thread.sleep(Configuration.WAITFORNETOP);
1405 } catch (final InterruptedException e) {
1406 SysErrLogger.FAKE_LOGGER.ignoreLog(e);
1407 }
1408 stopAllEndRetrieve();
1409 DbAdmin.closeAllConnection();
1410 Configuration.configuration.clientStop(quickShutdown);
1411 if (!Configuration.configuration.isServer()) {
1412 logger.debug("Last action before exit");
1413 WaarpSystemUtil.stopLogger(false);
1414 }
1415 }
1416
1417
1418 public static void stopAllEndRetrieve() {
1419 final Enumeration<RetrieveRunner> enumeration =
1420 retrieveRunnerConcurrentHashMap.elements();
1421 while (enumeration.hasMoreElements()) {
1422 final RetrieveRunner runner = enumeration.nextElement();
1423 runner.stopRunner();
1424 }
1425 retrieveRunnerConcurrentHashMap.clear();
1426 }
1427 }