Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IPv6 support #58 (+ Integration tests Windows fix) #86

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
245 changes: 168 additions & 77 deletions barchart-udt-core/src/main/c++/jni/JNIHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Developers: Andrei Pozolotin, CCob
* Developers: Andrei Pozolotin, CCob, Michal Holic;
*
* =================================================================================
*/
Expand Down Expand Up @@ -125,16 +125,7 @@ jobject X_NewLong(JNIEnv* env, int64_t value) {
return env->NewObject(jdk_Long, jdk_Long_init, (jlong) value);
}

// NOTE: ipv4 only
int X_InitSockAddr(sockaddr* sockAddr) {
CHK_NUL_RET_ERR(sockAddr, "sockAddr");
sockaddr_in* sockAddrIn = (sockaddr_in*) sockAddr;
sockAddrIn->sin_family = AF_INET;
memset(&(sockAddrIn->sin_zero), '\0', 8);
return JNI_OK;
}

// NOTE: ipv4 only
//IPv4
int X_ConvertInetAddressToInteger( //
JNIEnv* env, //
jobject objInetAddress, //
Expand All @@ -151,9 +142,16 @@ int X_ConvertInetAddressToInteger( //

const int sizeArray = env->GetArrayLength(objArray);

jbyte* refArray = env->GetByteArrayElements(objArray, NULL);

int value = 0;
switch (sizeArray) {
case 4:
// IPV4
value |= (0xFF000000 & (refArray[0] << 24));
value |= (0x00FF0000 & (refArray[1] << 16));
value |= (0x0000FF00 & (refArray[2] << 8));
value |= (0x000000FF & (refArray[3]));
break;
case 16:
// IPV6
Expand All @@ -162,27 +160,40 @@ int X_ConvertInetAddressToInteger( //
return JNI_ERR;
}

jbyte* refArray = env->GetByteArrayElements(objArray, NULL);

int value = 0;
value |= (0xFF000000 & (refArray[0] << 24));
value |= (0x00FF0000 & (refArray[1] << 16));
value |= (0x0000FF00 & (refArray[2] << 8));
value |= (0x000000FF & (refArray[3]));

env->ReleaseByteArrayElements(objArray, refArray, 0);

*address = value;

return JNI_OK;
}

//IPv6
int X_ConvertInetAddressToUnsignedCharArray( //
JNIEnv* env, //
jobject objInetAddress, //
unsigned char address[16] //
) {

CHK_NUL_RET_ERR(env, "env");
CHK_NUL_RET_ERR(objInetAddress, "objInetAddress");
CHK_NUL_RET_ERR(address, "address");

const jbyteArray objArray = (jbyteArray) env->CallObjectMethod(
objInetAddress, jdk_InetAddress_getAddress);
CHK_NUL_RET_ERR(objArray, "objArray");

const int sizeArray = env->GetArrayLength(objArray);
env->GetByteArrayRegion(objArray, (jint) 0, (jint) sizeArray, (jbyte*) address);

return JNI_OK;

}

// NOTE: ipv4 only
int X_ConvertInetSocketAddressToSockaddr( //
JNIEnv* env, //
jobject objInetSocketAddress, //
sockaddr* sockAddr //
sockaddr_storage* sockAddr, //
jint socketAddressFamily
) {

CHK_NUL_RET_ERR(env, "env");
Expand All @@ -193,108 +204,188 @@ int X_ConvertInetSocketAddressToSockaddr( //
jdk_InetSocketAddress_getAddress);
CHK_NUL_RET_ERR(objInetAddress, "objInetAddress");

jint address = 0;
jint port = env->CallIntMethod(objInetSocketAddress,
jdk_InetSocketAddress_getPort);

const int rv = X_ConvertInetAddressToInteger(env, objInetAddress, &address);
if (rv == JNI_ERR) {
return JNI_ERR;
}
if (socketAddressFamily == 2) {
//IPv4
jint address = 0;

const int rv = X_ConvertInetAddressToInteger(env, objInetAddress, &address);
if (rv == JNI_ERR) {
return JNI_ERR;
}

sockaddr_in* sockAddrIn = (sockaddr_in*) sockAddr;

sockaddr_in* sockAddrIn = (sockaddr_in*) sockAddr;
sockAddrIn->sin_addr.s_addr = htonl(address);
sockAddrIn->sin_port = htons(port);
} else {
//IPv6
unsigned char address[16] = {};

sockAddrIn->sin_addr.s_addr = htonl(address);
sockAddrIn->sin_port = htons(port);
const int rv = X_ConvertInetAddressToUnsignedCharArray(env, objInetAddress, address);
if (rv == JNI_ERR) {
return JNI_ERR;
}

sockaddr_in6* sockAddrIn = (sockaddr_in6*) sockAddr;

memcpy(sockAddrIn->sin6_addr.s6_addr, address, sizeof address);
sockAddrIn->sin6_port = htons(port);
}

return JNI_OK;

}

// NOTE: only ipv4
jobject X_NewInetAddress( //
JNIEnv* env, //
const jint address //
const void* addressPointer, //
const jint socketAddressFamily //
) {

CHK_NUL_RET_NUL(env, "env");

char valArray[4];
valArray[0] = (address & 0xFF000000) >> 24;
valArray[1] = (address & 0x00FF0000) >> 16;
valArray[2] = (address & 0x0000FF00) >> 8;
valArray[3] = (address & 0x000000FF);
if (socketAddressFamily == 2) {
// IPv4
char valArray[4];
int address = *(int*)addressPointer;
valArray[0] = (address & 0xFF000000) >> 24;
valArray[1] = (address & 0x00FF0000) >> 16;
valArray[2] = (address & 0x0000FF00) >> 8;
valArray[3] = (address & 0x000000FF);

const jbyteArray objArray = env->NewByteArray(4);
const jbyteArray objArray = env->NewByteArray(4);
env->SetByteArrayRegion(objArray, (jint) 0, (jint) 4, (jbyte*) valArray);

env->SetByteArrayRegion(objArray, (jint) 0, (jint) 4, (jbyte*) valArray);
const jobject objInetAddress = env->CallStaticObjectMethod(
jdk_InetAddress, jdk_InetAddress_getByAddress, objArray);
CHK_NUL_RET_NUL(objInetAddress, "objInetAddress");

const jobject objInetAddress = env->CallStaticObjectMethod(
jdk_InetAddress, jdk_InetAddress_getByAddress, objArray);
CHK_NUL_RET_NUL(objInetAddress, "objInetAddress");
return objInetAddress;
} else {
// IPv6
const unsigned char* addressArray = (unsigned char*)addressPointer;

return objInetAddress;
const jbyteArray objArray = env->NewByteArray(16);
env->SetByteArrayRegion(objArray, (jint) 0, (jint) 16, (jbyte*) addressArray);

const jobject objInetAddress = env->CallStaticObjectMethod(
jdk_InetAddress, jdk_InetAddress_getByAddress, objArray);
CHK_NUL_RET_NUL(objInetAddress, "objInetAddress");

return objInetAddress;
}

}

// NOTE: ipv4 only
jobject X_NewInetSocketAddress( //
JNIEnv* env, //
sockaddr* sockAddr //
sockaddr* sockAddr, //
jint socketAddressFamily //
) {

CHK_NUL_RET_NUL(env, "env");
CHK_NUL_RET_NUL(sockAddr, "sockAddr");

sockaddr_in* sockAddrIn = (sockaddr_in*) sockAddr;
const jint address = ntohl(sockAddrIn->sin_addr.s_addr);
const jint port = ntohs(sockAddrIn->sin_port);
if (socketAddressFamily == 2) {
//IPv4
sockaddr_in* sockAddrIn = (sockaddr_in*) sockAddr;

const jint address = ntohl(sockAddrIn->sin_addr.s_addr);
const jint port = ntohs(sockAddrIn->sin_port);

const jobject objInetAddress = X_NewInetAddress(env, &address, socketAddressFamily);
CHK_NUL_RET_NUL(objInetAddress, "objInetAddress");

const jobject objInetSocketAddress = env->NewObject(
jdk_InetSocketAddress, jdk_InetSocketAddress_init,
objInetAddress, port);
CHK_NUL_RET_NUL(objInetSocketAddress, "objInetSocketAddress");

const jobject objInetAddress = X_NewInetAddress(env, address);
CHK_NUL_RET_NUL(objInetAddress, "objInetAddress");
return objInetSocketAddress;
} else {
//IPv6
sockaddr_in6* sockAddrIn = (sockaddr_in6*) sockAddr;

const jobject objInetSocketAddress = env->NewObject(
jdk_InetSocketAddress, jdk_InetSocketAddress_init,
objInetAddress, port);
CHK_NUL_RET_NUL(objInetSocketAddress, "objInetSocketAddress");
const unsigned char* address = sockAddrIn->sin6_addr.s6_addr;
const jint port = ntohs(sockAddrIn->sin6_port);

return objInetSocketAddress;
const jobject objInetAddress = X_NewInetAddress(env, address, socketAddressFamily);
CHK_NUL_RET_NUL(objInetAddress, "objInetAddress");

const jobject objInetSocketAddress = env->NewObject(
jdk_InetSocketAddress, jdk_InetSocketAddress_init,
objInetAddress, port);
CHK_NUL_RET_NUL(objInetSocketAddress, "objInetSocketAddress");

return objInetSocketAddress;
}

}

bool X_IsSockaddrEqualsInetSocketAddress( //
JNIEnv* env, //
sockaddr* sockAddr, //
jobject objSocketAddress //
jobject objSocketAddress, //
jint socketAddressFamily //
) {

CHK_NUL_RET_FLS(env, "env");
CHK_NUL_RET_FLS(sockAddr, "sockAddr");
CHK_NUL_RET_FLS(objSocketAddress, "objSocketAddress");

sockaddr_in* sockAddrIn = (sockaddr_in*) sockAddr;

jint address1 = ntohl(sockAddrIn->sin_addr.s_addr);
jint port1 = ntohs(sockAddrIn->sin_port);

jint address2 = 0;
jint port2 = env->CallIntMethod(objSocketAddress,
jdk_InetSocketAddress_getPort);

jobject objInetAddress = env->CallObjectMethod(objSocketAddress,
jdk_InetSocketAddress_getAddress);
CHK_NUL_RET_ERR(objInetAddress, "objInetAddress");

const int rv = X_ConvertInetAddressToInteger(env, objInetAddress,
&address2);
if (rv == JNI_ERR) {
return false;
}

if (address1 == address2 && port1 == port2) {
return true;
if (socketAddressFamily == 2) {
//IPv4
sockaddr_in* sockAddrIn = (sockaddr_in*) sockAddr;

jint address1 = ntohl(sockAddrIn->sin_addr.s_addr);
jint port1 = ntohs(sockAddrIn->sin_port);

jint address2 = 0;
jint port2 = env->CallIntMethod(objSocketAddress,
jdk_InetSocketAddress_getPort);

jobject objInetAddress = env->CallObjectMethod(objSocketAddress,
jdk_InetSocketAddress_getAddress);
CHK_NUL_RET_ERR(objInetAddress, "objInetAddress");

const int rv = X_ConvertInetAddressToInteger(env, objInetAddress,
&address2);
if (rv == JNI_ERR) {
return false;
}

if (address1 == address2 && port1 == port2) {
return true;
}
} else {
//IPv6
sockaddr_in6* sockAddrIn = (sockaddr_in6*) sockAddr;

unsigned char* address1 = sockAddrIn->sin6_addr.s6_addr;
jint port1 = ntohs(sockAddrIn->sin6_port);

unsigned char address2[16] = {};
jint port2 = env->CallIntMethod(objSocketAddress,
jdk_InetSocketAddress_getPort);

jobject objInetAddress = env->CallObjectMethod(objSocketAddress,
jdk_InetSocketAddress_getAddress);
CHK_NUL_RET_ERR(objInetAddress, "objInetAddress");

const int rv = X_ConvertInetAddressToUnsignedCharArray(env, objInetAddress,
address2);
if (rv == JNI_ERR) {
return false;
}

if (port1 == port2) {
if (memcmp(address1, address2, 16) == 0)
return true;
}
}

return false;

}
16 changes: 5 additions & 11 deletions barchart-udt-core/src/main/c++/jni/JNIHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Developers: Andrei Pozolotin, CCob
* Developers: Andrei Pozolotin, CCob, Michal Holic;
*
* =================================================================================
*/
Expand Down Expand Up @@ -148,8 +148,6 @@ jobject X_NewInteger(JNIEnv *env, int value);

jobject X_NewLong(JNIEnv* env, int64_t value);

int X_InitSockAddr(sockaddr* sockAddr);

inline bool X_IsInRange(jlong min, jlong var, jlong max) {
if (min <= var && var <= max) {
return true;
Expand All @@ -172,19 +170,15 @@ inline void X_ConvertMillisIntoTimeValue(const jlong millisTimeout,
}
}

// NOTE: ipv4 only
int X_ConvertInetSocketAddressToSockaddr(JNIEnv* env,
jobject objInetSocketAddress, sockaddr* sockAddr);
jobject objInetSocketAddress, sockaddr_storage* sockAddr, jint socketAddressFamily);

// NOTE: only ipv4
jobject X_NewInetAddress(JNIEnv* env, jint address);
jobject X_NewInetAddress(JNIEnv* env, void* addressPointer, jshort sin_family);

// NOTE: ipv4 only
jobject X_NewInetSocketAddress(JNIEnv* env, sockaddr* sockAddr);
jobject X_NewInetSocketAddress(JNIEnv* env, sockaddr* sockAddr, jint socketAddressFamily);

// NOTE: ipv4 only
bool X_IsSockaddrEqualsInetSocketAddress(JNIEnv* env, sockaddr* sockAddr,
jobject socketAddress);
jobject socketAddress, jint socketAddressFamily);


void UDT_ThrowExceptionUDT_Message(JNIEnv* env, const jint socketID,
Expand Down
Loading