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