corda/sgx-jvm/avian/classpath/sockets.cpp

205 lines
5.0 KiB
C++
Raw Normal View History

2015-03-13 18:52:59 +00:00
/* Copyright (c) 2008-2015, Avian Contributors
2013-11-04 21:07:43 +00:00
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
/*
* This file implements a simple cross-platform JNI sockets API
* It is used from different classes of the default Avian classpath
*/
2017-01-19 16:55:54 +00:00
#ifndef SGX
2013-11-04 21:07:43 +00:00
#include "sockets.h"
namespace avian {
namespace classpath {
namespace sockets {
2014-07-11 15:50:18 +00:00
int last_socket_error()
{
2013-11-04 21:07:43 +00:00
#ifdef PLATFORM_WINDOWS
2014-07-11 15:50:18 +00:00
int error = WSAGetLastError();
2013-11-04 21:07:43 +00:00
#else
2014-07-11 15:50:18 +00:00
int error = errno;
2013-11-04 21:07:43 +00:00
#endif
2014-07-11 15:50:18 +00:00
return error;
2013-11-04 21:07:43 +00:00
}
2014-07-11 15:50:18 +00:00
void init(JNIEnv* ONLY_ON_WINDOWS(e))
{
2013-11-04 21:07:43 +00:00
#ifdef PLATFORM_WINDOWS
static bool wsaInitialized = false;
if (not wsaInitialized) {
2014-07-11 15:50:18 +00:00
WSADATA data;
int r = WSAStartup(MAKEWORD(2, 2), &data);
if (r or LOBYTE(data.wVersion) != 2 or HIBYTE(data.wVersion) != 2) {
throwNew(e, "java/io/IOException", "WSAStartup failed");
} else {
wsaInitialized = true;
}
2013-11-04 21:07:43 +00:00
}
#endif
}
2014-07-11 15:50:18 +00:00
SOCKET create(JNIEnv* e)
{
SOCKET sock;
if (INVALID_SOCKET == (sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))) {
char buf[255];
sprintf(
buf, "Can't create a socket. System error: %d", last_socket_error());
throwNew(e, "java/io/IOException", buf);
return 0; // This doesn't matter cause we have risen an exception
}
return sock;
2013-11-04 21:07:43 +00:00
}
2014-07-11 15:50:18 +00:00
void connect(JNIEnv* e, SOCKET sock, long addr, short port)
{
sockaddr_in adr;
adr.sin_family = AF_INET;
2013-11-04 21:07:43 +00:00
#ifdef PLATFORM_WINDOWS
2014-07-11 15:50:18 +00:00
adr.sin_addr.S_un.S_addr = htonl(addr);
2013-11-04 21:07:43 +00:00
#else
2014-07-11 15:50:18 +00:00
adr.sin_addr.s_addr = htonl(addr);
2013-11-04 21:07:43 +00:00
#endif
2014-07-11 15:50:18 +00:00
adr.sin_port = htons(port);
if (SOCKET_ERROR == ::connect(sock, (sockaddr*)&adr, sizeof(adr))) {
char buf[255];
sprintf(
buf, "Can't connect a socket. System error: %d", last_socket_error());
throwNew(e, "java/io/IOException", buf);
return;
}
2013-11-04 21:07:43 +00:00
}
2014-07-11 15:50:18 +00:00
void bind(JNIEnv* e, SOCKET sock, long addr, short port)
{
sockaddr_in adr;
adr.sin_family = AF_INET;
2013-11-04 21:07:43 +00:00
#ifdef PLATFORM_WINDOWS
2014-07-11 15:50:18 +00:00
adr.sin_addr.S_un.S_addr = htonl(addr);
2013-11-04 21:07:43 +00:00
#else
2014-07-11 15:50:18 +00:00
adr.sin_addr.s_addr = htonl(addr);
2013-11-04 21:07:43 +00:00
#endif
2014-07-11 15:50:18 +00:00
adr.sin_port = htons(port);
2013-11-04 21:07:43 +00:00
2014-07-11 15:50:18 +00:00
if (SOCKET_ERROR == ::bind(sock, (sockaddr*)&adr, sizeof(adr))) {
char buf[255];
sprintf(buf, "Can't bind a socket. System error: %d", last_socket_error());
throwNew(e, "java/io/IOException", buf);
return;
}
2013-11-04 21:07:43 +00:00
}
2014-07-11 15:50:18 +00:00
SOCKET accept(JNIEnv* e, SOCKET sock, long* client_addr, short* client_port)
{
sockaddr_in adr;
SOCKET client_socket = ::accept(sock, (sockaddr*)&adr, NULL);
if (INVALID_SOCKET == client_socket) {
char buf[255];
sprintf(buf,
"Can't accept the incoming connection. System error: %d",
last_socket_error());
throwNew(e, "java/io/IOException", buf);
return INVALID_SOCKET;
}
if (client_addr != NULL) {
#ifdef PLATFORM_WINDOWS
*client_addr = ntohl(adr.sin_addr.S_un.S_addr);
#else
*client_addr = ntohl(adr.sin_addr.s_addr);
#endif
}
if (client_port != NULL) {
*client_port = ntohs(adr.sin_port);
}
return client_socket;
2013-11-04 21:07:43 +00:00
}
2014-07-11 15:50:18 +00:00
void send(JNIEnv* e, SOCKET sock, const char* buff_ptr, int buff_size)
{
if (SOCKET_ERROR == ::send(sock, buff_ptr, buff_size, 0)) {
char buf[255];
sprintf(buf,
"Can't send data through the socket. System error: %d",
last_socket_error());
throwNew(e, "java/io/IOException", buf);
return;
}
2013-11-04 21:07:43 +00:00
}
2014-07-11 15:50:18 +00:00
int recv(JNIEnv* e, SOCKET sock, char* buff_ptr, int buff_size)
{
int length = ::recv(sock, buff_ptr, buff_size, 0);
if (SOCKET_ERROR == length) {
char buf[255];
sprintf(buf,
"Can't receive data through the socket. System error: %d",
last_socket_error());
throwNew(e, "java/io/IOException", buf);
return 0; // This doesn't matter cause we have risen an exception
}
return length;
2013-11-04 21:07:43 +00:00
}
2014-07-11 15:50:18 +00:00
void abort(JNIEnv* e, SOCKET sock)
{
if (SOCKET_ERROR == ::closesocket(sock)) {
char buf[255];
sprintf(
buf, "Can't close the socket. System error: %d", last_socket_error());
throwNew(e, "java/io/IOException", buf);
}
2013-11-04 21:07:43 +00:00
}
2014-07-11 15:50:18 +00:00
void close(JNIEnv* e, SOCKET sock)
{
if (SOCKET_ERROR == ::shutdown(sock, SD_BOTH)) {
int errcode = last_socket_error();
if (errcode != ENOTCONN) {
char buf[255];
sprintf(buf, "Can't shutdown the socket. System error: %d", errcode);
throwNew(e, "java/io/IOException", buf);
}
}
2013-11-04 21:07:43 +00:00
}
2014-07-11 15:50:18 +00:00
void close_input(JNIEnv* e, SOCKET sock)
{
if (SOCKET_ERROR == ::shutdown(sock, SD_RECEIVE)) {
int errcode = last_socket_error();
if (errcode != ENOTCONN) {
char buf[255];
sprintf(buf, "Can't shutdown the socket. System error: %d", errcode);
throwNew(e, "java/io/IOException", buf);
}
}
2013-11-04 21:07:43 +00:00
}
2014-07-11 15:50:18 +00:00
void close_output(JNIEnv* e, SOCKET sock)
{
if (SOCKET_ERROR == ::shutdown(sock, SD_SEND)) {
int errcode = last_socket_error();
if (errcode != ENOTCONN) {
char buf[255];
sprintf(buf, "Can't shutdown the socket. System error: %d", errcode);
throwNew(e, "java/io/IOException", buf);
}
}
}
2013-11-04 21:07:43 +00:00
}
}
}
2017-01-19 16:55:54 +00:00
#endif