diff --git a/mozilla/security/jss/lib/jss.def b/mozilla/security/jss/lib/jss.def
index 3d9b5548785..be5fa95bb04 100644
--- a/mozilla/security/jss/lib/jss.def
+++ b/mozilla/security/jss/lib/jss.def
@@ -218,3 +218,10 @@ Java_org_mozilla_jss_pkcs11_PK11Store_getEncryptedPrivateKeyInfo;
;+ local:
;+ *;
;+};
+;+JSS_3.1.1 { # JSS 3.1.1 release
+;+ global:
+Java_org_mozilla_jss_ssl_SSLServerSocket_setReuseAddress;
+Java_org_mozilla_jss_ssl_SSLServerSocket_getReuseAddress;
+;+ local:
+;+ *;
+;+};
diff --git a/mozilla/security/jss/org/mozilla/jss/ssl/SSLServerSocket.c b/mozilla/security/jss/org/mozilla/jss/ssl/SSLServerSocket.c
index 180a46d53a8..54aaa34ab66 100644
--- a/mozilla/security/jss/org/mozilla/jss/ssl/SSLServerSocket.c
+++ b/mozilla/security/jss/org/mozilla/jss/ssl/SSLServerSocket.c
@@ -222,3 +222,51 @@ finish:
(*env)->ReleaseStringUTFChars(env, nicknameStr, nickname);
}
}
+
+JNIEXPORT void JNICALL
+Java_org_mozilla_jss_ssl_SSLServerSocket_setReuseAddress(
+ JNIEnv *env, jobject self, jboolean reuse)
+{
+ JSSL_SocketData *sock;
+ PRStatus status;
+ PRSocketOptionData sockOptData;
+
+ if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish;
+
+ sockOptData.option = PR_SockOpt_Reuseaddr;
+ sockOptData.value.reuse_addr = ((reuse == JNI_TRUE) ? PR_TRUE : PR_FALSE );
+
+ status = PR_SetSocketOption(sock->fd, &sockOptData);
+ if( status != PR_SUCCESS ) {
+ JSS_throwMsgPrErr(env, SOCKET_EXCEPTION, "PR_SetSocketOption failed");
+ goto finish;
+ }
+
+finish:
+ return;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_org_mozilla_jss_ssl_SSLServerSocket_getReuseAddress(
+ JNIEnv *env, jobject self)
+{
+ JSSL_SocketData *sock;
+ PRStatus status;
+ PRSocketOptionData sockOptData;
+
+ if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish;
+
+ sockOptData.option = PR_SockOpt_Reuseaddr;
+
+ status = PR_GetSocketOption(sock->fd, &sockOptData);
+ if( status != PR_SUCCESS ) {
+ JSS_throwMsgPrErr(env, SOCKET_EXCEPTION, "PR_SetSocketOption failed");
+ goto finish;
+ }
+
+finish:
+ /* If we got here via failure, reuse_addr might be uninitialized. But in
+ * that case we're throwing an exception, so the return value doesn't
+ * matter. */
+ return ((sockOptData.value.reuse_addr == PR_TRUE) ? JNI_TRUE : JNI_FALSE);
+}
diff --git a/mozilla/security/jss/org/mozilla/jss/ssl/SSLServerSocket.java b/mozilla/security/jss/org/mozilla/jss/ssl/SSLServerSocket.java
index 768dd840362..ab4cfc9d2e7 100644
--- a/mozilla/security/jss/org/mozilla/jss/ssl/SSLServerSocket.java
+++ b/mozilla/security/jss/org/mozilla/jss/ssl/SSLServerSocket.java
@@ -87,6 +87,26 @@ public class SSLServerSocket extends java.net.ServerSocket {
public SSLServerSocket(int port, int backlog, InetAddress bindAddr,
SSLCertificateApprovalCallback certApprovalCallback)
throws IOException
+ {
+ this(port,backlog, bindAddr, certApprovalCallback, false);
+ }
+
+ /**
+ * Creates a server socket listening on the given port.
+ * @param backlog The size of the socket's listen queue.
+ * @param bindAddr The local address to which to bind. If null, an
+ * unspecified local address will be bound to.
+ * @param certApprovalCallback Will get called to approve any certificate
+ * presented by the client.
+ * @param reuseAddr Reuse the local bind port; this parameter sets
+ * the SO_REUSEADDR option on the socket before calling
+ * bind(). The default is false for backward
+ * compatibility.
+ */
+ public SSLServerSocket(int port, int backlog, InetAddress bindAddr,
+ SSLCertificateApprovalCallback certApprovalCallback,
+ boolean reuseAddr)
+ throws IOException
{
// Dance the dance of fools. The superclass doesn't have a default
// constructor, so we have to trick it here. This is an example
@@ -100,6 +120,8 @@ public class SSLServerSocket extends java.net.ServerSocket {
base.setProxy(sockProxy);
+ setReuseAddress(reuseAddr);
+
// bind it to the local address and port
if( bindAddr == null ) {
bindAddr = anyLocalAddr;
@@ -150,6 +172,9 @@ public class SSLServerSocket extends java.net.ServerSocket {
return base.getTimeout();
}
+ protected native void setReuseAddress(boolean reuse) throws SocketException;
+ protected native boolean getReuseAddress() throws SocketException;
+
private native byte[] socketAccept(SSLSocket s, int timeout,
boolean handshakeAsClient) throws SocketException;