1 /* Copyright (C) 2017 The Android Open Source Project 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This file implements interfaces from the file jdwpTransport.h. This 5 * implementation is licensed under the same terms as the file 6 * jdwpTransport.h. The copyright and license information for the file 7 * jdwpTransport.h follows. 8 * 9 * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. 10 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 11 * 12 * This code is free software; you can redistribute it and/or modify it 13 * under the terms of the GNU General Public License version 2 only, as 14 * published by the Free Software Foundation. Oracle designates this 15 * particular file as subject to the "Classpath" exception as provided 16 * by Oracle in the LICENSE file that accompanied this code. 17 * 18 * This code is distributed in the hope that it will be useful, but WITHOUT 19 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 20 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 21 * version 2 for more details (a copy is included in the LICENSE file that 22 * accompanied this code). 23 * 24 * You should have received a copy of the GNU General Public License version 25 * 2 along with this work; if not, write to the Free Software Foundation, 26 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 27 * 28 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 29 * or visit www.oracle.com if you need additional information or have any 30 * questions. 31 */ 32 33 #include "dt_fd_forward.h" 34 35 #include <string> 36 #include <vector> 37 38 #include <android-base/endian.h> 39 #include <android-base/logging.h> 40 #include <android-base/parseint.h> 41 #include <android-base/stringprintf.h> 42 43 #include <sys/ioctl.h> 44 #include <sys/eventfd.h> 45 #include <sys/socket.h> 46 #include <sys/types.h> 47 #include <unistd.h> 48 #include <poll.h> 49 50 #include <jni.h> 51 #include <jdwpTransport.h> 52 53 namespace dt_fd_forward { 54 55 // Helper that puts line-number in error message. 56 #define DT_IO_ERROR(f) \ 57 SetLastError(::android::base::StringPrintf("%s:%d - %s: %s", \ 58 __FILE__, __LINE__, f, strerror(errno))) 59 60 extern const jdwpTransportNativeInterface_ gTransportInterface; 61 62 template <typename T> static T HostToNetwork(T in); 63 template <typename T> static T NetworkToHost(T in); 64 65 template<> int8_t HostToNetwork(int8_t in) { return in; } 66 template<> int8_t NetworkToHost(int8_t in) { return in; } 67 template<> int16_t HostToNetwork(int16_t in) { return htons(in); } 68 template<> int16_t NetworkToHost(int16_t in) { return ntohs(in); } 69 template<> int32_t HostToNetwork(int32_t in) { return htonl(in); } 70 template<> int32_t NetworkToHost(int32_t in) { return ntohl(in); } 71 72 FdForwardTransport::FdForwardTransport(jdwpTransportCallback* cb) 73 : mem_(*cb), 74 read_fd_(-1), 75 write_fd_(-1), 76 wakeup_fd_(eventfd(0, EFD_NONBLOCK)), 77 listen_fd_(-1), 78 close_notify_fd_(-1), 79 state_(TransportState::kClosed), 80 current_seq_num_(0) {} 81 82 FdForwardTransport::~FdForwardTransport() { } 83 84 bool FdForwardTransport::ChangeState(TransportState old_state, TransportState new_state) { 85 if (old_state == state_) { 86 state_ = new_state; 87 state_cv_.notify_all(); 88 return true; 89 } else { 90 return false; 91 } 92 } 93 94 jdwpTransportError FdForwardTransport::PerformAttach(int listen_fd) { 95 jdwpTransportError err = SetupListen(listen_fd); 96 if (err != OK) { 97 return OK; 98 } 99 err = Accept(); 100 StopListening(); 101 return err; 102 } 103 104 static void SendListenMessage(const android::base::unique_fd& fd) { 105 TEMP_FAILURE_RETRY(send(fd, kListenStartMessage, sizeof(kListenStartMessage), MSG_EOR)); 106 } 107 108 jdwpTransportError FdForwardTransport::SetupListen(int listen_fd) { 109 std::lock_guard<std::mutex> lk(state_mutex_); 110 if (!ChangeState(TransportState::kClosed, TransportState::kListenSetup)) { 111 return ERR(ILLEGAL_STATE); 112 } else { 113 listen_fd_.reset(dup(listen_fd)); 114 SendListenMessage(listen_fd_); 115 CHECK(ChangeState(TransportState::kListenSetup, TransportState::kListening)); 116 return OK; 117 } 118 } 119 120 static void SendListenEndMessage(const android::base::unique_fd& fd) { 121 TEMP_FAILURE_RETRY(send(fd, kListenEndMessage, sizeof(kListenEndMessage), MSG_EOR)); 122 } 123 124 jdwpTransportError FdForwardTransport::StopListening() { 125 std::lock_guard<std::mutex> lk(state_mutex_); 126 if (listen_fd_ != -1) { 127 SendListenEndMessage(listen_fd_); 128 } 129 // Don't close the listen_fd_ since we might need it for later calls to listen. 130 if (ChangeState(TransportState::kListening, TransportState::kClosed) || 131 state_ == TransportState::kOpen) { 132 listen_fd_.reset(); 133 } 134 return OK; 135 } 136 137 // Last error message. 138 thread_local std::string global_last_error_; 139 140 void FdForwardTransport::SetLastError(const std::string& desc) { 141 LOG(ERROR) << desc; 142 global_last_error_ = desc; 143 } 144 145 IOResult FdForwardTransport::ReadFullyWithoutChecks(void* data, size_t ndata) { 146 uint8_t* bdata = reinterpret_cast<uint8_t*>(data); 147 size_t nbytes = 0; 148 while (nbytes < ndata) { 149 int res = TEMP_FAILURE_RETRY(read(read_fd_, bdata + nbytes, ndata - nbytes)); 150 if (res < 0) { 151 DT_IO_ERROR("Failed read()"); 152 return IOResult::kError; 153 } else if (res == 0) { 154 return IOResult::kEOF; 155 } else { 156 nbytes += res; 157 } 158 } 159 return IOResult::kOk; 160 } 161 162 IOResult FdForwardTransport::ReadUpToMax(void* data, size_t ndata, /*out*/size_t* read_amount) { 163 CHECK_GE(read_fd_.get(), 0); 164 int avail; 165 int res = TEMP_FAILURE_RETRY(ioctl(read_fd_, FIONREAD, &avail)); 166 if (res < 0) { 167 DT_IO_ERROR("Failed ioctl(read_fd_, FIONREAD, &avail)"); 168 return IOResult::kError; 169 } 170 size_t to_read = std::min(static_cast<size_t>(avail), ndata); 171 *read_amount = to_read; 172 if (*read_amount == 0) { 173 // Check if the read would cause an EOF. 174 struct pollfd pollfd = { read_fd_, POLLRDHUP, 0 }; 175 res = TEMP_FAILURE_RETRY(poll(&pollfd, /*nfds*/1, /*timeout*/0)); 176 if (res < 0 || (pollfd.revents & POLLERR) == POLLERR) { 177 DT_IO_ERROR("Failed poll on read fd."); 178 return IOResult::kError; 179 } 180 return ((pollfd.revents & (POLLRDHUP | POLLHUP)) == 0) ? IOResult::kOk : IOResult::kEOF; 181 } 182 183 return ReadFullyWithoutChecks(data, to_read); 184 } 185 186 IOResult FdForwardTransport::ReadFully(void* data, size_t ndata) { 187 uint64_t seq_num = current_seq_num_; 188 size_t nbytes = 0; 189 while (nbytes < ndata) { 190 size_t read_len; 191 struct pollfd pollfds[2]; 192 { 193 std::lock_guard<std::mutex> lk(state_mutex_); 194 // Operations in this block must not cause an unbounded pause. 195 if (state_ != TransportState::kOpen || seq_num != current_seq_num_) { 196 // Async-close occurred! 197 return IOResult::kInterrupt; 198 } else { 199 CHECK_GE(read_fd_.get(), 0); 200 } 201 IOResult res = ReadUpToMax(reinterpret_cast<uint8_t*>(data) + nbytes, 202 ndata - nbytes, 203 /*out*/&read_len); 204 if (res != IOResult::kOk) { 205 return res; 206 } else { 207 nbytes += read_len; 208 } 209 210 pollfds[0] = { read_fd_, POLLRDHUP | POLLIN, 0 }; 211 pollfds[1] = { wakeup_fd_, POLLIN, 0 }; 212 } 213 if (read_len == 0) { 214 // No more data. Sleep without locks until more is available. We don't actually check for any 215 // errors since possible ones are (1) the read_fd_ is closed or wakeup happens which are both 216 // fine since the wakeup_fd_ or the poll failing will wake us up. 217 int poll_res = TEMP_FAILURE_RETRY(poll(pollfds, 2, -1)); 218 if (poll_res < 0) { 219 DT_IO_ERROR("Failed to poll!"); 220 } 221 // Clear the wakeup_fd regardless. 222 uint64_t val; 223 int unused = TEMP_FAILURE_RETRY(read(wakeup_fd_, &val, sizeof(val))); 224 DCHECK(unused == sizeof(val) || errno == EAGAIN); 225 if (poll_res < 0) { 226 return IOResult::kError; 227 } 228 } 229 } 230 return IOResult::kOk; 231 } 232 233 // A helper that allows us to lock the eventfd 'fd'. 234 class ScopedEventFdLock { 235 public: 236 explicit ScopedEventFdLock(const android::base::unique_fd& fd) : fd_(fd), data_(0) { 237 TEMP_FAILURE_RETRY(read(fd_, &data_, sizeof(data_))); 238 } 239 240 ~ScopedEventFdLock() { 241 TEMP_FAILURE_RETRY(write(fd_, &data_, sizeof(data_))); 242 } 243 244 private: 245 const android::base::unique_fd& fd_; 246 uint64_t data_; 247 }; 248 249 IOResult FdForwardTransport::WriteFullyWithoutChecks(const void* data, size_t ndata) { 250 ScopedEventFdLock sefdl(write_lock_fd_); 251 const uint8_t* bdata = static_cast<const uint8_t*>(data); 252 size_t nbytes = 0; 253 while (nbytes < ndata) { 254 int res = TEMP_FAILURE_RETRY(write(write_fd_, bdata + nbytes, ndata - nbytes)); 255 if (res < 0) { 256 DT_IO_ERROR("Failed write()"); 257 return IOResult::kError; 258 } else if (res == 0) { 259 return IOResult::kEOF; 260 } else { 261 nbytes += res; 262 } 263 } 264 return IOResult::kOk; 265 } 266 267 IOResult FdForwardTransport::WriteFully(const void* data, size_t ndata) { 268 std::lock_guard<std::mutex> lk(state_mutex_); 269 if (state_ != TransportState::kOpen) { 270 return IOResult::kInterrupt; 271 } 272 return WriteFullyWithoutChecks(data, ndata); 273 } 274 275 static void SendAcceptMessage(int fd) { 276 TEMP_FAILURE_RETRY(send(fd, kAcceptMessage, sizeof(kAcceptMessage), MSG_EOR)); 277 } 278 279 IOResult FdForwardTransport::ReceiveFdsFromSocket(bool* do_handshake) { 280 union { 281 cmsghdr cm; 282 uint8_t buffer[CMSG_SPACE(sizeof(FdSet))]; 283 } msg_union; 284 // This lets us know if we need to do a handshake or not. 285 char message[128]; 286 iovec iov; 287 iov.iov_base = message; 288 iov.iov_len = sizeof(message); 289 290 msghdr msg; 291 memset(&msg, 0, sizeof(msg)); 292 msg.msg_iov = &iov; 293 msg.msg_iovlen = 1; 294 msg.msg_control = msg_union.buffer; 295 msg.msg_controllen = sizeof(msg_union.buffer); 296 297 cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); 298 cmsg->cmsg_len = msg.msg_controllen; 299 cmsg->cmsg_level = SOL_SOCKET; 300 cmsg->cmsg_type = SCM_RIGHTS; 301 memset(reinterpret_cast<int*>(CMSG_DATA(cmsg)), -1, FdSet::kDataLength); 302 303 int res = TEMP_FAILURE_RETRY(recvmsg(listen_fd_, &msg, 0)); 304 if (res <= 0) { 305 DT_IO_ERROR("Failed to receive fds!"); 306 return IOResult::kError; 307 } 308 FdSet out_fds = FdSet::ReadData(CMSG_DATA(cmsg)); 309 bool failed = false; 310 if (out_fds.read_fd_ < 0 || 311 out_fds.write_fd_ < 0 || 312 out_fds.write_lock_fd_ < 0) { 313 DT_IO_ERROR("Received fds were invalid!"); 314 failed = true; 315 } else if (strcmp(kPerformHandshakeMessage, message) == 0) { 316 *do_handshake = true; 317 } else if (strcmp(kSkipHandshakeMessage, message) == 0) { 318 *do_handshake = false; 319 } else { 320 DT_IO_ERROR("Unknown message sent with fds."); 321 failed = true; 322 } 323 324 if (failed) { 325 if (out_fds.read_fd_ >= 0) { 326 close(out_fds.read_fd_); 327 } 328 if (out_fds.write_fd_ >= 0) { 329 close(out_fds.write_fd_); 330 } 331 if (out_fds.write_lock_fd_ >= 0) { 332 close(out_fds.write_lock_fd_); 333 } 334 return IOResult::kError; 335 } 336 337 read_fd_.reset(out_fds.read_fd_); 338 write_fd_.reset(out_fds.write_fd_); 339 write_lock_fd_.reset(out_fds.write_lock_fd_); 340 341 // We got the fds. Send ack. 342 close_notify_fd_.reset(dup(listen_fd_)); 343 SendAcceptMessage(close_notify_fd_); 344 345 return IOResult::kOk; 346 } 347 348 // Accept the connection. Note that we match the behavior of other transports which is to just close 349 // the connection and try again if we get a bad handshake. 350 jdwpTransportError FdForwardTransport::Accept() { 351 // TODO Work with timeouts. 352 while (true) { 353 std::unique_lock<std::mutex> lk(state_mutex_); 354 while (!ChangeState(TransportState::kListening, TransportState::kOpening)) { 355 if (state_ == TransportState::kClosed || 356 state_ == TransportState::kOpen) { 357 return ERR(ILLEGAL_STATE); 358 } 359 state_cv_.wait(lk); 360 } 361 362 bool do_handshake = false; 363 DCHECK_NE(listen_fd_.get(), -1); 364 if (ReceiveFdsFromSocket(&do_handshake) != IOResult::kOk) { 365 CHECK(ChangeState(TransportState::kOpening, TransportState::kListening)); 366 return ERR(IO_ERROR); 367 } 368 369 current_seq_num_++; 370 371 // Moved to the opening state. 372 if (do_handshake) { 373 // Perform the handshake 374 char handshake_recv[sizeof(kJdwpHandshake)]; 375 memset(handshake_recv, 0, sizeof(handshake_recv)); 376 IOResult res = ReadFullyWithoutChecks(handshake_recv, sizeof(handshake_recv)); 377 if (res != IOResult::kOk || 378 strncmp(handshake_recv, kJdwpHandshake, sizeof(kJdwpHandshake)) != 0) { 379 DT_IO_ERROR("Failed to read handshake"); 380 CHECK(ChangeState(TransportState::kOpening, TransportState::kListening)); 381 CloseFdsLocked(); 382 // Retry. 383 continue; 384 } 385 res = WriteFullyWithoutChecks(kJdwpHandshake, sizeof(kJdwpHandshake)); 386 if (res != IOResult::kOk) { 387 DT_IO_ERROR("Failed to write handshake"); 388 CHECK(ChangeState(TransportState::kOpening, TransportState::kListening)); 389 CloseFdsLocked(); 390 // Retry. 391 continue; 392 } 393 } 394 break; 395 } 396 CHECK(ChangeState(TransportState::kOpening, TransportState::kOpen)); 397 return OK; 398 } 399 400 void SendClosingMessage(int fd) { 401 if (fd >= 0) { 402 TEMP_FAILURE_RETRY(send(fd, kCloseMessage, sizeof(kCloseMessage), MSG_EOR)); 403 } 404 } 405 406 // Actually close the fds associated with this transport. 407 void FdForwardTransport::CloseFdsLocked() { 408 // We have a different set of fd's now. Increase the seq number. 409 current_seq_num_++; 410 411 // All access to these is locked under the state_mutex_ so we are safe to close these. 412 { 413 ScopedEventFdLock sefdl(write_lock_fd_); 414 if (close_notify_fd_ >= 0) { 415 SendClosingMessage(close_notify_fd_); 416 } 417 close_notify_fd_.reset(); 418 read_fd_.reset(); 419 write_fd_.reset(); 420 close_notify_fd_.reset(); 421 } 422 write_lock_fd_.reset(); 423 424 // Send a wakeup in case we have any in-progress reads/writes. 425 uint64_t data = 1; 426 TEMP_FAILURE_RETRY(write(wakeup_fd_, &data, sizeof(data))); 427 } 428 429 jdwpTransportError FdForwardTransport::Close() { 430 std::lock_guard<std::mutex> lk(state_mutex_); 431 jdwpTransportError res = 432 ChangeState(TransportState::kOpen, TransportState::kClosed) ? OK : ERR(ILLEGAL_STATE); 433 // Send a wakeup after changing the state even if nothing actually happened. 434 uint64_t data = 1; 435 TEMP_FAILURE_RETRY(write(wakeup_fd_, &data, sizeof(data))); 436 if (res == OK) { 437 CloseFdsLocked(); 438 } 439 return res; 440 } 441 442 // A helper class to read and parse the JDWP packet. 443 class PacketReader { 444 public: 445 PacketReader(FdForwardTransport* transport, jdwpPacket* pkt) 446 : transport_(transport), 447 pkt_(pkt), 448 is_eof_(false), 449 is_err_(false) {} 450 bool ReadFully() { 451 // Zero out. 452 memset(pkt_, 0, sizeof(jdwpPacket)); 453 int32_t len = ReadInt32(); // read len 454 if (is_err_) { 455 return false; 456 } else if (is_eof_) { 457 return true; 458 } else if (len < 11) { 459 transport_->DT_IO_ERROR("Packet with len < 11 received!"); 460 return false; 461 } 462 pkt_->type.cmd.len = len; 463 pkt_->type.cmd.id = ReadInt32(); 464 pkt_->type.cmd.flags = ReadByte(); 465 if (is_err_) { 466 return false; 467 } else if (is_eof_) { 468 return true; 469 } else if ((pkt_->type.reply.flags & JDWPTRANSPORT_FLAGS_REPLY) == JDWPTRANSPORT_FLAGS_REPLY) { 470 ReadReplyPacket(); 471 } else { 472 ReadCmdPacket(); 473 } 474 return !is_err_; 475 } 476 477 private: 478 void ReadReplyPacket() { 479 pkt_->type.reply.errorCode = ReadInt16(); 480 pkt_->type.reply.data = ReadRemaining(); 481 } 482 483 void ReadCmdPacket() { 484 pkt_->type.cmd.cmdSet = ReadByte(); 485 pkt_->type.cmd.cmd = ReadByte(); 486 pkt_->type.cmd.data = ReadRemaining(); 487 } 488 489 template <typename T> 490 T HandleResult(IOResult res, T val, T fail) { 491 switch (res) { 492 case IOResult::kError: 493 is_err_ = true; 494 return fail; 495 case IOResult::kOk: 496 return val; 497 case IOResult::kEOF: 498 is_eof_ = true; 499 pkt_->type.cmd.len = 0; 500 return fail; 501 case IOResult::kInterrupt: 502 transport_->DT_IO_ERROR("Failed to read, concurrent close!"); 503 is_err_ = true; 504 return fail; 505 } 506 } 507 508 jbyte* ReadRemaining() { 509 if (is_eof_ || is_err_) { 510 return nullptr; 511 } 512 jbyte* out = nullptr; 513 jint rem = pkt_->type.cmd.len - 11; 514 CHECK_GE(rem, 0); 515 if (rem == 0) { 516 return nullptr; 517 } else { 518 out = reinterpret_cast<jbyte*>(transport_->Alloc(rem)); 519 IOResult res = transport_->ReadFully(out, rem); 520 jbyte* ret = HandleResult(res, out, static_cast<jbyte*>(nullptr)); 521 if (ret != out) { 522 transport_->Free(out); 523 } 524 return ret; 525 } 526 } 527 528 jbyte ReadByte() { 529 if (is_eof_ || is_err_) { 530 return -1; 531 } 532 jbyte out; 533 IOResult res = transport_->ReadFully(&out, sizeof(out)); 534 return HandleResult(res, NetworkToHost(out), static_cast<jbyte>(-1)); 535 } 536 537 jshort ReadInt16() { 538 if (is_eof_ || is_err_) { 539 return -1; 540 } 541 jshort out; 542 IOResult res = transport_->ReadFully(&out, sizeof(out)); 543 return HandleResult(res, NetworkToHost(out), static_cast<jshort>(-1)); 544 } 545 546 jint ReadInt32() { 547 if (is_eof_ || is_err_) { 548 return -1; 549 } 550 jint out; 551 IOResult res = transport_->ReadFully(&out, sizeof(out)); 552 return HandleResult(res, NetworkToHost(out), -1); 553 } 554 555 FdForwardTransport* transport_; 556 jdwpPacket* pkt_; 557 bool is_eof_; 558 bool is_err_; 559 }; 560 561 jdwpTransportError FdForwardTransport::ReadPacket(jdwpPacket* pkt) { 562 if (pkt == nullptr) { 563 return ERR(ILLEGAL_ARGUMENT); 564 } 565 PacketReader reader(this, pkt); 566 if (reader.ReadFully()) { 567 return OK; 568 } else { 569 return ERR(IO_ERROR); 570 } 571 } 572 573 // A class that writes a packet to the transport. 574 class PacketWriter { 575 public: 576 PacketWriter(FdForwardTransport* transport, const jdwpPacket* pkt) 577 : transport_(transport), pkt_(pkt), data_() {} 578 579 bool WriteFully() { 580 PushInt32(pkt_->type.cmd.len); 581 PushInt32(pkt_->type.cmd.id); 582 PushByte(pkt_->type.cmd.flags); 583 if ((pkt_->type.reply.flags & JDWPTRANSPORT_FLAGS_REPLY) == JDWPTRANSPORT_FLAGS_REPLY) { 584 PushInt16(pkt_->type.reply.errorCode); 585 PushData(pkt_->type.reply.data, pkt_->type.reply.len - 11); 586 } else { 587 PushByte(pkt_->type.cmd.cmdSet); 588 PushByte(pkt_->type.cmd.cmd); 589 PushData(pkt_->type.cmd.data, pkt_->type.cmd.len - 11); 590 } 591 IOResult res = transport_->WriteFully(data_.data(), data_.size()); 592 return res == IOResult::kOk; 593 } 594 595 private: 596 void PushInt32(int32_t data) { 597 data = HostToNetwork(data); 598 PushData(&data, sizeof(data)); 599 } 600 void PushInt16(int16_t data) { 601 data = HostToNetwork(data); 602 PushData(&data, sizeof(data)); 603 } 604 void PushByte(jbyte data) { 605 data_.push_back(HostToNetwork(data)); 606 } 607 608 void PushData(void* d, size_t size) { 609 uint8_t* bytes = reinterpret_cast<uint8_t*>(d); 610 data_.insert(data_.end(), bytes, bytes + size); 611 } 612 613 FdForwardTransport* transport_; 614 const jdwpPacket* pkt_; 615 std::vector<uint8_t> data_; 616 }; 617 618 jdwpTransportError FdForwardTransport::WritePacket(const jdwpPacket* pkt) { 619 if (pkt == nullptr) { 620 return ERR(ILLEGAL_ARGUMENT); 621 } 622 PacketWriter writer(this, pkt); 623 if (writer.WriteFully()) { 624 return OK; 625 } else { 626 return ERR(IO_ERROR); 627 } 628 } 629 630 jboolean FdForwardTransport::IsOpen() { 631 return state_ == TransportState::kOpen; 632 } 633 634 void* FdForwardTransport::Alloc(size_t s) { 635 return mem_.alloc(s); 636 } 637 638 void FdForwardTransport::Free(void* data) { 639 mem_.free(data); 640 } 641 642 jdwpTransportError FdForwardTransport::GetLastError(/*out*/char** err) { 643 std::string data = global_last_error_; 644 *err = reinterpret_cast<char*>(Alloc(data.size() + 1)); 645 strcpy(*err, data.c_str()); 646 return OK; 647 } 648 649 static FdForwardTransport* AsFdForward(jdwpTransportEnv* env) { 650 return reinterpret_cast<FdForwardTransport*>(env); 651 } 652 653 static jdwpTransportError ParseAddress(const std::string& addr, 654 /*out*/int* listen_sock) { 655 if (!android::base::ParseInt(addr.c_str(), listen_sock) || *listen_sock < 0) { 656 LOG(ERROR) << "address format is <fd_num> not " << addr; 657 return ERR(ILLEGAL_ARGUMENT); 658 } 659 return OK; 660 } 661 662 class JdwpTransportFunctions { 663 public: 664 static jdwpTransportError GetCapabilities(jdwpTransportEnv* env ATTRIBUTE_UNUSED, 665 /*out*/ JDWPTransportCapabilities* capabilities_ptr) { 666 // We don't support any of the optional capabilities (can_timeout_attach, can_timeout_accept, 667 // can_timeout_handshake) so just return a zeroed capabilities ptr. 668 // TODO We should maybe support these timeout options. 669 memset(capabilities_ptr, 0, sizeof(JDWPTransportCapabilities)); 670 return OK; 671 } 672 673 // Address is <sock_fd> 674 static jdwpTransportError Attach(jdwpTransportEnv* env, 675 const char* address, 676 jlong attach_timeout ATTRIBUTE_UNUSED, 677 jlong handshake_timeout ATTRIBUTE_UNUSED) { 678 if (address == nullptr || *address == '\0') { 679 return ERR(ILLEGAL_ARGUMENT); 680 } 681 int listen_fd; 682 jdwpTransportError err = ParseAddress(address, &listen_fd); 683 if (err != OK) { 684 return err; 685 } 686 return AsFdForward(env)->PerformAttach(listen_fd); 687 } 688 689 static jdwpTransportError StartListening(jdwpTransportEnv* env, 690 const char* address, 691 /*out*/ char** actual_address) { 692 if (address == nullptr || *address == '\0') { 693 return ERR(ILLEGAL_ARGUMENT); 694 } 695 int listen_fd; 696 jdwpTransportError err = ParseAddress(address, &listen_fd); 697 if (err != OK) { 698 return err; 699 } 700 err = AsFdForward(env)->SetupListen(listen_fd); 701 if (err != OK) { 702 return err; 703 } 704 if (actual_address != nullptr) { 705 *actual_address = reinterpret_cast<char*>(AsFdForward(env)->Alloc(strlen(address) + 1)); 706 memcpy(*actual_address, address, strlen(address) + 1); 707 } 708 return OK; 709 } 710 711 static jdwpTransportError StopListening(jdwpTransportEnv* env) { 712 return AsFdForward(env)->StopListening(); 713 } 714 715 static jdwpTransportError Accept(jdwpTransportEnv* env, 716 jlong accept_timeout ATTRIBUTE_UNUSED, 717 jlong handshake_timeout ATTRIBUTE_UNUSED) { 718 return AsFdForward(env)->Accept(); 719 } 720 721 static jboolean IsOpen(jdwpTransportEnv* env) { 722 return AsFdForward(env)->IsOpen(); 723 } 724 725 static jdwpTransportError Close(jdwpTransportEnv* env) { 726 return AsFdForward(env)->Close(); 727 } 728 729 static jdwpTransportError ReadPacket(jdwpTransportEnv* env, jdwpPacket *pkt) { 730 return AsFdForward(env)->ReadPacket(pkt); 731 } 732 733 static jdwpTransportError WritePacket(jdwpTransportEnv* env, const jdwpPacket* pkt) { 734 return AsFdForward(env)->WritePacket(pkt); 735 } 736 737 static jdwpTransportError GetLastError(jdwpTransportEnv* env, char** error) { 738 return AsFdForward(env)->GetLastError(error); 739 } 740 }; 741 742 // The actual struct holding all the entrypoints into the jdwpTransport interface. 743 const jdwpTransportNativeInterface_ gTransportInterface = { 744 nullptr, // reserved1 745 JdwpTransportFunctions::GetCapabilities, 746 JdwpTransportFunctions::Attach, 747 JdwpTransportFunctions::StartListening, 748 JdwpTransportFunctions::StopListening, 749 JdwpTransportFunctions::Accept, 750 JdwpTransportFunctions::IsOpen, 751 JdwpTransportFunctions::Close, 752 JdwpTransportFunctions::ReadPacket, 753 JdwpTransportFunctions::WritePacket, 754 JdwpTransportFunctions::GetLastError, 755 }; 756 757 extern "C" 758 JNIEXPORT jint JNICALL jdwpTransport_OnLoad(JavaVM* vm ATTRIBUTE_UNUSED, 759 jdwpTransportCallback* cb, 760 jint version, 761 jdwpTransportEnv** /*out*/env) { 762 if (version != JDWPTRANSPORT_VERSION_1_0) { 763 LOG(ERROR) << "unknown version " << version; 764 return JNI_EVERSION; 765 } 766 void* data = cb->alloc(sizeof(FdForwardTransport)); 767 if (data == nullptr) { 768 LOG(ERROR) << "Failed to allocate data for transport!"; 769 return JNI_ENOMEM; 770 } 771 FdForwardTransport* transport = 772 new (data) FdForwardTransport(cb); 773 transport->functions = &gTransportInterface; 774 *env = transport; 775 return JNI_OK; 776 } 777 778 } // namespace dt_fd_forward 779