1/*
2 * Copyright (c) 1998, 2019, 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#include <stdio.h>
26#include <string.h>
27#include <errno.h>
28#include <stdlib.h>
29#include <ctype.h>
30
31#include "jni.h"
32#include "jdwpTransport.h"
33#include "sysSocket.h"
34
35#ifdef _WIN32
36 #include <winsock2.h>
37 #include <ws2tcpip.h>
38#else
39 #include <arpa/inet.h>
40 #include <sys/socket.h>
41#endif
42
43/*
44 * The Socket Transport Library.
45 *
46 * This module is an implementation of the Java Debug Wire Protocol Transport
47 * Service Provider Interface - see src/share/javavm/export/jdwpTransport.h.
48 */
49
50static int serverSocketFD = -1;
51static int socketFD = -1;
52static jdwpTransportCallback *callback;
53static JavaVM *jvm;
54static int tlsIndex;
55static jboolean initialized;
56static struct jdwpTransportNativeInterface_ interface;
57static jdwpTransportEnv single_env = (jdwpTransportEnv)&interface;
58
59#define RETURN_ERROR(err, msg) \
60 if (1==1) { \
61 setLastError(err, msg); \
62 return err; \
63 }
64
65#define RETURN_IO_ERROR(msg) RETURN_ERROR(JDWPTRANSPORT_ERROR_IO_ERROR, msg);
66
67#define RETURN_RECV_ERROR(n) \
68 if (n == 0) { \
69 RETURN_ERROR(JDWPTRANSPORT_ERROR_IO_ERROR, "premature EOF"); \
70 } else { \
71 RETURN_IO_ERROR("recv error"); \
72 }
73
74#define MAX_DATA_SIZE 1000
75
76static jint recv_fully(int, char *, int);
77static jint send_fully(int, char *, int);
78
79/* version >= JDWPTRANSPORT_VERSION_1_1 */
80typedef struct {
81 /* subnet and mask are stored as IPv6 addresses, IPv4 is stored as mapped IPv6 */
82 struct in6_addr subnet;
83 struct in6_addr netmask;
84} AllowedPeerInfo;
85
86#define STR(x) #x
87#define MAX_PEER_ENTRIES 32
88#define MAX_PEERS_STR STR(MAX_PEER_ENTRIES)
89static AllowedPeerInfo _peers[MAX_PEER_ENTRIES];
90static int _peers_cnt = 0;
91
92
93static int allowOnlyIPv4 = 0; // reflects "java.net.preferIPv4Stack" sys. property
94static int preferredAddressFamily = AF_INET; // "java.net.preferIPv6Addresses"
95
96/*
97 * Record the last error for this thread.
98 */
99static void
100setLastError(jdwpTransportError err, char *newmsg) {
101 char buf[255];
102 char *msg;
103
104 /* get any I/O first in case any system calls override errno */
105 if (err == JDWPTRANSPORT_ERROR_IO_ERROR) {
106 dbgsysGetLastIOError(buf, sizeof(buf));
107 }
108
109 msg = (char *)dbgsysTlsGet(tlsIndex);
110 if (msg != NULL) {
111 (*callback->free)(msg);
112 }
113
114 if (err == JDWPTRANSPORT_ERROR_IO_ERROR) {
115 char *join_str = ": ";
116 int msg_len = (int)strlen(newmsg) + (int)strlen(join_str) +
117 (int)strlen(buf) + 3;
118 msg = (*callback->alloc)(msg_len);
119 if (msg != NULL) {
120 strcpy(msg, newmsg);
121 strcat(msg, join_str);
122 strcat(msg, buf);
123 }
124 } else {
125 msg = (*callback->alloc)((int)strlen(newmsg)+1);
126 if (msg != NULL) {
127 strcpy(msg, newmsg);
128 }
129 }
130
131 dbgsysTlsPut(tlsIndex, msg);
132}
133
134/*
135 * Return the last error for this thread (may be NULL)
136 */
137static char*
138getLastError() {
139 return (char *)dbgsysTlsGet(tlsIndex);
140}
141
142/* Set options common to client and server sides */
143static jdwpTransportError
144setOptionsCommon(int domain, int fd)
145{
146 jvalue dontcare;
147 int err;
148
149 if (domain == AF_INET6) {
150 int off = 0;
151 // make the socket a dual mode socket
152 // this may fail if IPv4 is not supported - it's ok
153 setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&off, sizeof(off));
154 }
155
156 dontcare.i = 0; /* keep compiler happy */
157 err = dbgsysSetSocketOption(fd, TCP_NODELAY, JNI_TRUE, dontcare);
158 if (err < 0) {
159 RETURN_IO_ERROR("setsockopt TCPNODELAY failed");
160 }
161
162 return JDWPTRANSPORT_ERROR_NONE;
163}
164
165/* Set the SO_REUSEADDR option */
166static jdwpTransportError
167setReuseAddrOption(int fd)
168{
169 jvalue dontcare;
170 int err;
171
172 dontcare.i = 0; /* keep compiler happy */
173
174 err = dbgsysSetSocketOption(fd, SO_REUSEADDR, JNI_TRUE, dontcare);
175 if (err < 0) {
176 RETURN_IO_ERROR("setsockopt SO_REUSEADDR failed");
177 }
178
179 return JDWPTRANSPORT_ERROR_NONE;
180}
181
182static jdwpTransportError
183handshake(int fd, jlong timeout) {
184 const char *hello = "JDWP-Handshake";
185 char b[16];
186 int rv, helloLen, received;
187
188 if (timeout > 0) {
189 dbgsysConfigureBlocking(fd, JNI_FALSE);
190 }
191 helloLen = (int)strlen(hello);
192 received = 0;
193 while (received < helloLen) {
194 int n;
195 char *buf;
196 if (timeout > 0) {
197 rv = dbgsysPoll(fd, JNI_TRUE, JNI_FALSE, (long)timeout);
198 if (rv <= 0) {
199 setLastError(0, "timeout during handshake");
200 return JDWPTRANSPORT_ERROR_IO_ERROR;
201 }
202 }
203 buf = b;
204 buf += received;
205 n = recv_fully(fd, buf, helloLen-received);
206 if (n == 0) {
207 setLastError(0, "handshake failed - connection prematurally closed");
208 return JDWPTRANSPORT_ERROR_IO_ERROR;
209 }
210 if (n < 0) {
211 RETURN_IO_ERROR("recv failed during handshake");
212 }
213 received += n;
214 }
215 if (timeout > 0) {
216 dbgsysConfigureBlocking(fd, JNI_TRUE);
217 }
218 if (strncmp(b, hello, received) != 0) {
219 char msg[80+2*16];
220 b[received] = '\0';
221 /*
222 * We should really use snprintf here but it's not available on Windows.
223 * We can't use jio_snprintf without linking the transport against the VM.
224 */
225 sprintf(msg, "handshake failed - received >%s< - expected >%s<", b, hello);
226 setLastError(0, msg);
227 return JDWPTRANSPORT_ERROR_IO_ERROR;
228 }
229
230 if (send_fully(fd, (char*)hello, helloLen) != helloLen) {
231 RETURN_IO_ERROR("send failed during handshake");
232 }
233 return JDWPTRANSPORT_ERROR_NONE;
234}
235
236static int
237getPortNumber(const char *s_port) {
238 u_long n;
239 char *eptr;
240
241 if (*s_port == 0) {
242 // bad address - colon with no port number in parameters
243 return -1;
244 }
245
246 n = strtoul(s_port, &eptr, 10);
247 if (eptr != s_port + strlen(s_port)) {
248 // incomplete conversion - port number contains non-digit
249 return -1;
250 }
251
252 if (n > (u_short) -1) {
253 // check that value supplied by user is less than
254 // maximum possible u_short value (65535) and
255 // will not be truncated later.
256 return -1;
257 }
258
259 return n;
260}
261
262static unsigned short getPort(struct sockaddr *sa)
263{
264 return dbgsysNetworkToHostShort(sa->sa_family == AF_INET
265 ? (((struct sockaddr_in*)sa)->sin_port)
266 : (((struct sockaddr_in6*)sa)->sin6_port));
267}
268
269/*
270 * Result must be released with dbgsysFreeAddrInfo.
271 */
272static jdwpTransportError
273parseAddress(const char *address, struct addrinfo **result) {
274 const char *colon;
275 size_t hostLen;
276 char *host = NULL;
277 const char *port;
278 struct addrinfo hints;
279 int res;
280
281 *result = NULL;
282
283 /* check for host:port or port */
284 colon = strrchr(address, ':');
285 port = (colon == NULL ? address : colon + 1);
286
287 /* ensure the port is valid (getaddrinfo allows port to be empty) */
288 if (getPortNumber(port) < 0) {
289 RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, "invalid port number specified");
290 }
291
292 memset (&hints, 0, sizeof(hints));
293 hints.ai_family = allowOnlyIPv4 ? AF_INET : AF_UNSPEC;
294 hints.ai_socktype = SOCK_STREAM;
295 hints.ai_protocol = IPPROTO_TCP;
296 hints.ai_flags = AI_NUMERICSERV; // port must be a number
297
298 hostLen = (colon == NULL ? 0 : colon - address);
299 if (hostLen == 0) {
300 /* no hostname - use localhost address (pass NULL to getaddrinfo) */
301 } else if (*address == '*' && hostLen == 1) {
302 /* *:port - listen on all interfaces
303 * use IPv6 socket (to accept IPv6 and mapped IPv4),
304 * pass hostname == NULL to getaddrinfo.
305 */
306 hints.ai_family = allowOnlyIPv4 ? AF_INET : AF_INET6;
307 hints.ai_flags |= AI_PASSIVE | (allowOnlyIPv4 ? 0 : AI_V4MAPPED | AI_ALL);
308 } else {
309 if (address[0] == '[' && colon[-1] == ']') {
310 address++;
311 hostLen -= 2;
312 }
313 host = (*callback->alloc)((int)hostLen + 1);
314 if (host == NULL) {
315 RETURN_ERROR(JDWPTRANSPORT_ERROR_OUT_OF_MEMORY, "out of memory");
316 }
317 strncpy(host, address, hostLen);
318 host[hostLen] = '\0';
319 }
320
321 res = dbgsysGetAddrInfo(host, port, &hints, result);
322 if (host != NULL) {
323 (*callback->free)(host);
324 }
325 if (res != 0) {
326 setLastError(res, "getaddrinfo: unknown host");
327 return JDWPTRANSPORT_ERROR_IO_ERROR;
328 }
329
330 return JDWPTRANSPORT_ERROR_NONE;
331}
332
333/*
334 * Input is sockaddr just because all clients have it.
335 */
336static void convertIPv4ToIPv6(const struct sockaddr *addr4, struct in6_addr *addr6) {
337 // Implement in a platform-independent way.
338 // Spec requires in_addr has s_addr member, in6_addr has s6_addr[16] member.
339 struct in_addr *a4 = &(((struct sockaddr_in*)addr4)->sin_addr);
340 memset(addr6, 0, sizeof(*addr6)); // for safety
341
342 // Mapped address contains 80 zero bits, then 16 "1" bits, then IPv4 address (4 bytes).
343 addr6->s6_addr[10] = addr6->s6_addr[11] = 0xFF;
344 memcpy(&(addr6->s6_addr[12]), &(a4->s_addr), 4);
345}
346
347/*
348 * Parses address (IPv4 or IPv6), fills in result by parsed address.
349 * For IPv4 mapped IPv6 is returned in result, isIPv4 is set.
350 */
351static jdwpTransportError
352parseAllowedAddr(const char *buffer, struct in6_addr *result, int *isIPv4) {
353 struct addrinfo hints;
354 struct addrinfo *addrInfo = NULL;
355 int err;
356
357 /*
358 * To parse both IPv4 and IPv6 need to specify AF_UNSPEC family
359 * (with AF_INET6 IPv4 addresses are not parsed even with AI_V4MAPPED and AI_ALL flags).
360 */
361 memset (&hints, 0, sizeof(hints));
362 hints.ai_family = AF_UNSPEC; // IPv6 or mapped IPv4
363 hints.ai_socktype = SOCK_STREAM;
364 hints.ai_protocol = IPPROTO_TCP;
365 hints.ai_flags = AI_NUMERICHOST; // only numeric addresses, no resolution
366
367 err = dbgsysGetAddrInfo(buffer, NULL, &hints, &addrInfo);
368
369 if (err != 0) {
370 setLastError(err, "getaddrinfo: failed to parse address");
371 return JDWPTRANSPORT_ERROR_IO_ERROR;
372 }
373
374 if (addrInfo->ai_family == AF_INET6) {
375 memcpy(result, &(((struct sockaddr_in6 *)(addrInfo->ai_addr))->sin6_addr), sizeof(*result));
376 *isIPv4 = 0;
377 } else { // IPv4 address - convert to mapped IPv6
378 struct in6_addr addr6;
379 convertIPv4ToIPv6(addrInfo->ai_addr, &addr6);
380 memcpy(result, &addr6, sizeof(*result));
381 *isIPv4 = 1;
382 }
383
384 dbgsysFreeAddrInfo(addrInfo);
385
386 return JDWPTRANSPORT_ERROR_NONE;
387}
388
389/*
390 * Parses prefix length from buffer (integer value), fills in result with corresponding net mask.
391 * For IPv4 (isIPv4 is set), maximum prefix length is 32 bit, for IPv6 - 128 bit.
392 */
393static jdwpTransportError
394parseAllowedMask(const char *buffer, int isIPv4, struct in6_addr *result) {
395 int prefixLen = 0;
396 int maxValue = isIPv4 ? 32 : 128;
397 int i;
398
399 do {
400 if (*buffer < '0' || *buffer > '9') {
401 return JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT;
402 }
403 prefixLen = prefixLen * 10 + (*buffer - '0');
404 if (prefixLen > maxValue) { // avoid overflow
405 return JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT;
406 }
407 buffer++;
408 } while (*buffer != '\0');
409
410 if (isIPv4) {
411 // IPv4 are stored as mapped IPv6, prefixLen needs to be converted too
412 prefixLen += 96;
413 }
414
415 if (prefixLen == 0) {
416 return JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT;
417 }
418
419 // generate mask for prefix length
420 memset(result, 0, sizeof(*result));
421
422 // prefixLen <= 128, so we won't go over result's size
423 for (i = 0; prefixLen > 0; i++, prefixLen -= 8) {
424 if (prefixLen >= 8) {
425 // set the whole byte
426 result->s6_addr[i] = 0xFF;
427 } else {
428 // set only "prefixLen" bits
429 result->s6_addr[i] = (char)(0xFF << (8 - prefixLen));
430 }
431 }
432
433 return JDWPTRANSPORT_ERROR_NONE;
434}
435
436/*
437 * Internal implementation of parseAllowedPeers (requires writable buffer).
438 */
439static jdwpTransportError
440parseAllowedPeersInternal(char *buffer) {
441 char *next;
442 int isIPv4 = 0;
443
444 do {
445 char *mask = NULL;
446 char *endOfAddr = strpbrk(buffer, "/+");
447 if (endOfAddr == NULL) {
448 // this is the last address and there is no prefix length
449 next = NULL;
450 } else {
451 next = endOfAddr + 1;
452 if (*endOfAddr == '/') {
453 // mask (prefix length) presents
454 char *endOfMask = strchr(next, '+');
455 mask = next;
456 if (endOfMask == NULL) {
457 // no more addresses
458 next = NULL;
459 } else {
460 next = endOfMask + 1;
461 *endOfMask = '\0';
462 }
463 }
464 *endOfAddr = '\0';
465 }
466
467 // parse subnet address (IPv4 is stored as mapped IPv6)
468 if (parseAllowedAddr(buffer, &(_peers[_peers_cnt].subnet), &isIPv4) != JDWPTRANSPORT_ERROR_NONE) {
469 _peers_cnt = 0;
470 fprintf(stderr, "Error in allow option: '%s'\n", buffer);
471 RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT,
472 "invalid IP address in allow option");
473 }
474 if (mask != NULL) {
475 size_t i;
476 if (parseAllowedMask(mask, isIPv4, &(_peers[_peers_cnt].netmask)) != JDWPTRANSPORT_ERROR_NONE) {
477 _peers_cnt = 0;
478 fprintf(stderr, "Error in allow option: '%s'\n", mask);
479 RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT,
480 "invalid netmask in allow option");
481 }
482 // for safety update subnet to satisfy the mask
483 for (i = 0; i < sizeof(_peers[_peers_cnt].subnet); i++) {
484 _peers[_peers_cnt].subnet.s6_addr[i] &= _peers[_peers_cnt].netmask.s6_addr[i];
485 }
486 } else {
487 memset(&(_peers[_peers_cnt].netmask), 0xFF, sizeof(_peers[_peers_cnt].netmask));
488 }
489 _peers_cnt++;
490 buffer = next;
491 } while (next != NULL);
492
493 return JDWPTRANSPORT_ERROR_NONE;
494}
495
496/*
497 * Parses 'allow' argument (fills in list of allowed peers (global _peers variable)).
498 * 'Allow' value consists of tokens separated by '+',
499 * each token contains IP address (IPv4 or IPv6) and optional prefixLength:
500 * '<addr>[/<prefixLength>]'.
501 * Example: '192.168.1.10+192.168.0.0/24'
502 * - connections are allowed from 192.168.1.10 and subnet 192.168.0.XX.
503 */
504static jdwpTransportError
505parseAllowedPeers(const char *allowed_peers, size_t len) {
506 // Build a list of allowed peers from char string
507 // of format 192.168.0.10+192.168.0.0/24
508
509 // writable copy of the value
510 char *buffer = (*callback->alloc)((int)len + 1);
511 if (buffer == NULL) {
512 RETURN_ERROR(JDWPTRANSPORT_ERROR_OUT_OF_MEMORY, "out of memory");
513 }
514 strncpy(buffer, allowed_peers, len);
515 buffer[len] = '\0';
516
517 jdwpTransportError err = parseAllowedPeersInternal(buffer);
518
519 (*callback->free)(buffer);
520
521 return err;
522}
523
524static int
525isAddressInSubnet(const struct in6_addr *address, const struct in6_addr *subnet, const struct in6_addr *mask) {
526 size_t i;
527 for (i = 0; i < sizeof(struct in6_addr); i++) {
528 if ((address->s6_addr[i] & mask->s6_addr[i]) != subnet->s6_addr[i]) {
529 return 0;
530 }
531 }
532 return 1;
533}
534
535static int
536isPeerAllowed(struct sockaddr_storage *peer) {
537 struct in6_addr tmp;
538 struct in6_addr *addr6;
539 int i;
540 // _peers contains IPv6 subnet and mask (IPv4 is converted to mapped IPv6)
541 if (peer->ss_family == AF_INET) {
542 convertIPv4ToIPv6((struct sockaddr *)peer, &tmp);
543 addr6 = &tmp;
544 } else {
545 addr6 = &(((struct sockaddr_in6 *)peer)->sin6_addr);
546 }
547
548 for (i = 0; i < _peers_cnt; ++i) {
549 if (isAddressInSubnet(addr6, &(_peers[i].subnet), &(_peers[i].netmask))) {
550 return 1;
551 }
552 }
553
554 return 0;
555}
556
557static jdwpTransportError JNICALL
558socketTransport_getCapabilities(jdwpTransportEnv* env,
559 JDWPTransportCapabilities* capabilitiesPtr)
560{
561 JDWPTransportCapabilities result;
562
563 memset(&result, 0, sizeof(result));
564 result.can_timeout_attach = JNI_TRUE;
565 result.can_timeout_accept = JNI_TRUE;
566 result.can_timeout_handshake = JNI_TRUE;
567
568 *capabilitiesPtr = result;
569
570 return JDWPTRANSPORT_ERROR_NONE;
571}
572
573/*
574 * Starts listening on the specified addrinfo,
575 * returns listening socket and actual listening port.
576 * If the function fails and returned socket != -1, the socket should be closed.
577 */
578static jdwpTransportError startListening(struct addrinfo *ai, int *socket, char** actualAddress)
579{
580 int err;
581
582 *socket = dbgsysSocket(ai->ai_family, SOCK_STREAM, IPPROTO_TCP);
583 if (*socket < 0) {
584 RETURN_IO_ERROR("socket creation failed");
585 }
586
587 err = setOptionsCommon(ai->ai_family, *socket);
588 if (err) {
589 return err;
590 }
591
592 if (getPort(ai->ai_addr) != 0) {
593 /*
594 * Only need SO_REUSEADDR if we're using a fixed port. If we
595 * start seeing EADDRINUSE due to collisions in free ports
596 * then we should retry the dbgsysBind() a few times.
597 */
598 err = setReuseAddrOption(*socket);
599 if (err) {
600 return err;
601 }
602 }
603
604 err = dbgsysBind(*socket, ai->ai_addr, (socklen_t)ai->ai_addrlen);
605 if (err < 0) {
606 RETURN_IO_ERROR("bind failed");
607 }
608
609 err = dbgsysListen(*socket, 1); // only 1 debugger can attach
610 if (err < 0) {
611 RETURN_IO_ERROR("listen failed");
612 }
613
614 {
615 char buf[20];
616 struct sockaddr_storage addr;
617 socklen_t len = sizeof(addr);
618 jint portNum;
619 err = dbgsysGetSocketName(*socket, (struct sockaddr *)&addr, &len);
620 if (err != 0) {
621 RETURN_IO_ERROR("getsockname failed");
622 }
623
624 portNum = getPort((struct sockaddr *)&addr);
625 sprintf(buf, "%d", portNum);
626 *actualAddress = (*callback->alloc)((int)strlen(buf) + 1);
627 if (*actualAddress == NULL) {
628 RETURN_ERROR(JDWPTRANSPORT_ERROR_OUT_OF_MEMORY, "out of memory");
629 } else {
630 strcpy(*actualAddress, buf);
631 }
632 }
633
634 return JDWPTRANSPORT_ERROR_NONE;
635}
636
637static jdwpTransportError JNICALL
638socketTransport_startListening(jdwpTransportEnv* env, const char* address,
639 char** actualAddress)
640{
641 int err;
642 int pass;
643 struct addrinfo *addrInfo = NULL;
644 struct addrinfo *listenAddr = NULL;
645 struct addrinfo *ai = NULL;
646
647 /* no address provided */
648 if ((address == NULL) || (address[0] == '\0')) {
649 address = "0";
650 }
651
652 err = parseAddress(address, &addrInfo);
653 if (err != JDWPTRANSPORT_ERROR_NONE) {
654 return err;
655 }
656
657 /* 1st pass - preferredAddressFamily (by default IPv4), 2nd pass - the rest */
658 for (pass = 0; pass < 2 && listenAddr == NULL; pass++) {
659 for (ai = addrInfo; ai != NULL; ai = ai->ai_next) {
660 if ((pass == 0 && ai->ai_family == preferredAddressFamily) ||
661 (pass == 1 && ai->ai_family != preferredAddressFamily))
662 {
663 listenAddr = ai;
664 break;
665 }
666 }
667 }
668
669 if (listenAddr == NULL) {
670 dbgsysFreeAddrInfo(addrInfo);
671 RETURN_ERROR(JDWPTRANSPORT_ERROR_INTERNAL, "listen failed: wrong address");
672 }
673
674 err = startListening(listenAddr, &serverSocketFD, actualAddress);
675
676 dbgsysFreeAddrInfo(addrInfo);
677
678 if (err != JDWPTRANSPORT_ERROR_NONE) {
679 if (serverSocketFD >= 0) {
680 dbgsysSocketClose(serverSocketFD);
681 serverSocketFD = -1;
682 }
683 return err;
684 }
685
686 return JDWPTRANSPORT_ERROR_NONE;
687}
688
689static jdwpTransportError JNICALL
690socketTransport_accept(jdwpTransportEnv* env, jlong acceptTimeout, jlong handshakeTimeout)
691{
692 int err = JDWPTRANSPORT_ERROR_NONE;
693 struct sockaddr_storage clientAddr;
694 socklen_t clientAddrLen;
695 jlong startTime = 0;
696
697 /*
698 * Use a default handshake timeout if not specified - this avoids an indefinite
699 * hang in cases where something other than a debugger connects to our port.
700 */
701 if (handshakeTimeout == 0) {
702 handshakeTimeout = 2000;
703 }
704
705 do {
706 /*
707 * If there is an accept timeout then we put the socket in non-blocking
708 * mode and poll for a connection.
709 */
710 if (acceptTimeout > 0) {
711 int rv;
712 dbgsysConfigureBlocking(serverSocketFD, JNI_FALSE);
713 startTime = dbgsysCurrentTimeMillis();
714 rv = dbgsysPoll(serverSocketFD, JNI_TRUE, JNI_FALSE, (long)acceptTimeout);
715 if (rv <= 0) {
716 /* set the last error here as could be overridden by configureBlocking */
717 if (rv == 0) {
718 setLastError(JDWPTRANSPORT_ERROR_IO_ERROR, "poll failed");
719 }
720 /* restore blocking state */
721 dbgsysConfigureBlocking(serverSocketFD, JNI_TRUE);
722 if (rv == 0) {
723 RETURN_ERROR(JDWPTRANSPORT_ERROR_TIMEOUT, "timed out waiting for connection");
724 } else {
725 return JDWPTRANSPORT_ERROR_IO_ERROR;
726 }
727 }
728 }
729
730 /*
731 * Accept the connection
732 */
733 clientAddrLen = sizeof(clientAddr);
734 socketFD = dbgsysAccept(serverSocketFD,
735 (struct sockaddr *)&clientAddr,
736 &clientAddrLen);
737 /* set the last error here as could be overridden by configureBlocking */
738 if (socketFD < 0) {
739 setLastError(JDWPTRANSPORT_ERROR_IO_ERROR, "accept failed");
740 }
741 /*
742 * Restore the blocking state - note that the accepted socket may be in
743 * blocking or non-blocking mode (platform dependent). However as there
744 * is a handshake timeout set then it will go into non-blocking mode
745 * anyway for the handshake.
746 */
747 if (acceptTimeout > 0) {
748 dbgsysConfigureBlocking(serverSocketFD, JNI_TRUE);
749 }
750 if (socketFD < 0) {
751 return JDWPTRANSPORT_ERROR_IO_ERROR;
752 }
753
754 /*
755 * version >= JDWPTRANSPORT_VERSION_1_1:
756 * Verify that peer is allowed to connect.
757 */
758 if (_peers_cnt > 0) {
759 if (!isPeerAllowed(&clientAddr)) {
760 char ebuf[64] = { 0 };
761 char addrStr[INET_ADDRSTRLEN] = { 0 };
762 int err2 = getnameinfo((struct sockaddr *)&clientAddr, clientAddrLen,
763 addrStr, sizeof(addrStr), NULL, 0,
764 NI_NUMERICHOST);
765 sprintf(ebuf, "ERROR: Peer not allowed to connect: %s\n",
766 (err2 != 0) ? "<bad address>" : addrStr);
767 dbgsysSocketClose(socketFD);
768 socketFD = -1;
769 err = JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT;
770 setLastError(err, ebuf);
771 }
772 }
773
774 if (socketFD > 0) {
775 /* handshake with the debugger */
776 err = handshake(socketFD, handshakeTimeout);
777 }
778
779 /*
780 * If the handshake fails then close the connection. If there if an accept
781 * timeout then we must adjust the timeout for the next poll.
782 */
783 if (err != JDWPTRANSPORT_ERROR_NONE) {
784 fprintf(stderr, "Debugger failed to attach: %s\n", getLastError());
785 dbgsysSocketClose(socketFD);
786 socketFD = -1;
787 if (acceptTimeout > 0) {
788 long endTime = dbgsysCurrentTimeMillis();
789 acceptTimeout -= (endTime - startTime);
790 if (acceptTimeout <= 0) {
791 setLastError(JDWPTRANSPORT_ERROR_IO_ERROR,
792 "timeout waiting for debugger to connect");
793 return JDWPTRANSPORT_ERROR_IO_ERROR;
794 }
795 }
796 }
797 } while (socketFD < 0);
798
799 return JDWPTRANSPORT_ERROR_NONE;
800}
801
802static jdwpTransportError JNICALL
803socketTransport_stopListening(jdwpTransportEnv *env)
804{
805 if (serverSocketFD < 0) {
806 RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_STATE, "connection not open");
807 }
808 if (dbgsysSocketClose(serverSocketFD) < 0) {
809 RETURN_IO_ERROR("close failed");
810 }
811 serverSocketFD = -1;
812 return JDWPTRANSPORT_ERROR_NONE;
813}
814
815/*
816 * Tries to connect to the specified addrinfo, returns connected socket.
817 * If the function fails and returned socket != -1, the socket should be closed.
818 */
819static jdwpTransportError connectToAddr(struct addrinfo *ai, jlong timeout, int *socket) {
820 int err;
821
822 *socket = dbgsysSocket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
823 if (*socket < 0) {
824 RETURN_IO_ERROR("unable to create socket");
825 }
826
827 err = setOptionsCommon(ai->ai_family, socketFD);
828 if (err) {
829 return err;
830 }
831
832 /*
833 * We don't call setReuseAddrOption() for the non-server socket
834 * case. If we start seeing EADDRINUSE due to collisions in free
835 * ports then we should retry the dbgsysConnect() a few times.
836 */
837
838 /*
839 * To do a timed connect we make the socket non-blocking
840 * and poll with a timeout;
841 */
842 if (timeout > 0) {
843 dbgsysConfigureBlocking(socketFD, JNI_FALSE);
844 }
845
846 err = dbgsysConnect(socketFD, ai->ai_addr, (socklen_t)ai->ai_addrlen);
847 if (err == DBG_EINPROGRESS && timeout > 0) {
848 err = dbgsysFinishConnect(socketFD, (long)timeout);
849
850 if (err == DBG_ETIMEOUT) {
851 dbgsysConfigureBlocking(socketFD, JNI_TRUE);
852 RETURN_ERROR(JDWPTRANSPORT_ERROR_TIMEOUT, "connect timed out");
853 }
854 }
855
856 if (err) {
857 RETURN_IO_ERROR("connect failed");
858 }
859
860 return err;
861}
862
863
864static jdwpTransportError JNICALL
865socketTransport_attach(jdwpTransportEnv* env, const char* addressString, jlong attachTimeout,
866 jlong handshakeTimeout)
867{
868 int err;
869 int pass;
870 struct addrinfo *addrInfo = NULL;
871 struct addrinfo *ai;
872
873 if (addressString == NULL || addressString[0] == '\0') {
874 RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, "address is missing");
875 }
876
877 err = parseAddress(addressString, &addrInfo);
878 if (err) {
879 return err;
880 }
881
882 /* 1st pass - preferredAddressFamily (by default IPv4), 2nd pass - the rest */
883 for (pass = 0; pass < 2 && socketFD < 0; pass++) {
884 for (ai = addrInfo; ai != NULL; ai = ai->ai_next) {
885 if ((pass == 0 && ai->ai_family == preferredAddressFamily) ||
886 (pass == 1 && ai->ai_family != preferredAddressFamily))
887 {
888 err = connectToAddr(ai, attachTimeout, &socketFD);
889 if (err == JDWPTRANSPORT_ERROR_NONE) {
890 break;
891 }
892 if (socketFD >= 0) {
893 dbgsysSocketClose(socketFD);
894 socketFD = -1;
895 }
896 }
897 }
898 }
899
900 freeaddrinfo(addrInfo);
901
902 /* err from the last connectToAddr() call */
903 if (err != 0) {
904 return err;
905 }
906
907 if (attachTimeout > 0) {
908 dbgsysConfigureBlocking(socketFD, JNI_TRUE);
909 }
910
911 err = handshake(socketFD, handshakeTimeout);
912 if (err) {
913 dbgsysSocketClose(socketFD);
914 socketFD = -1;
915 return err;
916 }
917
918 return JDWPTRANSPORT_ERROR_NONE;
919}
920
921static jboolean JNICALL
922socketTransport_isOpen(jdwpTransportEnv* env)
923{
924 if (socketFD >= 0) {
925 return JNI_TRUE;
926 } else {
927 return JNI_FALSE;
928 }
929}
930
931static jdwpTransportError JNICALL
932socketTransport_close(jdwpTransportEnv* env)
933{
934 int fd = socketFD;
935 socketFD = -1;
936 if (fd < 0) {
937 return JDWPTRANSPORT_ERROR_NONE;
938 }
939#ifdef _AIX
940 /*
941 AIX needs a workaround for I/O cancellation, see:
942 http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/close.htm
943 ...
944 The close subroutine is blocked until all subroutines which use the file
945 descriptor return to usr space. For example, when a thread is calling close
946 and another thread is calling select with the same file descriptor, the
947 close subroutine does not return until the select call returns.
948 ...
949 */
950 shutdown(fd, 2);
951#endif
952 if (dbgsysSocketClose(fd) < 0) {
953 /*
954 * close failed - it's pointless to restore socketFD here because
955 * any subsequent close will likely fail as well.
956 */
957 RETURN_IO_ERROR("close failed");
958 }
959 return JDWPTRANSPORT_ERROR_NONE;
960}
961
962static jdwpTransportError JNICALL
963socketTransport_writePacket(jdwpTransportEnv* env, const jdwpPacket *packet)
964{
965 jint len, data_len, id;
966 /*
967 * room for header and up to MAX_DATA_SIZE data bytes
968 */
969 char header[JDWP_HEADER_SIZE + MAX_DATA_SIZE];
970 jbyte *data;
971
972 /* packet can't be null */
973 if (packet == NULL) {
974 RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, "packet is NULL");
975 }
976
977 len = packet->type.cmd.len; /* includes header */
978 data_len = len - JDWP_HEADER_SIZE;
979
980 /* bad packet */
981 if (data_len < 0) {
982 RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, "invalid length");
983 }
984
985 /* prepare the header for transmission */
986 len = (jint)dbgsysHostToNetworkLong(len);
987 id = (jint)dbgsysHostToNetworkLong(packet->type.cmd.id);
988
989 memcpy(header + 0, &len, 4);
990 memcpy(header + 4, &id, 4);
991 header[8] = packet->type.cmd.flags;
992 if (packet->type.cmd.flags & JDWPTRANSPORT_FLAGS_REPLY) {
993 jshort errorCode =
994 dbgsysHostToNetworkShort(packet->type.reply.errorCode);
995 memcpy(header + 9, &errorCode, 2);
996 } else {
997 header[9] = packet->type.cmd.cmdSet;
998 header[10] = packet->type.cmd.cmd;
999 }
1000
1001 data = packet->type.cmd.data;
1002 /* Do one send for short packets, two for longer ones */
1003 if (data_len <= MAX_DATA_SIZE) {
1004 memcpy(header + JDWP_HEADER_SIZE, data, data_len);
1005 if (send_fully(socketFD, (char *)&header, JDWP_HEADER_SIZE + data_len) !=
1006 JDWP_HEADER_SIZE + data_len) {
1007 RETURN_IO_ERROR("send failed");
1008 }
1009 } else {
1010 memcpy(header + JDWP_HEADER_SIZE, data, MAX_DATA_SIZE);
1011 if (send_fully(socketFD, (char *)&header, JDWP_HEADER_SIZE + MAX_DATA_SIZE) !=
1012 JDWP_HEADER_SIZE + MAX_DATA_SIZE) {
1013 RETURN_IO_ERROR("send failed");
1014 }
1015 /* Send the remaining data bytes right out of the data area. */
1016 if (send_fully(socketFD, (char *)data + MAX_DATA_SIZE,
1017 data_len - MAX_DATA_SIZE) != data_len - MAX_DATA_SIZE) {
1018 RETURN_IO_ERROR("send failed");
1019 }
1020 }
1021
1022 return JDWPTRANSPORT_ERROR_NONE;
1023}
1024
1025static jint
1026recv_fully(int f, char *buf, int len)
1027{
1028 int nbytes = 0;
1029 while (nbytes < len) {
1030 int res = dbgsysRecv(f, buf + nbytes, len - nbytes, 0);
1031 if (res < 0) {
1032 return res;
1033 } else if (res == 0) {
1034 break; /* eof, return nbytes which is less than len */
1035 }
1036 nbytes += res;
1037 }
1038 return nbytes;
1039}
1040
1041jint
1042send_fully(int f, char *buf, int len)
1043{
1044 int nbytes = 0;
1045 while (nbytes < len) {
1046 int res = dbgsysSend(f, buf + nbytes, len - nbytes, 0);
1047 if (res < 0) {
1048 return res;
1049 } else if (res == 0) {
1050 break; /* eof, return nbytes which is less than len */
1051 }
1052 nbytes += res;
1053 }
1054 return nbytes;
1055}
1056
1057static jdwpTransportError JNICALL
1058socketTransport_readPacket(jdwpTransportEnv* env, jdwpPacket* packet) {
1059 jint length, data_len;
1060 jint n;
1061
1062 /* packet can't be null */
1063 if (packet == NULL) {
1064 RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, "packet is null");
1065 }
1066
1067 /* read the length field */
1068 n = recv_fully(socketFD, (char *)&length, sizeof(jint));
1069
1070 /* check for EOF */
1071 if (n == 0) {
1072 packet->type.cmd.len = 0;
1073 return JDWPTRANSPORT_ERROR_NONE;
1074 }
1075 if (n != sizeof(jint)) {
1076 RETURN_RECV_ERROR(n);
1077 }
1078
1079 length = (jint)dbgsysNetworkToHostLong(length);
1080 packet->type.cmd.len = length;
1081
1082
1083 n = recv_fully(socketFD,(char *)&(packet->type.cmd.id), sizeof(jint));
1084 if (n < (int)sizeof(jint)) {
1085 RETURN_RECV_ERROR(n);
1086 }
1087
1088 packet->type.cmd.id = (jint)dbgsysNetworkToHostLong(packet->type.cmd.id);
1089
1090 n = recv_fully(socketFD,(char *)&(packet->type.cmd.flags), sizeof(jbyte));
1091 if (n < (int)sizeof(jbyte)) {
1092 RETURN_RECV_ERROR(n);
1093 }
1094
1095 if (packet->type.cmd.flags & JDWPTRANSPORT_FLAGS_REPLY) {
1096 n = recv_fully(socketFD,(char *)&(packet->type.reply.errorCode), sizeof(jbyte));
1097 if (n < (int)sizeof(jshort)) {
1098 RETURN_RECV_ERROR(n);
1099 }
1100
1101 /* FIXME - should the error be converted to host order?? */
1102
1103
1104 } else {
1105 n = recv_fully(socketFD,(char *)&(packet->type.cmd.cmdSet), sizeof(jbyte));
1106 if (n < (int)sizeof(jbyte)) {
1107 RETURN_RECV_ERROR(n);
1108 }
1109
1110 n = recv_fully(socketFD,(char *)&(packet->type.cmd.cmd), sizeof(jbyte));
1111 if (n < (int)sizeof(jbyte)) {
1112 RETURN_RECV_ERROR(n);
1113 }
1114 }
1115
1116 data_len = length - ((sizeof(jint) * 2) + (sizeof(jbyte) * 3));
1117
1118 if (data_len < 0) {
1119 setLastError(0, "Badly formed packet received - invalid length");
1120 return JDWPTRANSPORT_ERROR_IO_ERROR;
1121 } else if (data_len == 0) {
1122 packet->type.cmd.data = NULL;
1123 } else {
1124 packet->type.cmd.data= (*callback->alloc)(data_len);
1125
1126 if (packet->type.cmd.data == NULL) {
1127 RETURN_ERROR(JDWPTRANSPORT_ERROR_OUT_OF_MEMORY, "out of memory");
1128 }
1129
1130 n = recv_fully(socketFD,(char *)packet->type.cmd.data, data_len);
1131 if (n < data_len) {
1132 (*callback->free)(packet->type.cmd.data);
1133 RETURN_RECV_ERROR(n);
1134 }
1135 }
1136
1137 return JDWPTRANSPORT_ERROR_NONE;
1138}
1139
1140static jdwpTransportError JNICALL
1141socketTransport_getLastError(jdwpTransportEnv* env, char** msgP) {
1142 char *msg = (char *)dbgsysTlsGet(tlsIndex);
1143 if (msg == NULL) {
1144 return JDWPTRANSPORT_ERROR_MSG_NOT_AVAILABLE;
1145 }
1146 *msgP = (*callback->alloc)((int)strlen(msg)+1);
1147 if (*msgP == NULL) {
1148 return JDWPTRANSPORT_ERROR_OUT_OF_MEMORY;
1149 }
1150 strcpy(*msgP, msg);
1151 return JDWPTRANSPORT_ERROR_NONE;
1152}
1153
1154static jdwpTransportError JNICALL
1155socketTransport_setConfiguration(jdwpTransportEnv* env, jdwpTransportConfiguration* cfg) {
1156 const char* allowed_peers = NULL;
1157
1158 if (cfg == NULL) {
1159 RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT,
1160 "NULL pointer to transport configuration is invalid");
1161 }
1162 allowed_peers = cfg->allowed_peers;
1163 _peers_cnt = 0;
1164 if (allowed_peers != NULL) {
1165 size_t len = strlen(allowed_peers);
1166 if (len == 0) { /* Impossible: parseOptions() would reject it */
1167 fprintf(stderr, "Error in allow option: '%s'\n", allowed_peers);
1168 RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT,
1169 "allow option should not be empty");
1170 } else if (*allowed_peers == '*') {
1171 if (len != 1) {
1172 fprintf(stderr, "Error in allow option: '%s'\n", allowed_peers);
1173 RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT,
1174 "allow option '*' cannot be expanded");
1175 }
1176 } else {
1177 int err = parseAllowedPeers(allowed_peers, len);
1178 if (err != JDWPTRANSPORT_ERROR_NONE) {
1179 return err;
1180 }
1181 }
1182 }
1183 return JDWPTRANSPORT_ERROR_NONE;
1184}
1185
1186/*
1187 * Reads boolean system value, sets *result to
1188 * - trueValue if the property is "true";
1189 * - falseValue if the property is "false".
1190 * Doesn't change *result if the property is not set or failed to read.
1191 */
1192static int readBooleanSysProp(int *result, int trueValue, int falseValue,
1193 JNIEnv* jniEnv, jclass sysClass, jmethodID getPropMethod, const char *propName)
1194{
1195 jstring value;
1196 jstring name = (*jniEnv)->NewStringUTF(jniEnv, propName);
1197
1198 if (name == NULL) {
1199 return JNI_ERR;
1200 }
1201 value = (jstring)(*jniEnv)->CallStaticObjectMethod(jniEnv, sysClass, getPropMethod, name);
1202 if ((*jniEnv)->ExceptionCheck(jniEnv)) {
1203 return JNI_ERR;
1204 }
1205 if (value != NULL) {
1206 const char *theValue = (*jniEnv)->GetStringUTFChars(jniEnv, value, NULL);
1207 if (theValue == NULL) {
1208 return JNI_ERR;
1209 }
1210 if (strcmp(theValue, "true") == 0) {
1211 *result = trueValue;
1212 } else if (strcmp(theValue, "false") == 0) {
1213 *result = falseValue;
1214 }
1215 (*jniEnv)->ReleaseStringUTFChars(jniEnv, value, theValue);
1216 }
1217 return JNI_OK;
1218}
1219
1220JNIEXPORT jint JNICALL
1221jdwpTransport_OnLoad(JavaVM *vm, jdwpTransportCallback* cbTablePtr,
1222 jint version, jdwpTransportEnv** env)
1223{
1224 JNIEnv* jniEnv = NULL;
1225
1226 if (version < JDWPTRANSPORT_VERSION_1_0 ||
1227 version > JDWPTRANSPORT_VERSION_1_1) {
1228 return JNI_EVERSION;
1229 }
1230 if (initialized) {
1231 /*
1232 * This library doesn't support multiple environments (yet)
1233 */
1234 return JNI_EEXIST;
1235 }
1236 initialized = JNI_TRUE;
1237 jvm = vm;
1238 callback = cbTablePtr;
1239
1240 /* initialize interface table */
1241 interface.GetCapabilities = &socketTransport_getCapabilities;
1242 interface.Attach = &socketTransport_attach;
1243 interface.StartListening = &socketTransport_startListening;
1244 interface.StopListening = &socketTransport_stopListening;
1245 interface.Accept = &socketTransport_accept;
1246 interface.IsOpen = &socketTransport_isOpen;
1247 interface.Close = &socketTransport_close;
1248 interface.ReadPacket = &socketTransport_readPacket;
1249 interface.WritePacket = &socketTransport_writePacket;
1250 interface.GetLastError = &socketTransport_getLastError;
1251 if (version >= JDWPTRANSPORT_VERSION_1_1) {
1252 interface.SetTransportConfiguration = &socketTransport_setConfiguration;
1253 }
1254 *env = &single_env;
1255
1256 /* initialized TLS */
1257 tlsIndex = dbgsysTlsAlloc();
1258
1259 // retrieve network-related system properties
1260 do {
1261 jclass sysClass;
1262 jmethodID getPropMethod;
1263 if ((*vm)->GetEnv(vm, (void **)&jniEnv, JNI_VERSION_9) != JNI_OK) {
1264 break;
1265 }
1266 sysClass = (*jniEnv)->FindClass(jniEnv, "java/lang/System");
1267 if (sysClass == NULL) {
1268 break;
1269 }
1270 getPropMethod = (*jniEnv)->GetStaticMethodID(jniEnv, sysClass,
1271 "getProperty", "(Ljava/lang/String;)Ljava/lang/String;");
1272 if (getPropMethod == NULL) {
1273 break;
1274 }
1275 readBooleanSysProp(&allowOnlyIPv4, 1, 0,
1276 jniEnv, sysClass, getPropMethod, "java.net.preferIPv4Stack");
1277 readBooleanSysProp(&preferredAddressFamily, AF_INET6, AF_INET,
1278 jniEnv, sysClass, getPropMethod, "java.net.preferIPv6Addresses");
1279 } while (0);
1280
1281 if (jniEnv != NULL && (*jniEnv)->ExceptionCheck(jniEnv)) {
1282 (*jniEnv)->ExceptionClear(jniEnv);
1283 }
1284
1285
1286 return JNI_OK;
1287}
1288