1 /* 2 * Copyright (c) 1998, 2018, 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 "jdwpTransport.h" 32 #include "sysSocket.h" 33 34 #ifdef _WIN32 35 #include <winsock2.h> 36 #include <ws2tcpip.h> 37 #else 38 #include <arpa/inet.h> 39 #include <sys/socket.h> 40 #endif 41 42 /* 43 * The Socket Transport Library. 44 * 45 * This module is an implementation of the Java Debug Wire Protocol Transport 46 * Service Provider Interface - see src/share/javavm/export/jdwpTransport.h. 47 */ 48 49 static int serverSocketFD; 50 static int socketFD = -1; 51 static jdwpTransportCallback *callback; 52 static JavaVM *jvm; 53 static int tlsIndex; 54 static jboolean initialized; 55 static struct jdwpTransportNativeInterface_ interface; 56 static jdwpTransportEnv single_env = (jdwpTransportEnv)&interface; 57 58 #define RETURN_ERROR(err, msg) \ 59 if (1==1) { \ 60 setLastError(err, msg); \ 61 return err; \ 62 } 63 64 #define RETURN_IO_ERROR(msg) RETURN_ERROR(JDWPTRANSPORT_ERROR_IO_ERROR, msg); 65 66 #define RETURN_RECV_ERROR(n) \ 67 if (n == 0) { \ 68 RETURN_ERROR(JDWPTRANSPORT_ERROR_IO_ERROR, "premature EOF"); \ 69 } else { \ 70 RETURN_IO_ERROR("recv error"); \ 71 } 72 73 #define MAX_DATA_SIZE 1000 74 75 static jint recv_fully(int, char *, int); 76 static jint send_fully(int, char *, int); 77 78 /* version >= JDWPTRANSPORT_VERSION_1_1 */ 79 typedef struct { 80 uint32_t subnet; 81 uint32_t netmask; 82 } AllowedPeerInfo; 83 84 #define STR(x) #x 85 #define MAX_PEER_ENTRIES 32 86 #define MAX_PEERS_STR STR(MAX_PEER_ENTRIES) 87 static AllowedPeerInfo _peers[MAX_PEER_ENTRIES]; 88 static int _peers_cnt = 0; 89 90 91 /* 92 * Record the last error for this thread. 93 */ 94 static void 95 setLastError(jdwpTransportError err, char *newmsg) { 96 char buf[255]; 97 char *msg; 98 99 /* get any I/O first in case any system calls override errno */ 100 if (err == JDWPTRANSPORT_ERROR_IO_ERROR) { 101 dbgsysGetLastIOError(buf, sizeof(buf)); 102 } 103 104 msg = (char *)dbgsysTlsGet(tlsIndex); 105 if (msg != NULL) { 106 (*callback->free)(msg); 107 } 108 109 if (err == JDWPTRANSPORT_ERROR_IO_ERROR) { 110 char *join_str = ": "; 111 int msg_len = (int)strlen(newmsg) + (int)strlen(join_str) + 112 (int)strlen(buf) + 3; 113 msg = (*callback->alloc)(msg_len); 114 if (msg != NULL) { 115 strcpy(msg, newmsg); 116 strcat(msg, join_str); 117 strcat(msg, buf); 118 } 119 } else { 120 msg = (*callback->alloc)((int)strlen(newmsg)+1); 121 if (msg != NULL) { 122 strcpy(msg, newmsg); 123 } 124 } 125 126 dbgsysTlsPut(tlsIndex, msg); 127 } 128 129 /* 130 * Return the last error for this thread (may be NULL) 131 */ 132 static char* 133 getLastError() { 134 return (char *)dbgsysTlsGet(tlsIndex); 135 } 136 137 /* Set options common to client and server sides */ 138 static jdwpTransportError 139 setOptionsCommon(int fd) 140 { 141 jvalue dontcare; 142 int err; 143 144 dontcare.i = 0; /* keep compiler happy */ 145 146 err = dbgsysSetSocketOption(fd, TCP_NODELAY, JNI_TRUE, dontcare); 147 if (err < 0) { 148 RETURN_IO_ERROR("setsockopt TCPNODELAY failed"); 149 } 150 151 return JDWPTRANSPORT_ERROR_NONE; 152 } 153 154 /* Set the SO_REUSEADDR option */ 155 static jdwpTransportError 156 setReuseAddrOption(int fd) 157 { 158 jvalue dontcare; 159 int err; 160 161 dontcare.i = 0; /* keep compiler happy */ 162 163 err = dbgsysSetSocketOption(fd, SO_REUSEADDR, JNI_TRUE, dontcare); 164 if (err < 0) { 165 RETURN_IO_ERROR("setsockopt SO_REUSEADDR failed"); 166 } 167 168 return JDWPTRANSPORT_ERROR_NONE; 169 } 170 171 static jdwpTransportError 172 handshake(int fd, jlong timeout) { 173 const char *hello = "JDWP-Handshake"; 174 char b[16]; 175 int rv, helloLen, received; 176 177 if (timeout > 0) { 178 dbgsysConfigureBlocking(fd, JNI_FALSE); 179 } 180 helloLen = (int)strlen(hello); 181 received = 0; 182 while (received < helloLen) { 183 int n; 184 char *buf; 185 if (timeout > 0) { 186 rv = dbgsysPoll(fd, JNI_TRUE, JNI_FALSE, (long)timeout); 187 if (rv <= 0) { 188 setLastError(0, "timeout during handshake"); 189 return JDWPTRANSPORT_ERROR_IO_ERROR; 190 } 191 } 192 buf = b; 193 buf += received; 194 n = recv_fully(fd, buf, helloLen-received); 195 if (n == 0) { 196 setLastError(0, "handshake failed - connection prematurally closed"); 197 return JDWPTRANSPORT_ERROR_IO_ERROR; 198 } 199 if (n < 0) { 200 RETURN_IO_ERROR("recv failed during handshake"); 201 } 202 received += n; 203 } 204 if (timeout > 0) { 205 dbgsysConfigureBlocking(fd, JNI_TRUE); 206 } 207 if (strncmp(b, hello, received) != 0) { 208 char msg[80+2*16]; 209 b[received] = '\0'; 210 /* 211 * We should really use snprintf here but it's not available on Windows. 212 * We can't use jio_snprintf without linking the transport against the VM. 213 */ 214 sprintf(msg, "handshake failed - received >%s< - expected >%s<", b, hello); 215 setLastError(0, msg); 216 return JDWPTRANSPORT_ERROR_IO_ERROR; 217 } 218 219 if (send_fully(fd, (char*)hello, helloLen) != helloLen) { 220 RETURN_IO_ERROR("send failed during handshake"); 221 } 222 return JDWPTRANSPORT_ERROR_NONE; 223 } 224 225 static uint32_t 226 getLocalHostAddress() { 227 // Simple routine to guess localhost address. 228 // it looks up "localhost" and returns 127.0.0.1 if lookup 229 // fails. 230 struct addrinfo hints, *res = NULL; 231 uint32_t addr; 232 int err; 233 234 // Use portable way to initialize the structure 235 memset((void *)&hints, 0, sizeof(hints)); 236 hints.ai_family = AF_INET; 237 238 err = getaddrinfo("localhost", NULL, &hints, &res); 239 if (err < 0 || res == NULL) { 240 return dbgsysHostToNetworkLong(INADDR_LOOPBACK); 241 } 242 243 // getaddrinfo might return more than one address 244 // but we are using first one only 245 addr = ((struct sockaddr_in *)(res->ai_addr))->sin_addr.s_addr; 246 freeaddrinfo(res); 247 return addr; 248 } 249 250 static int 251 getPortNumber(const char *s_port) { 252 u_long n; 253 char *eptr; 254 255 if (*s_port == 0) { 256 // bad address - colon with no port number in parameters 257 return -1; 258 } 259 260 n = strtoul(s_port, &eptr, 10); 261 if (eptr != s_port + strlen(s_port)) { 262 // incomplete conversion - port number contains non-digit 263 return -1; 264 } 265 266 if (n > (u_short) -1) { 267 // check that value supplied by user is less than 268 // maximum possible u_short value (65535) and 269 // will not be truncated later. 270 return -1; 271 } 272 273 return n; 274 } 275 276 static jdwpTransportError 277 parseAddress(const char *address, struct sockaddr_in *sa) { 278 char *colon; 279 int port; 280 281 memset((void *)sa, 0, sizeof(struct sockaddr_in)); 282 sa->sin_family = AF_INET; 283 284 /* check for host:port or port */ 285 colon = strchr(address, ':'); 286 port = getPortNumber((colon == NULL) ? address : colon +1); 287 if (port < 0) { 288 RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, "invalid port number specified"); 289 } 290 sa->sin_port = dbgsysHostToNetworkShort((u_short)port); 291 292 if (colon == NULL) { 293 // bind to localhost only if no address specified 294 sa->sin_addr.s_addr = getLocalHostAddress(); 295 } else if (strncmp(address, "localhost:", 10) == 0) { 296 // optimize for common case 297 sa->sin_addr.s_addr = getLocalHostAddress(); 298 } else if (*address == '*' && *(address+1) == ':') { 299 // we are explicitly asked to bind server to all available IP addresses 300 // has no meaning for client. 301 sa->sin_addr.s_addr = dbgsysHostToNetworkLong(INADDR_ANY); 302 } else { 303 char *buf; 304 char *hostname; 305 uint32_t addr; 306 int ai; 307 buf = (*callback->alloc)((int)strlen(address) + 1); 308 if (buf == NULL) { 309 RETURN_ERROR(JDWPTRANSPORT_ERROR_OUT_OF_MEMORY, "out of memory"); 310 } 311 strcpy(buf, address); 312 buf[colon - address] = '\0'; 313 hostname = buf; 314 315 /* 316 * First see if the host is a literal IP address. 317 * If not then try to resolve it. 318 */ 319 addr = dbgsysInetAddr(hostname); 320 if (addr == 0xffffffff) { 321 struct addrinfo hints; 322 struct addrinfo *results = NULL; 323 memset (&hints, 0, sizeof(hints)); 324 hints.ai_family = AF_INET; 325 hints.ai_socktype = SOCK_STREAM; 326 hints.ai_protocol = IPPROTO_TCP; 327 328 ai = dbgsysGetAddrInfo(hostname, NULL, &hints, &results); 329 330 if (ai != 0) { 331 /* don't use RETURN_IO_ERROR as unknown host is normal */ 332 setLastError(0, "getaddrinfo: unknown host"); 333 (*callback->free)(buf); 334 return JDWPTRANSPORT_ERROR_IO_ERROR; 335 } 336 337 /* lookup was successful */ 338 sa->sin_addr = ((struct sockaddr_in *)results->ai_addr)->sin_addr; 339 freeaddrinfo(results); 340 } else { 341 sa->sin_addr.s_addr = addr; 342 } 343 344 (*callback->free)(buf); 345 } 346 347 return JDWPTRANSPORT_ERROR_NONE; 348 } 349 350 static const char * 351 ip_s2u(const char *instr, uint32_t *ip) { 352 // Convert string representation of ip to integer 353 // in network byte order (big-endian) 354 char t[4] = { 0, 0, 0, 0 }; 355 const char *s = instr; 356 int i = 0; 357 358 while (1) { 359 if (*s == '.') { 360 ++i; 361 ++s; 362 continue; 363 } 364 if (*s == 0 || *s == '+' || *s == '/') { 365 break; 366 } 367 if (*s < '0' || *s > '9') { 368 return instr; 369 } 370 t[i] = (t[i] * 10) + (*s - '0'); 371 ++s; 372 } 373 374 *ip = *(uint32_t*)(t); 375 return s; 376 } 377 378 static const char * 379 mask_s2u(const char *instr, uint32_t *mask) { 380 // Convert the number of bits to a netmask 381 // in network byte order (big-endian) 382 unsigned char m = 0; 383 const char *s = instr; 384 385 while (1) { 386 if (*s == 0 || *s == '+') { 387 break; 388 } 389 if (*s < '0' || *s > '9') { 390 return instr; 391 } 392 m = (m * 10) + (*s - '0'); 393 ++s; 394 } 395 396 if (m == 0 || m > 32) { 397 // Drop invalid input 398 return instr; 399 } 400 401 *mask = htonl((uint32_t)(~0) << (32 - m)); 402 return s; 403 } 404 405 static int 406 ip_in_subnet(uint32_t subnet, uint32_t mask, uint32_t ipaddr) { 407 return (ipaddr & mask) == subnet; 408 } 409 410 static jdwpTransportError 411 parseAllowedPeers(const char *allowed_peers) { 412 // Build a list of allowed peers from char string 413 // of format 192.168.0.10+192.168.0.0/24 414 const char *s = NULL; 415 const char *p = allowed_peers; 416 uint32_t ip = 0; 417 uint32_t mask = 0xFFFFFFFF; 418 419 while (1) { 420 s = ip_s2u(p, &ip); 421 if (s == p) { 422 _peers_cnt = 0; 423 fprintf(stderr, "Error in allow option: '%s'\n", s); 424 RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, 425 "invalid IP address in allow option"); 426 } 427 428 if (*s == '/') { 429 // netmask specified 430 s = mask_s2u(s + 1, &mask); 431 if (*(s - 1) == '/') { 432 // Input is not consumed, something bad happened 433 _peers_cnt = 0; 434 fprintf(stderr, "Error in allow option: '%s'\n", s); 435 RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, 436 "invalid netmask in allow option"); 437 } 438 } else { 439 // reset netmask 440 mask = 0xFFFFFFFF; 441 } 442 443 if (*s == '+' || *s == 0) { 444 if (_peers_cnt >= MAX_PEER_ENTRIES) { 445 fprintf(stderr, "Error in allow option: '%s'\n", allowed_peers); 446 RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, 447 "exceeded max number of allowed peers: " MAX_PEERS_STR); 448 } 449 _peers[_peers_cnt].subnet = ip; 450 _peers[_peers_cnt].netmask = mask; 451 _peers_cnt++; 452 if (*s == 0) { 453 // end of options 454 break; 455 } 456 // advance to next IP block 457 p = s + 1; 458 } 459 } 460 return JDWPTRANSPORT_ERROR_NONE; 461 } 462 463 static int 464 isPeerAllowed(struct sockaddr_in *peer) { 465 int i; 466 for (i = 0; i < _peers_cnt; ++i) { 467 int peer_ip = peer->sin_addr.s_addr; 468 if (ip_in_subnet(_peers[i].subnet, _peers[i].netmask, peer_ip)) { 469 return 1; 470 } 471 } 472 473 return 0; 474 } 475 476 static jdwpTransportError JNICALL 477 socketTransport_getCapabilities(jdwpTransportEnv* env, 478 JDWPTransportCapabilities* capabilitiesPtr) 479 { 480 JDWPTransportCapabilities result; 481 482 memset(&result, 0, sizeof(result)); 483 result.can_timeout_attach = JNI_TRUE; 484 result.can_timeout_accept = JNI_TRUE; 485 result.can_timeout_handshake = JNI_TRUE; 486 487 *capabilitiesPtr = result; 488 489 return JDWPTRANSPORT_ERROR_NONE; 490 } 491 492 493 static jdwpTransportError JNICALL 494 socketTransport_startListening(jdwpTransportEnv* env, const char* address, 495 char** actualAddress) 496 { 497 struct sockaddr_in sa; 498 int err; 499 500 memset((void *)&sa,0,sizeof(struct sockaddr_in)); 501 sa.sin_family = AF_INET; 502 503 /* no address provided */ 504 if ((address == NULL) || (address[0] == '\0')) { 505 address = "0"; 506 } 507 508 err = parseAddress(address, &sa); 509 if (err != JDWPTRANSPORT_ERROR_NONE) { 510 return err; 511 } 512 513 serverSocketFD = dbgsysSocket(AF_INET, SOCK_STREAM, 0); 514 if (serverSocketFD < 0) { 515 RETURN_IO_ERROR("socket creation failed"); 516 } 517 518 err = setOptionsCommon(serverSocketFD); 519 if (err) { 520 return err; 521 } 522 if (sa.sin_port != 0) { 523 /* 524 * Only need SO_REUSEADDR if we're using a fixed port. If we 525 * start seeing EADDRINUSE due to collisions in free ports 526 * then we should retry the dbgsysBind() a few times. 527 */ 528 err = setReuseAddrOption(serverSocketFD); 529 if (err) { 530 return err; 531 } 532 } 533 534 err = dbgsysBind(serverSocketFD, (struct sockaddr *)&sa, sizeof(sa)); 535 if (err < 0) { 536 RETURN_IO_ERROR("bind failed"); 537 } 538 539 err = dbgsysListen(serverSocketFD, 1); 540 if (err < 0) { 541 RETURN_IO_ERROR("listen failed"); 542 } 543 544 { 545 char buf[20]; 546 socklen_t len = sizeof(sa); 547 jint portNum; 548 err = dbgsysGetSocketName(serverSocketFD, 549 (struct sockaddr *)&sa, &len); 550 portNum = dbgsysNetworkToHostShort(sa.sin_port); 551 sprintf(buf, "%d", portNum); 552 *actualAddress = (*callback->alloc)((int)strlen(buf) + 1); 553 if (*actualAddress == NULL) { 554 RETURN_ERROR(JDWPTRANSPORT_ERROR_OUT_OF_MEMORY, "out of memory"); 555 } else { 556 strcpy(*actualAddress, buf); 557 } 558 } 559 560 return JDWPTRANSPORT_ERROR_NONE; 561 } 562 563 static jdwpTransportError JNICALL 564 socketTransport_accept(jdwpTransportEnv* env, jlong acceptTimeout, jlong handshakeTimeout) 565 { 566 socklen_t socketLen; 567 int err = JDWPTRANSPORT_ERROR_NONE; 568 struct sockaddr_in socket; 569 jlong startTime = (jlong)0; 570 571 /* 572 * Use a default handshake timeout if not specified - this avoids an indefinite 573 * hang in cases where something other than a debugger connects to our port. 574 */ 575 if (handshakeTimeout == 0) { 576 handshakeTimeout = 2000; 577 } 578 579 do { 580 /* 581 * If there is an accept timeout then we put the socket in non-blocking 582 * mode and poll for a connection. 583 */ 584 if (acceptTimeout > 0) { 585 int rv; 586 dbgsysConfigureBlocking(serverSocketFD, JNI_FALSE); 587 startTime = dbgsysCurrentTimeMillis(); 588 rv = dbgsysPoll(serverSocketFD, JNI_TRUE, JNI_FALSE, (long)acceptTimeout); 589 if (rv <= 0) { 590 /* set the last error here as could be overridden by configureBlocking */ 591 if (rv == 0) { 592 setLastError(JDWPTRANSPORT_ERROR_IO_ERROR, "poll failed"); 593 } 594 /* restore blocking state */ 595 dbgsysConfigureBlocking(serverSocketFD, JNI_TRUE); 596 if (rv == 0) { 597 RETURN_ERROR(JDWPTRANSPORT_ERROR_TIMEOUT, "timed out waiting for connection"); 598 } else { 599 return JDWPTRANSPORT_ERROR_IO_ERROR; 600 } 601 } 602 } 603 604 /* 605 * Accept the connection 606 */ 607 memset((void *)&socket,0,sizeof(struct sockaddr_in)); 608 socketLen = sizeof(socket); 609 socketFD = dbgsysAccept(serverSocketFD, 610 (struct sockaddr *)&socket, 611 &socketLen); 612 /* set the last error here as could be overridden by configureBlocking */ 613 if (socketFD < 0) { 614 setLastError(JDWPTRANSPORT_ERROR_IO_ERROR, "accept failed"); 615 } 616 /* 617 * Restore the blocking state - note that the accepted socket may be in 618 * blocking or non-blocking mode (platform dependent). However as there 619 * is a handshake timeout set then it will go into non-blocking mode 620 * anyway for the handshake. 621 */ 622 if (acceptTimeout > 0) { 623 dbgsysConfigureBlocking(serverSocketFD, JNI_TRUE); 624 } 625 if (socketFD < 0) { 626 return JDWPTRANSPORT_ERROR_IO_ERROR; 627 } 628 629 /* 630 * version >= JDWPTRANSPORT_VERSION_1_1: 631 * Verify that peer is allowed to connect. 632 */ 633 if (_peers_cnt > 0) { 634 if (!isPeerAllowed(&socket)) { 635 char ebuf[64] = { 0 }; 636 char buf[INET_ADDRSTRLEN] = { 0 }; 637 const char* addr_str = inet_ntop(AF_INET, &(socket.sin_addr), buf, INET_ADDRSTRLEN); 638 sprintf(ebuf, "ERROR: Peer not allowed to connect: %s\n", 639 (addr_str == NULL) ? "<bad address>" : addr_str); 640 dbgsysSocketClose(socketFD); 641 socketFD = -1; 642 err = JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT; 643 setLastError(err, ebuf); 644 } 645 } 646 647 if (socketFD > 0) { 648 /* handshake with the debugger */ 649 err = handshake(socketFD, handshakeTimeout); 650 } 651 652 /* 653 * If the handshake fails then close the connection. If there if an accept 654 * timeout then we must adjust the timeout for the next poll. 655 */ 656 if (err != JDWPTRANSPORT_ERROR_NONE) { 657 fprintf(stderr, "Debugger failed to attach: %s\n", getLastError()); 658 dbgsysSocketClose(socketFD); 659 socketFD = -1; 660 if (acceptTimeout > 0) { 661 long endTime = dbgsysCurrentTimeMillis(); 662 acceptTimeout -= (endTime - startTime); 663 if (acceptTimeout <= 0) { 664 setLastError(JDWPTRANSPORT_ERROR_IO_ERROR, 665 "timeout waiting for debugger to connect"); 666 return JDWPTRANSPORT_ERROR_IO_ERROR; 667 } 668 } 669 } 670 } while (socketFD < 0); 671 672 return JDWPTRANSPORT_ERROR_NONE; 673 } 674 675 static jdwpTransportError JNICALL 676 socketTransport_stopListening(jdwpTransportEnv *env) 677 { 678 if (serverSocketFD < 0) { 679 RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_STATE, "connection not open"); 680 } 681 if (dbgsysSocketClose(serverSocketFD) < 0) { 682 RETURN_IO_ERROR("close failed"); 683 } 684 serverSocketFD = -1; 685 return JDWPTRANSPORT_ERROR_NONE; 686 } 687 688 static jdwpTransportError JNICALL 689 socketTransport_attach(jdwpTransportEnv* env, const char* addressString, jlong attachTimeout, 690 jlong handshakeTimeout) 691 { 692 struct sockaddr_in sa; 693 int err; 694 695 if (addressString == NULL || addressString[0] == '\0') { 696 RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, "address is missing"); 697 } 698 699 err = parseAddress(addressString, &sa); 700 if (err != JDWPTRANSPORT_ERROR_NONE) { 701 return err; 702 } 703 704 socketFD = dbgsysSocket(AF_INET, SOCK_STREAM, 0); 705 if (socketFD < 0) { 706 RETURN_IO_ERROR("unable to create socket"); 707 } 708 709 err = setOptionsCommon(socketFD); 710 if (err) { 711 return err; 712 } 713 714 /* 715 * We don't call setReuseAddrOption() for the non-server socket 716 * case. If we start seeing EADDRINUSE due to collisions in free 717 * ports then we should retry the dbgsysConnect() a few times. 718 */ 719 720 /* 721 * To do a timed connect we make the socket non-blocking 722 * and poll with a timeout; 723 */ 724 if (attachTimeout > 0) { 725 dbgsysConfigureBlocking(socketFD, JNI_FALSE); 726 } 727 728 err = dbgsysConnect(socketFD, (struct sockaddr *)&sa, sizeof(sa)); 729 if (err == DBG_EINPROGRESS && attachTimeout > 0) { 730 err = dbgsysFinishConnect(socketFD, (long)attachTimeout); 731 732 if (err == DBG_ETIMEOUT) { 733 dbgsysConfigureBlocking(socketFD, JNI_TRUE); 734 RETURN_ERROR(JDWPTRANSPORT_ERROR_TIMEOUT, "connect timed out"); 735 } 736 } 737 738 if (err < 0) { 739 RETURN_IO_ERROR("connect failed"); 740 } 741 742 if (attachTimeout > 0) { 743 dbgsysConfigureBlocking(socketFD, JNI_TRUE); 744 } 745 746 err = handshake(socketFD, handshakeTimeout); 747 if (err) { 748 dbgsysSocketClose(socketFD); 749 socketFD = -1; 750 return err; 751 } 752 753 return JDWPTRANSPORT_ERROR_NONE; 754 } 755 756 static jboolean JNICALL 757 socketTransport_isOpen(jdwpTransportEnv* env) 758 { 759 if (socketFD >= 0) { 760 return JNI_TRUE; 761 } else { 762 return JNI_FALSE; 763 } 764 } 765 766 static jdwpTransportError JNICALL 767 socketTransport_close(jdwpTransportEnv* env) 768 { 769 int fd = socketFD; 770 socketFD = -1; 771 if (fd < 0) { 772 return JDWPTRANSPORT_ERROR_NONE; 773 } 774 #ifdef _AIX 775 /* 776 AIX needs a workaround for I/O cancellation, see: 777 http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/close.htm 778 ... 779 The close subroutine is blocked until all subroutines which use the file 780 descriptor return to usr space. For example, when a thread is calling close 781 and another thread is calling select with the same file descriptor, the 782 close subroutine does not return until the select call returns. 783 ... 784 */ 785 shutdown(fd, 2); 786 #endif 787 if (dbgsysSocketClose(fd) < 0) { 788 /* 789 * close failed - it's pointless to restore socketFD here because 790 * any subsequent close will likely fail as well. 791 */ 792 RETURN_IO_ERROR("close failed"); 793 } 794 return JDWPTRANSPORT_ERROR_NONE; 795 } 796 797 static jdwpTransportError JNICALL 798 socketTransport_writePacket(jdwpTransportEnv* env, const jdwpPacket *packet) 799 { 800 jint len, data_len, id; 801 /* 802 * room for header and up to MAX_DATA_SIZE data bytes 803 */ 804 char header[JDWP_HEADER_SIZE + MAX_DATA_SIZE]; 805 jbyte *data; 806 807 /* packet can't be null */ 808 if (packet == NULL) { 809 RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, "packet is NULL"); 810 } 811 812 len = packet->type.cmd.len; /* includes header */ 813 data_len = len - JDWP_HEADER_SIZE; 814 815 /* bad packet */ 816 if (data_len < 0) { 817 RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, "invalid length"); 818 } 819 820 /* prepare the header for transmission */ 821 len = (jint)dbgsysHostToNetworkLong(len); 822 id = (jint)dbgsysHostToNetworkLong(packet->type.cmd.id); 823 824 memcpy(header + 0, &len, 4); 825 memcpy(header + 4, &id, 4); 826 header[8] = packet->type.cmd.flags; 827 if (packet->type.cmd.flags & JDWPTRANSPORT_FLAGS_REPLY) { 828 jshort errorCode = 829 dbgsysHostToNetworkShort(packet->type.reply.errorCode); 830 memcpy(header + 9, &errorCode, 2); 831 } else { 832 header[9] = packet->type.cmd.cmdSet; 833 header[10] = packet->type.cmd.cmd; 834 } 835 836 data = packet->type.cmd.data; 837 /* Do one send for short packets, two for longer ones */ 838 if (data_len <= MAX_DATA_SIZE) { 839 memcpy(header + JDWP_HEADER_SIZE, data, data_len); 840 if (send_fully(socketFD, (char *)&header, JDWP_HEADER_SIZE + data_len) != 841 JDWP_HEADER_SIZE + data_len) { 842 RETURN_IO_ERROR("send failed"); 843 } 844 } else { 845 memcpy(header + JDWP_HEADER_SIZE, data, MAX_DATA_SIZE); 846 if (send_fully(socketFD, (char *)&header, JDWP_HEADER_SIZE + MAX_DATA_SIZE) != 847 JDWP_HEADER_SIZE + MAX_DATA_SIZE) { 848 RETURN_IO_ERROR("send failed"); 849 } 850 /* Send the remaining data bytes right out of the data area. */ 851 if (send_fully(socketFD, (char *)data + MAX_DATA_SIZE, 852 data_len - MAX_DATA_SIZE) != data_len - MAX_DATA_SIZE) { 853 RETURN_IO_ERROR("send failed"); 854 } 855 } 856 857 return JDWPTRANSPORT_ERROR_NONE; 858 } 859 860 static jint 861 recv_fully(int f, char *buf, int len) 862 { 863 int nbytes = 0; 864 while (nbytes < len) { 865 int res = dbgsysRecv(f, buf + nbytes, len - nbytes, 0); 866 if (res < 0) { 867 return res; 868 } else if (res == 0) { 869 break; /* eof, return nbytes which is less than len */ 870 } 871 nbytes += res; 872 } 873 return nbytes; 874 } 875 876 jint 877 send_fully(int f, char *buf, int len) 878 { 879 int nbytes = 0; 880 while (nbytes < len) { 881 int res = dbgsysSend(f, buf + nbytes, len - nbytes, 0); 882 if (res < 0) { 883 return res; 884 } else if (res == 0) { 885 break; /* eof, return nbytes which is less than len */ 886 } 887 nbytes += res; 888 } 889 return nbytes; 890 } 891 892 static jdwpTransportError JNICALL 893 socketTransport_readPacket(jdwpTransportEnv* env, jdwpPacket* packet) { 894 jint length, data_len; 895 jint n; 896 897 /* packet can't be null */ 898 if (packet == NULL) { 899 RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, "packet is null"); 900 } 901 902 /* read the length field */ 903 n = recv_fully(socketFD, (char *)&length, sizeof(jint)); 904 905 /* check for EOF */ 906 if (n == 0) { 907 packet->type.cmd.len = 0; 908 return JDWPTRANSPORT_ERROR_NONE; 909 } 910 if (n != sizeof(jint)) { 911 RETURN_RECV_ERROR(n); 912 } 913 914 length = (jint)dbgsysNetworkToHostLong(length); 915 packet->type.cmd.len = length; 916 917 918 n = recv_fully(socketFD,(char *)&(packet->type.cmd.id), sizeof(jint)); 919 if (n < (int)sizeof(jint)) { 920 RETURN_RECV_ERROR(n); 921 } 922 923 packet->type.cmd.id = (jint)dbgsysNetworkToHostLong(packet->type.cmd.id); 924 925 n = recv_fully(socketFD,(char *)&(packet->type.cmd.flags), sizeof(jbyte)); 926 if (n < (int)sizeof(jbyte)) { 927 RETURN_RECV_ERROR(n); 928 } 929 930 if (packet->type.cmd.flags & JDWPTRANSPORT_FLAGS_REPLY) { 931 n = recv_fully(socketFD,(char *)&(packet->type.reply.errorCode), sizeof(jbyte)); 932 if (n < (int)sizeof(jshort)) { 933 RETURN_RECV_ERROR(n); 934 } 935 936 /* FIXME - should the error be converted to host order?? */ 937 938 939 } else { 940 n = recv_fully(socketFD,(char *)&(packet->type.cmd.cmdSet), sizeof(jbyte)); 941 if (n < (int)sizeof(jbyte)) { 942 RETURN_RECV_ERROR(n); 943 } 944 945 n = recv_fully(socketFD,(char *)&(packet->type.cmd.cmd), sizeof(jbyte)); 946 if (n < (int)sizeof(jbyte)) { 947 RETURN_RECV_ERROR(n); 948 } 949 } 950 951 data_len = length - ((sizeof(jint) * 2) + (sizeof(jbyte) * 3)); 952 953 if (data_len < 0) { 954 setLastError(0, "Badly formed packet received - invalid length"); 955 return JDWPTRANSPORT_ERROR_IO_ERROR; 956 } else if (data_len == 0) { 957 packet->type.cmd.data = NULL; 958 } else { 959 packet->type.cmd.data= (*callback->alloc)(data_len); 960 961 if (packet->type.cmd.data == NULL) { 962 RETURN_ERROR(JDWPTRANSPORT_ERROR_OUT_OF_MEMORY, "out of memory"); 963 } 964 965 n = recv_fully(socketFD,(char *)packet->type.cmd.data, data_len); 966 if (n < data_len) { 967 (*callback->free)(packet->type.cmd.data); 968 RETURN_RECV_ERROR(n); 969 } 970 } 971 972 return JDWPTRANSPORT_ERROR_NONE; 973 } 974 975 static jdwpTransportError JNICALL 976 socketTransport_getLastError(jdwpTransportEnv* env, char** msgP) { 977 char *msg = (char *)dbgsysTlsGet(tlsIndex); 978 if (msg == NULL) { 979 return JDWPTRANSPORT_ERROR_MSG_NOT_AVAILABLE; 980 } 981 *msgP = (*callback->alloc)((int)strlen(msg)+1); 982 if (*msgP == NULL) { 983 return JDWPTRANSPORT_ERROR_OUT_OF_MEMORY; 984 } 985 strcpy(*msgP, msg); 986 return JDWPTRANSPORT_ERROR_NONE; 987 } 988 989 static jdwpTransportError JNICALL 990 socketTransport_setConfiguration(jdwpTransportEnv* env, jdwpTransportConfiguration* cfg) { 991 const char* allowed_peers = NULL; 992 993 if (cfg == NULL) { 994 RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, 995 "NULL pointer to transport configuration is invalid"); 996 } 997 allowed_peers = cfg->allowed_peers; 998 _peers_cnt = 0; 999 if (allowed_peers != NULL) { 1000 size_t len = strlen(allowed_peers); 1001 if (len == 0) { /* Impossible: parseOptions() would reject it */ 1002 fprintf(stderr, "Error in allow option: '%s'\n", allowed_peers); 1003 RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, 1004 "allow option should not be empty"); 1005 } else if (*allowed_peers == '*') { 1006 if (len != 1) { 1007 fprintf(stderr, "Error in allow option: '%s'\n", allowed_peers); 1008 RETURN_ERROR(JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT, 1009 "allow option '*' cannot be expanded"); 1010 } 1011 } else { 1012 int err = parseAllowedPeers(allowed_peers); 1013 if (err != JDWPTRANSPORT_ERROR_NONE) { 1014 return err; 1015 } 1016 } 1017 } 1018 return JDWPTRANSPORT_ERROR_NONE; 1019 } 1020 1021 jint JNICALL 1022 jdwpTransport_OnLoad(JavaVM *vm, jdwpTransportCallback* cbTablePtr, 1023 jint version, jdwpTransportEnv** env) 1024 { 1025 if (version < JDWPTRANSPORT_VERSION_1_0 || 1026 version > JDWPTRANSPORT_VERSION_1_1) { 1027 return JNI_EVERSION; 1028 } 1029 if (initialized) { 1030 /* 1031 * This library doesn't support multiple environments (yet) 1032 */ 1033 return JNI_EEXIST; 1034 } 1035 initialized = JNI_TRUE; 1036 jvm = vm; 1037 callback = cbTablePtr; 1038 1039 /* initialize interface table */ 1040 interface.GetCapabilities = &socketTransport_getCapabilities; 1041 interface.Attach = &socketTransport_attach; 1042 interface.StartListening = &socketTransport_startListening; 1043 interface.StopListening = &socketTransport_stopListening; 1044 interface.Accept = &socketTransport_accept; 1045 interface.IsOpen = &socketTransport_isOpen; 1046 interface.Close = &socketTransport_close; 1047 interface.ReadPacket = &socketTransport_readPacket; 1048 interface.WritePacket = &socketTransport_writePacket; 1049 interface.GetLastError = &socketTransport_getLastError; 1050 if (version >= JDWPTRANSPORT_VERSION_1_1) { 1051 interface.SetTransportConfiguration = &socketTransport_setConfiguration; 1052 } 1053 *env = &single_env; 1054 1055 /* initialized TLS */ 1056 tlsIndex = dbgsysTlsAlloc(); 1057 return JNI_OK; 1058 }