Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/windows/transport/socket/socket_md.c
48580 views
/*1* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/24#include <windows.h>25#include <winsock2.h>2627#include "sysSocket.h"28#include "socketTransport.h"2930typedef jboolean bool_t;3132/*33* Table of Windows Sockets errors, the specific exception we34* throw for the error, and the error text.35*36* Note that this table excludes OS dependent errors.37*/38static struct {39int errCode;40const char *errString;41} const winsock_errors[] = {42{ WSAEPROVIDERFAILEDINIT, "Provider initialization failed (check %SystemRoot%)" },43{ WSAEACCES, "Permission denied" },44{ WSAEADDRINUSE, "Address already in use" },45{ WSAEADDRNOTAVAIL, "Cannot assign requested address" },46{ WSAEAFNOSUPPORT, "Address family not supported by protocol family" },47{ WSAEALREADY, "Operation already in progress" },48{ WSAECONNABORTED, "Software caused connection abort" },49{ WSAECONNREFUSED, "Connection refused" },50{ WSAECONNRESET, "Connection reset by peer" },51{ WSAEDESTADDRREQ, "Destination address required" },52{ WSAEFAULT, "Bad address" },53{ WSAEHOSTDOWN, "Host is down" },54{ WSAEHOSTUNREACH, "No route to host" },55{ WSAEINPROGRESS, "Operation now in progress" },56{ WSAEINTR, "Interrupted function call" },57{ WSAEINVAL, "Invalid argument" },58{ WSAEISCONN, "Socket is already connected" },59{ WSAEMFILE, "Too many open files" },60{ WSAEMSGSIZE, "The message is larger than the maximum supported by the underlying transport" },61{ WSAENETDOWN, "Network is down" },62{ WSAENETRESET, "Network dropped connection on reset" },63{ WSAENETUNREACH, "Network is unreachable" },64{ WSAENOBUFS, "No buffer space available (maximum connections reached?)" },65{ WSAENOPROTOOPT, "Bad protocol option" },66{ WSAENOTCONN, "Socket is not connected" },67{ WSAENOTSOCK, "Socket operation on nonsocket" },68{ WSAEOPNOTSUPP, "Operation not supported" },69{ WSAEPFNOSUPPORT, "Protocol family not supported" },70{ WSAEPROCLIM, "Too many processes" },71{ WSAEPROTONOSUPPORT, "Protocol not supported" },72{ WSAEPROTOTYPE, "Protocol wrong type for socket" },73{ WSAESHUTDOWN, "Cannot send after socket shutdown" },74{ WSAESOCKTNOSUPPORT, "Socket type not supported" },75{ WSAETIMEDOUT, "Connection timed out" },76{ WSATYPE_NOT_FOUND, "Class type not found" },77{ WSAEWOULDBLOCK, "Resource temporarily unavailable" },78{ WSAHOST_NOT_FOUND, "Host not found" },79{ WSA_NOT_ENOUGH_MEMORY, "Insufficient memory available" },80{ WSANOTINITIALISED, "Successful WSAStartup not yet performed" },81{ WSANO_DATA, "Valid name, no data record of requested type" },82{ WSANO_RECOVERY, "This is a nonrecoverable error" },83{ WSASYSNOTREADY, "Network subsystem is unavailable" },84{ WSATRY_AGAIN, "Nonauthoritative host not found" },85{ WSAVERNOTSUPPORTED, "Winsock.dll version out of range" },86{ WSAEDISCON, "Graceful shutdown in progress" },87{ WSA_OPERATION_ABORTED, "Overlapped operation aborted" },88};899091/*92* Initialize Windows Sockets API support93*/94BOOL WINAPI95DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved)96{97WSADATA wsadata;9899switch (reason) {100case DLL_PROCESS_ATTACH:101if (WSAStartup(MAKEWORD(2,2), &wsadata) != 0) {102return FALSE;103}104break;105106case DLL_PROCESS_DETACH:107WSACleanup();108break;109110default:111break;112}113return TRUE;114}115116/*117* If we get a nonnull function pointer it might still be the case118* that some other thread is in the process of initializing the socket119* function pointer table, but our pointer should still be good.120*/121int122dbgsysListen(int fd, int backlog) {123return listen(fd, backlog);124}125126int127dbgsysConnect(int fd, struct sockaddr *name, socklen_t namelen) {128int rv = connect(fd, name, namelen);129if (rv == SOCKET_ERROR) {130if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK) {131return DBG_EINPROGRESS;132}133}134return rv;135}136137int dbgsysFinishConnect(int fd, int timeout) {138int rv;139struct timeval t;140fd_set wr, ex;141142t.tv_sec = timeout / 1000;143t.tv_usec = (timeout % 1000) * 1000;144145FD_ZERO(&wr);146FD_ZERO(&ex);147FD_SET((unsigned int)fd, &wr);148FD_SET((unsigned int)fd, &ex);149150rv = select(fd+1, 0, &wr, &ex, &t);151if (rv == 0) {152return SYS_ERR; /* timeout */153}154155/*156* Check if there was an error - this is preferable to check if157* the socket is writable because some versions of Windows don't158* report a connected socket as being writable.159*/160if (!FD_ISSET(fd, &ex)) {161return SYS_OK;162}163164/*165* Unable to establish connection - to get the reason we must166* call getsockopt.167*/168return SYS_ERR;169}170171172int173dbgsysAccept(int fd, struct sockaddr *name, socklen_t *namelen) {174return (int)accept(fd, name, namelen);175}176177int178dbgsysRecvFrom(int fd, char *buf, size_t nBytes,179int flags, struct sockaddr *from, socklen_t *fromlen) {180return recvfrom(fd, buf, (int)nBytes, flags, from, fromlen);181}182183int184dbgsysSendTo(int fd, char *buf, size_t len,185int flags, struct sockaddr *to, socklen_t tolen) {186return sendto(fd, buf, (int)len, flags, to, tolen);187}188189int190dbgsysRecv(int fd, char *buf, size_t nBytes, int flags) {191return recv(fd, buf, (int) nBytes, flags);192}193194int195dbgsysSend(int fd, char *buf, size_t nBytes, int flags) {196return send(fd, buf, (int)nBytes, flags);197}198199struct hostent *200dbgsysGetHostByName(char *hostname) {201return gethostbyname(hostname);202}203204unsigned short205dbgsysHostToNetworkShort(unsigned short hostshort) {206return htons(hostshort);207}208209int210dbgsysSocket(int domain, int type, int protocol) {211int fd = (int)socket(domain, type, protocol);212if (fd != SOCKET_ERROR) {213SetHandleInformation((HANDLE)(UINT_PTR)fd, HANDLE_FLAG_INHERIT, FALSE);214}215return fd;216}217218int219dbgsysSocketClose(int fd) {220struct linger l;221int len = sizeof(l);222223if (getsockopt(fd, SOL_SOCKET, SO_LINGER, (char *)&l, &len) == 0) {224if (l.l_onoff == 0) {225WSASendDisconnect(fd, NULL);226}227}228return closesocket(fd);229}230231/* Additions to original follow */232233int234dbgsysBind(int fd, struct sockaddr *name, socklen_t namelen) {235return bind(fd, name, namelen);236}237238239uint32_t240dbgsysInetAddr(const char* cp) {241return (uint32_t)inet_addr(cp);242}243244uint32_t245dbgsysHostToNetworkLong(uint32_t hostlong) {246return (uint32_t)htonl((u_long)hostlong);247}248249unsigned short250dbgsysNetworkToHostShort(unsigned short netshort) {251return ntohs(netshort);252}253254int255dbgsysGetSocketName(int fd, struct sockaddr *name, socklen_t *namelen) {256return getsockname(fd, name, namelen);257}258259uint32_t260dbgsysNetworkToHostLong(uint32_t netlong) {261return (uint32_t)ntohl((u_long)netlong);262}263264/*265* Below Adapted from PlainSocketImpl.c, win32 version 1.18. Changed exception266* throws to returns of SYS_ERR; we should improve the error codes267* eventually. Changed java objects to values the debugger back end can268* more easily deal with.269*/270271int272dbgsysSetSocketOption(int fd, jint cmd, jboolean on, jvalue value)273{274if (cmd == TCP_NODELAY) {275struct protoent *proto = getprotobyname("TCP");276int tcp_level = (proto == 0 ? IPPROTO_TCP: proto->p_proto);277long onl = (long)on;278279if (setsockopt(fd, tcp_level, TCP_NODELAY,280(char *)&onl, sizeof(long)) < 0) {281return SYS_ERR;282}283} else if (cmd == SO_LINGER) {284struct linger arg;285arg.l_onoff = on;286287if(on) {288arg.l_linger = (unsigned short)value.i;289if(setsockopt(fd, SOL_SOCKET, SO_LINGER,290(char*)&arg, sizeof(arg)) < 0) {291return SYS_ERR;292}293} else {294if (setsockopt(fd, SOL_SOCKET, SO_LINGER,295(char*)&arg, sizeof(arg)) < 0) {296return SYS_ERR;297}298}299} else if (cmd == SO_SNDBUF) {300jint buflen = value.i;301if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF,302(char *)&buflen, sizeof(buflen)) < 0) {303return SYS_ERR;304}305} else if (cmd == SO_REUSEADDR) {306/*307* On Windows the SO_REUSEADDR socket option doesn't implement308* BSD semantics. Specifically, the socket option allows multiple309* processes to bind to the same address/port rather than allowing310* a process to bind with a previous connection in the TIME_WAIT311* state. Hence on Windows we never enable this option for TCP312* option.313*/314int sotype, arglen=sizeof(sotype);315if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (void *)&sotype, &arglen) == SOCKET_ERROR) {316return SYS_ERR;317}318if (sotype != SOCK_STREAM) {319int oni = (int)on;320if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,321(char *)&oni, sizeof(oni)) == SOCKET_ERROR) {322return SYS_ERR;323}324}325} else {326return SYS_ERR;327}328return SYS_OK;329}330331int dbgsysConfigureBlocking(int fd, jboolean blocking) {332u_long argp;333int result = 0;334335if (blocking == JNI_FALSE) {336argp = 1;337} else {338argp = 0;339}340result = ioctlsocket(fd, FIONBIO, &argp);341if (result == SOCKET_ERROR) {342return SYS_ERR;343} else {344return SYS_OK;345}346}347348int349dbgsysPoll(int fd, jboolean rd, jboolean wr, long timeout) {350int rv;351struct timeval t;352fd_set rd_tbl, wr_tbl;353354t.tv_sec = timeout / 1000;355t.tv_usec = (timeout % 1000) * 1000;356357FD_ZERO(&rd_tbl);358if (rd) {359FD_SET((unsigned int)fd, &rd_tbl);360}361362FD_ZERO(&wr_tbl);363if (wr) {364FD_SET((unsigned int)fd, &wr_tbl);365}366367rv = select(fd+1, &rd_tbl, &wr_tbl, 0, &t);368if (rv >= 0) {369rv = 0;370if (FD_ISSET(fd, &rd_tbl)) {371rv |= DBG_POLLIN;372}373if (FD_ISSET(fd, &wr_tbl)) {374rv |= DBG_POLLOUT;375}376}377return rv;378}379380int381dbgsysGetLastIOError(char *buf, jint size) {382int table_size = sizeof(winsock_errors) /383sizeof(winsock_errors[0]);384int i;385int error = WSAGetLastError();386387/*388* Check table for known winsock errors389*/390i=0;391while (i < table_size) {392if (error == winsock_errors[i].errCode) {393break;394}395i++;396}397398if (i < table_size) {399strcpy(buf, winsock_errors[i].errString);400} else {401sprintf(buf, "winsock error %d", error);402}403return 0;404}405406407int408dbgsysTlsAlloc() {409return TlsAlloc();410}411412void413dbgsysTlsFree(int index) {414TlsFree(index);415}416417void418dbgsysTlsPut(int index, void *value) {419TlsSetValue(index, value);420}421422void *423dbgsysTlsGet(int index) {424return TlsGetValue(index);425}426427#define FT2INT64(ft) \428((INT64)(ft).dwHighDateTime << 32 | (INT64)(ft).dwLowDateTime)429430long431dbgsysCurrentTimeMillis() {432static long fileTime_1_1_70 = 0; /* midnight 1/1/70 */433SYSTEMTIME st0;434FILETIME ft0;435436/* initialize on first usage */437if (fileTime_1_1_70 == 0) {438memset(&st0, 0, sizeof(st0));439st0.wYear = 1970;440st0.wMonth = 1;441st0.wDay = 1;442SystemTimeToFileTime(&st0, &ft0);443fileTime_1_1_70 = FT2INT64(ft0);444}445446GetSystemTime(&st0);447SystemTimeToFileTime(&st0, &ft0);448449return (FT2INT64(ft0) - fileTime_1_1_70) / 10000;450}451452453