Author: markt
Date: Fri Jan 30 14:23:08 2015
New Revision: 1656023
URL: http://svn.apache.org/r1656023
Log:
Move creation of SSLSupport instances to the SocketWrapper
Modified:
tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java
tomcat/trunk/java/org/apache/coyote/Processor.java
tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java
tomcat/trunk/java/org/apache/coyote/ajp/AjpNio2Protocol.java
tomcat/trunk/java/org/apache/coyote/ajp/AjpNioProtocol.java
tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11JsseProtocol.java
tomcat/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java
tomcat/trunk/java/org/apache/coyote/http11/Http11Nio2Protocol.java
tomcat/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java
tomcat/trunk/java/org/apache/coyote/spdy/SpdyProxyProtocol.java
tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java
tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java
tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapperBase.java
Modified: tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java?rev=1656023&r1=1656022&r2=1656023&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java Fri Jan 30
14:23:08 2015
@@ -628,7 +628,8 @@ public abstract class AbstractProtocol<S
processor = createProcessor();
}
- initSsl(wrapper, processor);
+ processor.setSslSupport(
+
wrapper.getSslSupport(getProtocol().getClientCertProvider()));
SocketState state = SocketState.CLOSED;
Iterator<DispatchType> dispatches = null;
@@ -774,8 +775,6 @@ public abstract class AbstractProtocol<S
}
protected abstract P createProcessor();
- protected abstract void initSsl(SocketWrapperBase<S> socket,
- Processor processor);
protected abstract void longPoll(SocketWrapperBase<S> socket,
Processor processor);
Modified: tomcat/trunk/java/org/apache/coyote/Processor.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/Processor.java?rev=1656023&r1=1656022&r2=1656023&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/Processor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/Processor.java Fri Jan 30 14:23:08 2015
@@ -76,6 +76,4 @@ public interface Processor {
* @return leftover bytes
*/
ByteBuffer getLeftoverInput();
-
-
}
Modified: tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java?rev=1656023&r1=1656022&r2=1656023&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java Fri Jan 30
14:23:08 2015
@@ -135,11 +135,6 @@ public abstract class AbstractAjpProtoco
}
@Override
- protected void initSsl(SocketWrapperBase<S> socket, Processor
processor) {
- // NOOP for AJP
- }
-
- @Override
protected void longPoll(SocketWrapperBase<S> socket, Processor
processor) {
// Same requirements for all AJP connectors
socket.setAsync(true);
Modified: tomcat/trunk/java/org/apache/coyote/ajp/AjpNio2Protocol.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ajp/AjpNio2Protocol.java?rev=1656023&r1=1656022&r2=1656023&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/ajp/AjpNio2Protocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/ajp/AjpNio2Protocol.java Fri Jan 30
14:23:08 2015
@@ -24,7 +24,6 @@ import org.apache.juli.logging.LogFactor
import org.apache.tomcat.util.net.Nio2Channel;
import org.apache.tomcat.util.net.Nio2Endpoint;
import org.apache.tomcat.util.net.Nio2Endpoint.Handler;
-import org.apache.tomcat.util.net.SSLImplementation;
import org.apache.tomcat.util.net.SocketWrapperBase;
@@ -72,12 +71,6 @@ public class AjpNio2Protocol extends Abs
return log;
}
- @Override
- public SSLImplementation getSslImplementation() {
- // AJP does not support SSL
- return null;
- }
-
/**
* Expected to be used by the Poller to release resources on socket
* close, errors etc.
Modified: tomcat/trunk/java/org/apache/coyote/ajp/AjpNioProtocol.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ajp/AjpNioProtocol.java?rev=1656023&r1=1656022&r2=1656023&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/ajp/AjpNioProtocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/ajp/AjpNioProtocol.java Fri Jan 30
14:23:08 2015
@@ -27,7 +27,6 @@ import org.apache.juli.logging.LogFactor
import org.apache.tomcat.util.net.NioChannel;
import org.apache.tomcat.util.net.NioEndpoint;
import org.apache.tomcat.util.net.NioEndpoint.Handler;
-import org.apache.tomcat.util.net.SSLImplementation;
import org.apache.tomcat.util.net.SocketWrapperBase;
/**
@@ -74,12 +73,6 @@ public class AjpNioProtocol extends Abst
return log;
}
- @Override
- public SSLImplementation getSslImplementation() {
- // AJP does not support SSL
- return null;
- }
-
/**
* Expected to be used by the Poller to release resources on socket
* close, errors etc.
Modified:
tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11JsseProtocol.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11JsseProtocol.java?rev=1656023&r1=1656022&r2=1656023&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11JsseProtocol.java
(original)
+++ tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11JsseProtocol.java
Fri Jan 30 14:23:08 2015
@@ -17,13 +17,10 @@
package org.apache.coyote.http11;
import org.apache.tomcat.util.net.AbstractEndpoint;
-import org.apache.tomcat.util.net.SSLImplementation;
public abstract class AbstractHttp11JsseProtocol<S>
extends AbstractHttp11Protocol<S> {
- protected SSLImplementation sslImplementation = null;
-
public AbstractHttp11JsseProtocol(AbstractEndpoint<S> endpoint) {
super(endpoint);
}
@@ -109,19 +106,6 @@ public abstract class AbstractHttp11Jsse
return getEndpoint().getAllowUnsafeLegacyRenegotiation();
}
- private String sslImplementationName = null;
- public String getSslImplementationName() { return sslImplementationName; }
- public void setSslImplementationName(String s) {
- this.sslImplementationName = s;
- }
-
- // ------------------------------------------------------- Lifecycle
methods
-
- @Override
- public void init() throws Exception {
- // SSL implementation needs to be in place before end point is
- // initialized
- sslImplementation =
SSLImplementation.getInstance(sslImplementationName);
- super.init();
- }
+ public String getSslImplementationName() { return
getEndpoint().getSslImplementationName(); }
+ public void setSslImplementationName(String s) {
getEndpoint().setSslImplementationName(s); }
}
Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java?rev=1656023&r1=1656022&r2=1656023&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java Fri Jan
30 14:23:08 2015
@@ -21,7 +21,6 @@ import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.net.AprEndpoint;
import org.apache.tomcat.util.net.AprEndpoint.Poller;
-import org.apache.tomcat.util.net.AprSSLSupport;
import org.apache.tomcat.util.net.SocketStatus;
import org.apache.tomcat.util.net.SocketWrapperBase;
@@ -251,17 +250,6 @@ public class Http11AprProtocol extends A
}
@Override
- protected void initSsl(SocketWrapperBase<Long> socket, Processor
processor) {
- if (getProtocol().isSSLEnabled()) {
- AprSSLSupport sslSupport =
- new AprSSLSupport(socket,
processor.getClientCertProvider());
- processor.setSslSupport(sslSupport);
- } else {
- processor.setSslSupport(null);
- }
- }
-
- @Override
protected void longPoll(SocketWrapperBase<Long> socket, Processor
processor) {
if (processor.isAsync()) {
Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11Nio2Protocol.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11Nio2Protocol.java?rev=1656023&r1=1656022&r2=1656023&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11Nio2Protocol.java
(original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11Nio2Protocol.java Fri Jan
30 14:23:08 2015
@@ -27,8 +27,6 @@ import org.apache.tomcat.util.net.Nio2Ch
import org.apache.tomcat.util.net.Nio2Endpoint;
import org.apache.tomcat.util.net.Nio2Endpoint.Handler;
import org.apache.tomcat.util.net.Nio2Endpoint.Nio2SocketWrapper;
-import org.apache.tomcat.util.net.SSLImplementation;
-import org.apache.tomcat.util.net.SecureNio2Channel;
import org.apache.tomcat.util.net.SocketStatus;
import org.apache.tomcat.util.net.SocketWrapperBase;
@@ -108,12 +106,6 @@ public class Http11Nio2Protocol extends
return log;
}
-
- @Override
- public SSLImplementation getSslImplementation() {
- return ((Http11Nio2Protocol) getProtocol()).sslImplementation;
- }
-
/**
* Expected to be used by the Poller to release resources on socket
* close, errors etc.
@@ -155,19 +147,6 @@ public class Http11Nio2Protocol extends
@Override
- protected void initSsl(SocketWrapperBase<Nio2Channel> socket,
Processor processor) {
- if (getProtocol().isSSLEnabled() && getSslImplementation() != null
- && (socket.getSocket() instanceof SecureNio2Channel)) {
- SecureNio2Channel ch = (SecureNio2Channel)socket.getSocket();
- processor.setSslSupport(getSslImplementation().getSSLSupport(
- ch.getSslEngine().getSession()));
- } else {
- processor.setSslSupport(null);
- }
-
- }
-
- @Override
protected void longPoll(SocketWrapperBase<Nio2Channel> socket,
Processor processor) {
if (processor.isAsync()) {
socket.setAsync(true);
Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java?rev=1656023&r1=1656022&r2=1656023&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java Fri Jan
30 14:23:08 2015
@@ -27,8 +27,6 @@ import org.apache.juli.logging.LogFactor
import org.apache.tomcat.util.net.NioChannel;
import org.apache.tomcat.util.net.NioEndpoint;
import org.apache.tomcat.util.net.NioEndpoint.Handler;
-import org.apache.tomcat.util.net.SSLImplementation;
-import org.apache.tomcat.util.net.SecureNioChannel;
import org.apache.tomcat.util.net.SocketStatus;
import org.apache.tomcat.util.net.SocketWrapperBase;
@@ -135,11 +133,6 @@ public class Http11NioProtocol extends A
}
- @Override
- public SSLImplementation getSslImplementation() {
- return ((Http11NioProtocol) getProtocol()).sslImplementation;
- }
-
/**
* Expected to be used by the Poller to release resources on socket
* close, errors etc.
@@ -201,22 +194,6 @@ public class Http11NioProtocol extends A
}
}
-
- @Override
- protected void initSsl(SocketWrapperBase<NioChannel> socket, Processor
processor) {
- if (getProtocol().isSSLEnabled() &&
- (getSslImplementation() != null)
- && (socket.getSocket() instanceof SecureNioChannel)) {
- SecureNioChannel ch = (SecureNioChannel)socket.getSocket();
- processor.setSslSupport(
- getSslImplementation().getSSLSupport(
- ch.getSslEngine().getSession()));
- } else {
- processor.setSslSupport(null);
- }
-
- }
-
@Override
protected void longPoll(SocketWrapperBase<NioChannel> socket,
Processor processor) {
Modified: tomcat/trunk/java/org/apache/coyote/spdy/SpdyProxyProtocol.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/spdy/SpdyProxyProtocol.java?rev=1656023&r1=1656022&r2=1656023&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/spdy/SpdyProxyProtocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/spdy/SpdyProxyProtocol.java Fri Jan 30
14:23:08 2015
@@ -32,7 +32,6 @@ import org.apache.tomcat.spdy.SpdyContex
import org.apache.tomcat.spdy.SpdyStream;
import org.apache.tomcat.util.net.NioChannel;
import org.apache.tomcat.util.net.NioEndpoint;
-import org.apache.tomcat.util.net.SSLImplementation;
import org.apache.tomcat.util.net.SocketStatus;
import org.apache.tomcat.util.net.SocketWrapperBase;
@@ -130,11 +129,6 @@ public class SpdyProxyProtocol extends A
}
@Override
- public SSLImplementation getSslImplementation() {
- return null;
- }
-
- @Override
public void release(SocketWrapperBase<NioChannel> socket) {
// TODO Auto-generated method stub
}
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java?rev=1656023&r1=1656022&r2=1656023&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java Fri Jan
30 14:23:08 2015
@@ -915,6 +915,12 @@ public abstract class AbstractEndpoint<S
// -------------------- SSL related properties --------------------
+ private String sslImplementationName = null;
+ public String getSslImplementationName() { return sslImplementationName; }
+ public void setSslImplementationName(String s) {
+ this.sslImplementationName = s;
+ }
+
private String algorithm = KeyManagerFactory.getDefaultAlgorithm();
public String getAlgorithm() { return algorithm;}
public void setAlgorithm(String s ) { this.algorithm = s;}
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java?rev=1656023&r1=1656022&r2=1656023&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Fri Jan 30
14:23:08 2015
@@ -2752,6 +2752,16 @@ public class AprEndpoint extends Abstrac
@Override
+ public SSLSupport getSslSupport(String clientCertProvider) {
+ if (getEndpoint().isSSLEnabled()) {
+ return new AprSSLSupport(this, clientCertProvider);
+ } else {
+ return null;
+ }
+ }
+
+
+ @Override
public void doClientAuth(SSLSupport sslSupport) {
long socket = getSocket().longValue();
// Configure connection to require a certificate
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java?rev=1656023&r1=1656022&r2=1656023&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java Fri Jan 30
14:23:08 2015
@@ -45,6 +45,7 @@ import java.util.concurrent.atomic.Atomi
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSessionContext;
import javax.net.ssl.X509KeyManager;
@@ -168,6 +169,7 @@ public class Nio2Endpoint extends Abstra
}
+ private SSLImplementation sslImplementation = null;
private SSLContext sslContext = null;
public SSLContext getSSLContext() { return sslContext;}
public void setSSLContext(SSLContext c) { sslContext = c;}
@@ -197,6 +199,11 @@ public class Nio2Endpoint extends Abstra
}
+ public SSLImplementation getSslImplementation() {
+ return sslImplementation;
+ }
+
+
@Override
public String[] getCiphersUsed() {
return enabledCiphers;
@@ -282,7 +289,8 @@ public class Nio2Endpoint extends Abstra
// Initialize SSL if needed
if (isSSLEnabled()) {
- SSLUtil sslUtil = handler.getSslImplementation().getSSLUtil(this);
+ sslImplementation =
SSLImplementation.getInstance(getSslImplementationName());
+ SSLUtil sslUtil = sslImplementation.getSSLUtil(this);
sslContext = sslUtil.createSSLContext();
sslContext.init(wrap(sslUtil.getKeyManagers()),
@@ -335,6 +343,8 @@ public class Nio2Endpoint extends Abstra
socketProperties.getBufferPool());
}
+ sslImplementation =
SSLImplementation.getInstance(getSslImplementationName());
+
// Create worker collection
if ( getExecutor() == null ) {
createExecutor();
@@ -1419,6 +1429,22 @@ public class Nio2Endpoint extends Abstra
}
+ /**
+ * {@inheritDoc}
+ * @param clientCertProvider Ignored for this implementation
+ */
+ @Override
+ public SSLSupport getSslSupport(String clientCertProvider) {
+ if (getSocket() instanceof SecureNio2Channel) {
+ SecureNio2Channel ch = (SecureNio2Channel) getSocket();
+ SSLSession session = ch.getSslEngine().getSession();
+ return ((Nio2Endpoint)
getEndpoint()).getSslImplementation().getSSLSupport(session);
+ } else {
+ return null;
+ }
+ }
+
+
@Override
public void doClientAuth(SSLSupport sslSupport) {
SecureNio2Channel sslChannel = (SecureNio2Channel) getSocket();
@@ -1447,7 +1473,6 @@ public class Nio2Endpoint extends Abstra
public interface Handler extends AbstractEndpoint.Handler<Nio2Channel> {
public void release(SocketWrapperBase<Nio2Channel> socket);
public void closeAll();
- public SSLImplementation getSslImplementation();
public void onCreateSSLEngine(SSLEngine engine);
}
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java?rev=1656023&r1=1656022&r2=1656023&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java Fri Jan 30
14:23:08 2015
@@ -45,6 +45,7 @@ import java.util.concurrent.atomic.Atomi
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSessionContext;
import javax.net.ssl.X509KeyManager;
@@ -230,6 +231,7 @@ public class NioEndpoint extends Abstrac
}
+ private SSLImplementation sslImplementation = null;
private SSLContext sslContext = null;
public SSLContext getSSLContext() { return sslContext;}
public void setSSLContext(SSLContext c) { sslContext = c;}
@@ -255,6 +257,11 @@ public class NioEndpoint extends Abstrac
}
+ public SSLImplementation getSslImplementation() {
+ return sslImplementation;
+ }
+
+
@Override
public String[] getCiphersUsed() {
return enabledCiphers;
@@ -340,7 +347,8 @@ public class NioEndpoint extends Abstrac
// Initialize SSL if needed
if (isSSLEnabled()) {
- SSLUtil sslUtil = handler.getSslImplementation().getSSLUtil(this);
+ sslImplementation =
SSLImplementation.getInstance(getSslImplementationName());
+ SSLUtil sslUtil = sslImplementation.getSSLUtil(this);
sslContext = sslUtil.createSSLContext();
sslContext.init(wrap(sslUtil.getKeyManagers()),
@@ -1607,6 +1615,22 @@ public class NioEndpoint extends Abstrac
}
+ /**
+ * {@inheritDoc}
+ * @param clientCertProvider Ignored for this implementation
+ */
+ @Override
+ public SSLSupport getSslSupport(String clientCertProvider) {
+ if (getSocket() instanceof SecureNioChannel) {
+ SecureNioChannel ch = (SecureNioChannel) getSocket();
+ SSLSession session = ch.getSslEngine().getSession();
+ return ((NioEndpoint)
getEndpoint()).getSslImplementation().getSSLSupport(session);
+ } else {
+ return null;
+ }
+ }
+
+
@Override
public void doClientAuth(SSLSupport sslSupport) {
SecureNioChannel sslChannel = (SecureNioChannel) getSocket();
@@ -1635,7 +1659,6 @@ public class NioEndpoint extends Abstrac
public interface Handler extends AbstractEndpoint.Handler<NioChannel> {
public void release(SocketWrapperBase<NioChannel> socket);
public void release(SocketChannel socket);
- public SSLImplementation getSslImplementation();
public void onCreateSSLEngine(SSLEngine engine);
}
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapperBase.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapperBase.java?rev=1656023&r1=1656022&r2=1656023&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapperBase.java
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapperBase.java Fri Jan
30 14:23:08 2015
@@ -626,6 +626,8 @@ public abstract class SocketWrapperBase<
*/
public abstract void doClientAuth(SSLSupport sslSupport);
+ public abstract SSLSupport getSslSupport(String clientCertProvider);
+
/*
* TODO
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]