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 implementation
5  * is licensed under the same terms as the file jdwpTransport.h.  The
6  * copyright and license information for the file jdwpTranport.h follows.
7  *
8  * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
9  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
10  *
11  * This code is free software; you can redistribute it and/or modify it
12  * under the terms of the GNU General Public License version 2 only, as
13  * published by the Free Software Foundation.  Oracle designates this
14  * particular file as subject to the "Classpath" exception as provided
15  * by Oracle in the LICENSE file that accompanied this code.
16  *
17  * This code is distributed in the hope that it will be useful, but WITHOUT
18  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20  * version 2 for more details (a copy is included in the LICENSE file that
21  * accompanied this code).
22  *
23  * You should have received a copy of the GNU General Public License version
24  * 2 along with this work; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26  *
27  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
28  * or visit www.oracle.com if you need additional information or have any
29  * questions.
30  */
31 
32 #ifndef ART_DT_FD_FORWARD_DT_FD_FORWARD_H_
33 #define ART_DT_FD_FORWARD_DT_FD_FORWARD_H_
34 
35 #include <atomic>
36 #include <condition_variable>
37 #include <mutex>
38 #include <string>
39 
40 #include <android-base/logging.h>
41 #include <android-base/thread_annotations.h>
42 #include <android-base/unique_fd.h>
43 
44 #include <arpa/inet.h>
45 #include <sys/eventfd.h>
46 #include <unistd.h>
47 #include <poll.h>
48 
49 #include <jni.h>
50 #include <jvmti.h>
51 #include <jdwpTransport.h>
52 
53 #include "fd_transport.h"
54 
55 namespace dt_fd_forward {
56 
57 static constexpr uint8_t kReplyFlag = 0x80;
58 // Macro and constexpr to make error values less annoying to write.
59 #define ERR(e) JDWPTRANSPORT_ERROR_ ## e
60 static constexpr jdwpTransportError OK = ERR(NONE);
61 
62 static constexpr const char kJdwpHandshake[14] = {
63     'J', 'D', 'W', 'P', '-', 'H', 'a', 'n', 'd', 's', 'h', 'a', 'k', 'e'
64 };  // "JDWP-Handshake"
65 
66 enum class TransportState {
67   kClosed,       // Main state.
68   kListenSetup,  // Transient, wait for the state to change before proceeding.
69   kListening,    // Main state.
70   kOpening,      // Transient, wait for the state to change before proceeding.
71   kOpen,         // Main state.
72 };
73 
74 enum class IOResult {
75   kOk, kInterrupt, kError, kEOF,
76 };
77 
78 class PacketReader;
79 class PacketWriter;
80 
81 // TODO It would be good to get the thread-safety analysis checks working but first we would need to
82 // use something other than std::mutex which does not have the annotations required.
83 class FdForwardTransport : public jdwpTransportEnv {
84  public:
85   explicit FdForwardTransport(jdwpTransportCallback* cb);
86   ~FdForwardTransport();
87 
88   jdwpTransportError PerformAttach(int listen_fd);
89   jdwpTransportError SetupListen(int listen_fd);
90   jdwpTransportError StopListening();
91 
92   jboolean IsOpen();
93 
94   jdwpTransportError WritePacket(const jdwpPacket* pkt);
95   jdwpTransportError ReadPacket(jdwpPacket* pkt);
96   jdwpTransportError Close();
97   jdwpTransportError Accept();
98   jdwpTransportError GetLastError(/*out*/char** description);
99 
100   void* Alloc(size_t data);
101   void Free(void* data);
102 
103  private:
104   void SetLastError(const std::string& desc);
105 
106   bool ChangeState(TransportState old_state, TransportState new_state);  // REQUIRES(state_mutex_);
107 
108   // Gets the fds from the server side. do_handshake returns whether the transport can skip the
109   // jdwp handshake.
110   IOResult ReceiveFdsFromSocket(/*out*/bool* do_handshake);
111 
112   IOResult WriteFully(const void* data, size_t ndata);  // REQUIRES(!state_mutex_);
113   IOResult WriteFullyWithoutChecks(const void* data, size_t ndata);  // REQUIRES(state_mutex_);
114   IOResult ReadFully(void* data, size_t ndata);  // REQUIRES(!state_mutex_);
115   IOResult ReadUpToMax(void* data, size_t ndata, /*out*/size_t* amount_read);
116       // REQUIRES(state_mutex_);
117   IOResult ReadFullyWithoutChecks(void* data, size_t ndata);  // REQUIRES(state_mutex_);
118 
119   void CloseFdsLocked();  // REQUIRES(state_mutex_)
120 
121   // The allocation/deallocation functions.
122   jdwpTransportCallback mem_;
123 
124   // Input from the server;
125   android::base::unique_fd read_fd_;  // GUARDED_BY(state_mutex_);
126   // Output to the server;
127   android::base::unique_fd write_fd_;  // GUARDED_BY(state_mutex_);
128 
129   // an eventfd passed with the write_fd to the transport that we will 'read' from to get a lock on
130   // the write_fd_. The other side must not hold it for unbounded time.
131   android::base::unique_fd write_lock_fd_;  // GUARDED_BY(state_mutex_);
132 
133   // Eventfd we will use to wake-up paused reads for close().
134   android::base::unique_fd wakeup_fd_;
135 
136   // Socket we will get the read/write fd's from.
137   android::base::unique_fd listen_fd_;
138 
139   // Fd we will write close notification to. This is a dup of listen_fd_.
140   android::base::unique_fd close_notify_fd_;
141 
142   TransportState state_;  // GUARDED_BY(state_mutex_);
143 
144   std::mutex state_mutex_;
145   std::condition_variable state_cv_;
146 
147   // A counter that we use to make sure we don't do half a read on one and half on another fd.
148   std::atomic<uint64_t> current_seq_num_;
149 
150   friend class PacketReader;  // For ReadFullyWithInterrupt
151   friend class PacketWriter;  // For WriteFullyWithInterrupt
152 };
153 
154 }  // namespace dt_fd_forward
155 
156 #endif  // ART_DT_FD_FORWARD_DT_FD_FORWARD_H_
157