-
Notifications
You must be signed in to change notification settings - Fork 0
/
socket.h
165 lines (130 loc) · 6.46 KB
/
socket.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __ADB_SOCKET_H
#define __ADB_SOCKET_H
#include <stddef.h>
#include <deque>
#include <memory>
#include <optional>
#include <string>
#include "adb_unique_fd.h"
#include "fdevent/fdevent.h"
#include "types.h"
class atransport;
/* An asocket represents one half of a connection between a local and
remote entity. A local asocket is bound to a file descriptor. A
remote asocket is bound to the protocol engine.
Example (two local_sockets) :
ASOCKET(THIS)
┌────────────────────────────────────────────────┐
┌──┐ write(3) │ ┌─────┐ enqueue() │
│ │◄─────────┼──┤Queue├─────────────◄────────────┐ │
│fd│ │ └─────┘ ▲ │
│ ├──────────►─────────────────┐ │ │
└──┘ read(3) └─────────────────┼─────────────────┼────────────┘
outgoing │ │ incoming
┌─────────────────▼─────────────────▲────────────┐ read(3) ┌──┐
│ │ └────────────┼─────────◄─┤ │
│ │ ┌─────┐ │ │fd│
│ └─────────────────────►│Queue├─┼─────────►─┤ │
│ enqueue() └─────┘ │ write(3) └──┘
└────────────────────────────────────────────────┘
ASOCKET(PEER)
Note that sockets can be peered regardless of their kind. A remote socket can be peered with
a smart socket, a local socket can be peered with a remote socket and so on.
*/
struct asocket {
/* the unique identifier for this asocket
*/
unsigned id = 0;
// Start Local socket fields
// TODO: move all the local socket fields together
/* flag: set when the socket's peer has closed
* but packets are still queued for delivery
* TODO: This should be a boolean.
*/
bool closing = false;
// flag: set when the socket failed to write, so the socket will not wait to
// write packets and close directly.
bool has_write_error = false;
/* flag: quit adbd when both ends close the
* local service socket
*/
int exit_on_close = 0;
// End Local socket fields
// the asocket we are connected to
asocket* peer = nullptr;
/* enqueue is called by our peer when it has data
* for us. It should return 0 if we can accept more
* data or 1 if not. If we return 1, we must call
* peer->ready() when we once again are ready to
* receive data.
*/
int (*enqueue)(asocket* s, apacket::payload_type data) = nullptr;
/* ready is called by the peer when it is ready for
* us to send data via enqueue again
*/
void (*ready)(asocket* s) = nullptr;
/* shutdown is called by the peer before it goes away.
* the socket should not do any further calls on its peer.
* Always followed by a call to close. Optional, i.e. can be NULL.
*/
void (*shutdown)(asocket* s) = nullptr;
/* close is called by the peer when it has gone away.
* we are not allowed to make any further calls on the
* peer once our close method is called.
*/
void (*close)(asocket* s) = nullptr;
/* A socket is bound to atransport */
atransport* transport = nullptr;
size_t get_max_payload() const;
// TODO: Make asocket an actual class and use inheritance instead of having an ever-growing
// struct with random use-specific fields stuffed into it.
// Start Local socket fields
fdevent* fde = nullptr;
int fd = -1;
// Queue of data that we've received from our peer, and are waiting to write into fd.
IOVector packet_queue;
// End Local socket fields
// The number of bytes that have been acknowledged by the other end if delayed_ack is available.
// This value can go negative: if we have a MAX_PAYLOAD's worth of bytes available to send,
// we'll send out a full packet.
std::optional<int64_t> available_send_bytes;
// Start Smart socket fields
// A temporary buffer used to hold a partially-read service string for smartsockets.
std::string smart_socket_data;
// End Smart socket fields
};
asocket *find_local_socket(unsigned local_id, unsigned remote_id);
void install_local_socket(asocket *s);
void remove_socket(asocket *s);
void close_all_sockets(atransport *t);
void local_socket_ack(asocket* s, std::optional<int32_t> acked_bytes);
asocket* create_local_socket(unique_fd fd);
asocket* create_local_service_socket(std::string_view destination, atransport* transport);
asocket *create_remote_socket(unsigned id, atransport *t);
void connect_to_remote(asocket* s, std::string_view destination);
#if ADB_HOST
void connect_to_smartsocket(asocket *s);
#endif
// Internal functions that are only made available here for testing purposes.
namespace internal {
#if ADB_HOST
bool parse_host_service(std::string_view* out_serial, std::string_view* out_command,
std::string_view service);
#endif
} // namespace internal
#endif // __ADB_SOCKET_H