1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty5.handler.ssl;
17
18 import io.netty.internal.tcnative.SSL;
19 import io.netty5.util.AsciiString;
20
21 import java.util.HashMap;
22 import java.util.Map;
23
24
25
26
27 final class OpenSslClientSessionCache extends OpenSslSessionCache {
28
29
30 private final Map<HostPort, NativeSslSession> sessions = new HashMap<>();
31
32 OpenSslClientSessionCache(OpenSslEngineMap engineMap) {
33 super(engineMap);
34 }
35
36 @Override
37 protected boolean sessionCreated(NativeSslSession session) {
38 assert Thread.holdsLock(this);
39 HostPort hostPort = keyFor(session.getPeerHost(), session.getPeerPort());
40 if (hostPort == null || sessions.containsKey(hostPort)) {
41 return false;
42 }
43 sessions.put(hostPort, session);
44 return true;
45 }
46
47 @Override
48 protected void sessionRemoved(NativeSslSession session) {
49 assert Thread.holdsLock(this);
50 HostPort hostPort = keyFor(session.getPeerHost(), session.getPeerPort());
51 if (hostPort == null) {
52 return;
53 }
54 sessions.remove(hostPort);
55 }
56
57 @Override
58 void setSession(long ssl, String host, int port) {
59 HostPort hostPort = keyFor(host, port);
60 if (hostPort == null) {
61 return;
62 }
63 final NativeSslSession session;
64 final boolean reused;
65 synchronized (this) {
66 session = sessions.get(hostPort);
67 if (session == null) {
68 return;
69 }
70 if (!session.isValid()) {
71 removeSessionWithId(session.sessionId());
72 return;
73 }
74
75
76 reused = SSL.setSession(ssl, session.session());
77 }
78
79 if (reused) {
80 if (session.shouldBeSingleUse()) {
81
82 session.invalidate();
83 }
84 session.updateLastAccessedTime();
85 }
86 }
87
88 private static HostPort keyFor(String host, int port) {
89 if (host == null && port < 1) {
90 return null;
91 }
92 return new HostPort(host, port);
93 }
94
95 @Override
96 synchronized void clear() {
97 super.clear();
98 sessions.clear();
99 }
100
101
102
103
104 private static final class HostPort {
105 private final int hash;
106 private final String host;
107 private final int port;
108
109 HostPort(String host, int port) {
110 this.host = host;
111 this.port = port;
112
113 hash = 31 * AsciiString.hashCode(host) + port;
114 }
115
116 @Override
117 public int hashCode() {
118 return hash;
119 }
120
121 @Override
122 public boolean equals(Object obj) {
123 if (!(obj instanceof HostPort)) {
124 return false;
125 }
126 HostPort other = (HostPort) obj;
127 return port == other.port && host.equalsIgnoreCase(other.host);
128 }
129
130 @Override
131 public String toString() {
132 return "HostPort{" +
133 "host='" + host + '\'' +
134 ", port=" + port +
135 '}';
136 }
137 }
138 }