Home | History | Annotate | Download | only in socket
      1 /*
      2  * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
      3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      4  *
      5  * This code is free software; you can redistribute it and/or modify it
      6  * under the terms of the GNU General Public License version 2 only, as
      7  * published by the Free Software Foundation.  Oracle designates this
      8  * particular file as subject to the "Classpath" exception as provided
      9  * by Oracle in the LICENSE file that accompanied this code.
     10  *
     11  * This code is distributed in the hope that it will be useful, but WITHOUT
     12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14  * version 2 for more details (a copy is included in the LICENSE file that
     15  * accompanied this code).
     16  *
     17  * You should have received a copy of the GNU General Public License version
     18  * 2 along with this work; if not, write to the Free Software Foundation,
     19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     20  *
     21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     22  * or visit www.oracle.com if you need additional information or have any
     23  * questions.
     24  */
     25 
     26 #include <stdlib.h>
     27 #include <sys/types.h>
     28 #include <sys/socket.h>
     29 #include <netinet/in.h>
     30 #include <arpa/inet.h>
     31 #include <unistd.h>
     32 #include <fcntl.h>
     33 #include <errno.h>
     34 #include <string.h>
     35 #include <sys/time.h>
     36 #ifdef __solaris__
     37 #include <thread.h>
     38 #else
     39 #include <pthread.h>
     40 #include <sys/poll.h>
     41 #endif
     42 
     43 #include "socket_md.h"
     44 #include "sysSocket.h"
     45 
     46 int
     47 dbgsysListen(int fd, int backlog) {
     48     return listen(fd, backlog);
     49 }
     50 
     51 int
     52 dbgsysConnect(int fd, struct sockaddr *name, socklen_t namelen) {
     53     int rv = connect(fd, name, namelen);
     54     if (rv < 0 && (errno == EINPROGRESS || errno == EINTR)) {
     55         return DBG_EINPROGRESS;
     56     } else {
     57         return rv;
     58     }
     59 }
     60 
     61 int
     62 dbgsysFinishConnect(int fd, int timeout) {
     63     int rv = dbgsysPoll(fd, 0, 1, timeout);
     64     if (rv == 0) {
     65         return DBG_ETIMEOUT;
     66     }
     67     if (rv > 0) {
     68         return 0;
     69     }
     70     return rv;
     71 }
     72 
     73 int
     74 dbgsysAccept(int fd, struct sockaddr *name, socklen_t *namelen) {
     75     int rv;
     76     for (;;) {
     77         rv = accept(fd, name, namelen);
     78         if (rv >= 0) {
     79             return rv;
     80         }
     81         if (errno != ECONNABORTED && errno != EINTR) {
     82             return rv;
     83         }
     84     }
     85 }
     86 
     87 int
     88 dbgsysRecvFrom(int fd, char *buf, size_t nBytes,
     89                   int flags, struct sockaddr *from, socklen_t *fromlen) {
     90     int rv;
     91     do {
     92         rv = recvfrom(fd, buf, nBytes, flags, from, fromlen);
     93     } while (rv == -1 && errno == EINTR);
     94 
     95     return rv;
     96 }
     97 
     98 int
     99 dbgsysSendTo(int fd, char *buf, size_t len,
    100                 int flags, struct sockaddr *to, socklen_t tolen) {
    101     int rv;
    102     do {
    103         rv = sendto(fd, buf, len, flags, to, tolen);
    104     } while (rv == -1 && errno == EINTR);
    105 
    106     return rv;
    107 }
    108 
    109 int
    110 dbgsysRecv(int fd, char *buf, size_t nBytes, int flags) {
    111     int rv;
    112     do {
    113         rv = recv(fd, buf, nBytes, flags);
    114     } while (rv == -1 && errno == EINTR);
    115 
    116     return rv;
    117 }
    118 
    119 int
    120 dbgsysSend(int fd, char *buf, size_t nBytes, int flags) {
    121     int rv;
    122     do {
    123         rv = send(fd, buf, nBytes, flags);
    124     } while (rv == -1 && errno == EINTR);
    125 
    126     return rv;
    127 }
    128 
    129 struct hostent *
    130 dbgsysGetHostByName(char *hostname) {
    131     return gethostbyname(hostname);
    132 }
    133 
    134 unsigned short
    135 dbgsysHostToNetworkShort(unsigned short hostshort) {
    136     return htons(hostshort);
    137 }
    138 
    139 int
    140 dbgsysSocket(int domain, int type, int protocol) {
    141     return socket(domain, type, protocol);
    142 }
    143 
    144 int dbgsysSocketClose(int fd) {
    145     int rv;
    146     do {
    147         rv = close(fd);
    148     } while (rv == -1 && errno == EINTR);
    149 
    150     return rv;
    151 }
    152 
    153 int
    154 dbgsysBind(int fd, struct sockaddr *name, socklen_t namelen) {
    155     return bind(fd, name, namelen);
    156 }
    157 
    158 uint32_t
    159 dbgsysInetAddr(const char* cp) {
    160     return (uint32_t)inet_addr(cp);
    161 }
    162 
    163 uint32_t
    164 dbgsysHostToNetworkLong(uint32_t hostlong) {
    165     return htonl(hostlong);
    166 }
    167 
    168 unsigned short
    169 dbgsysNetworkToHostShort(unsigned short netshort) {
    170     return ntohs(netshort);
    171 }
    172 
    173 int
    174 dbgsysGetSocketName(int fd, struct sockaddr *name, socklen_t *namelen) {
    175     return getsockname(fd, name, namelen);
    176 }
    177 
    178 uint32_t
    179 dbgsysNetworkToHostLong(uint32_t netlong) {
    180     return ntohl(netlong);
    181 }
    182 
    183 
    184 int
    185 dbgsysSetSocketOption(int fd, jint cmd, jboolean on, jvalue value)
    186 {
    187     if (cmd == TCP_NODELAY) {
    188         struct protoent *proto = getprotobyname("TCP");
    189         int tcp_level = (proto == 0 ? IPPROTO_TCP: proto->p_proto);
    190         uint32_t onl = (uint32_t)on;
    191 
    192         if (setsockopt(fd, tcp_level, TCP_NODELAY,
    193                        (char *)&onl, sizeof(uint32_t)) < 0) {
    194                 return SYS_ERR;
    195         }
    196     } else if (cmd == SO_LINGER) {
    197         struct linger arg;
    198         arg.l_onoff = on;
    199 
    200         if(on) {
    201             arg.l_linger = (unsigned short)value.i;
    202             if(setsockopt(fd, SOL_SOCKET, SO_LINGER,
    203                           (char*)&arg, sizeof(arg)) < 0) {
    204                 return SYS_ERR;
    205             }
    206         } else {
    207             if (setsockopt(fd, SOL_SOCKET, SO_LINGER,
    208                            (char*)&arg, sizeof(arg)) < 0) {
    209                 return SYS_ERR;
    210             }
    211         }
    212     } else if (cmd == SO_SNDBUF) {
    213         jint buflen = value.i;
    214         if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF,
    215                        (char *)&buflen, sizeof(buflen)) < 0) {
    216             return SYS_ERR;
    217         }
    218     } else if (cmd == SO_REUSEADDR) {
    219         int oni = (int)on;
    220         if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
    221                        (char *)&oni, sizeof(oni)) < 0) {
    222             return SYS_ERR;
    223 
    224         }
    225     } else {
    226         return SYS_ERR;
    227     }
    228     return SYS_OK;
    229 }
    230 
    231 int
    232 dbgsysConfigureBlocking(int fd, jboolean blocking) {
    233     int flags = fcntl(fd, F_GETFL);
    234 
    235     if ((blocking == JNI_FALSE) && !(flags & O_NONBLOCK)) {
    236         return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
    237     }
    238     if ((blocking == JNI_TRUE) && (flags & O_NONBLOCK)) {
    239         return fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
    240     }
    241     return 0;
    242 }
    243 
    244 int
    245 dbgsysPoll(int fd, jboolean rd, jboolean wr, long timeout) {
    246     struct pollfd fds[1];
    247     int rv;
    248 
    249     fds[0].fd = fd;
    250     fds[0].events = 0;
    251     if (rd) {
    252         fds[0].events |= POLLIN;
    253     }
    254     if (wr) {
    255         fds[0].events |= POLLOUT;
    256     }
    257     fds[0].revents = 0;
    258 
    259     rv = poll(&fds[0], 1, timeout);
    260     if (rv >= 0) {
    261         rv = 0;
    262         if (fds[0].revents & POLLIN) {
    263             rv |= DBG_POLLIN;
    264         }
    265         if (fds[0].revents & POLLOUT) {
    266             rv |= DBG_POLLOUT;
    267         }
    268     }
    269     return rv;
    270 }
    271 
    272 int
    273 dbgsysGetLastIOError(char *buf, jint size) {
    274     char *msg = strerror(errno);
    275     strncpy(buf, msg, size-1);
    276     buf[size-1] = '\0';
    277     return 0;
    278 }
    279 
    280 #ifdef __solaris__
    281 int
    282 dbgsysTlsAlloc() {
    283     thread_key_t tk;
    284     if (thr_keycreate(&tk, NULL)) {
    285         perror("thr_keycreate");
    286         exit(-1);
    287     }
    288     return (int)tk;
    289 }
    290 
    291 void
    292 dbgsysTlsFree(int index) {
    293    /* no-op */
    294 }
    295 
    296 void
    297 dbgsysTlsPut(int index, void *value) {
    298     thr_setspecific((thread_key_t)index, value) ;
    299 }
    300 
    301 void *
    302 dbgsysTlsGet(int index) {
    303     void* r = NULL;
    304     thr_getspecific((thread_key_t)index, &r);
    305     return r;
    306 }
    307 
    308 #else
    309 int
    310 dbgsysTlsAlloc() {
    311     pthread_key_t key;
    312     if (pthread_key_create(&key, NULL)) {
    313         perror("pthread_key_create");
    314         exit(-1);
    315     }
    316     return (int)key;
    317 }
    318 
    319 void
    320 dbgsysTlsFree(int index) {
    321     pthread_key_delete((pthread_key_t)index);
    322 }
    323 
    324 void
    325 dbgsysTlsPut(int index, void *value) {
    326     pthread_setspecific((pthread_key_t)index, value) ;
    327 }
    328 
    329 void *
    330 dbgsysTlsGet(int index) {
    331     return pthread_getspecific((pthread_key_t)index);
    332 }
    333 
    334 #endif
    335 
    336 long
    337 dbgsysCurrentTimeMillis() {
    338     struct timeval t;
    339     gettimeofday(&t, 0);
    340     return ((jlong)t.tv_sec) * 1000 + (jlong)(t.tv_usec/1000);
    341 }
    342