1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "common/libs/tcp_socket/tcp_socket.h"
18 
19 #include <netinet/in.h>
20 #include <sys/socket.h>
21 #include <sys/types.h>
22 
23 #include <cerrno>
24 
25 #include <glog/logging.h>
26 
27 using cvd::ClientSocket;
28 using cvd::ServerSocket;
29 
ClientSocket(int port)30 ClientSocket::ClientSocket(int port)
31     : fd_(SharedFD::SocketLocalClient(port, SOCK_STREAM)) {}
32 
RecvAny(std::size_t length)33 cvd::Message ClientSocket::RecvAny(std::size_t length) {
34   Message buf(length);
35   auto read_count = fd_->Read(buf.data(), buf.size());
36   if (read_count < 0) {
37     read_count = 0;
38   }
39   buf.resize(read_count);
40   return buf;
41 }
42 
closed() const43 bool ClientSocket::closed() const {
44   std::lock_guard<std::mutex> guard(closed_lock_);
45   return other_side_closed_;
46 }
47 
Recv(std::size_t length)48 cvd::Message ClientSocket::Recv(std::size_t length) {
49   Message buf(length);
50   ssize_t total_read = 0;
51   while (total_read < static_cast<ssize_t>(length)) {
52     auto just_read = fd_->Read(&buf[total_read], buf.size() - total_read);
53     if (just_read <= 0) {
54       if (just_read < 0) {
55         LOG(ERROR) << "read() error: " << strerror(errno);
56       }
57       {
58         std::lock_guard<std::mutex> guard(closed_lock_);
59         other_side_closed_ = true;
60       }
61       return Message{};
62     }
63     total_read += just_read;
64   }
65   CHECK(total_read == static_cast<ssize_t>(length));
66   return buf;
67 }
68 
SendNoSignal(const uint8_t * data,std::size_t size)69 ssize_t ClientSocket::SendNoSignal(const uint8_t* data, std::size_t size) {
70   std::lock_guard<std::mutex> lock(send_lock_);
71   ssize_t written{};
72   while (written < static_cast<ssize_t>(size)) {
73     if (!fd_->IsOpen()) {
74       LOG(ERROR) << "fd_ is closed";
75     }
76     auto just_written = fd_->Send(data + written, size - written, MSG_NOSIGNAL);
77     if (just_written <= 0) {
78       LOG(INFO) << "Couldn't write to client: " << strerror(errno);
79       {
80         std::lock_guard<std::mutex> guard(closed_lock_);
81         other_side_closed_ = true;
82       }
83       return just_written;
84     }
85     written += just_written;
86   }
87   return written;
88 }
89 
SendNoSignal(const Message & message)90 ssize_t ClientSocket::SendNoSignal(const Message& message) {
91   return SendNoSignal(&message[0], message.size());
92 }
93 
ServerSocket(int port)94 ServerSocket::ServerSocket(int port)
95     : fd_{SharedFD::SocketLocalServer(port, SOCK_STREAM)} {
96   if (!fd_->IsOpen()) {
97     LOG(FATAL) << "Couldn't open streaming server on port " << port;
98   }
99 }
100 
Accept()101 ClientSocket ServerSocket::Accept() {
102   SharedFD client = SharedFD::Accept(*fd_);
103   if (!client->IsOpen()) {
104     LOG(FATAL) << "Error attemping to accept: " << strerror(errno);
105   }
106   return ClientSocket{client};
107 }
108 
AppendInNetworkByteOrder(Message * msg,const std::uint8_t b)109 void cvd::AppendInNetworkByteOrder(Message* msg, const std::uint8_t b) {
110   msg->push_back(b);
111 }
112 
AppendInNetworkByteOrder(Message * msg,const std::uint16_t s)113 void cvd::AppendInNetworkByteOrder(Message* msg, const std::uint16_t s) {
114   const std::uint16_t n = htons(s);
115   auto p = reinterpret_cast<const std::uint8_t*>(&n);
116   msg->insert(msg->end(), p, p + sizeof n);
117 }
118 
AppendInNetworkByteOrder(Message * msg,const std::uint32_t w)119 void cvd::AppendInNetworkByteOrder(Message* msg, const std::uint32_t w) {
120   const std::uint32_t n = htonl(w);
121   auto p = reinterpret_cast<const std::uint8_t*>(&n);
122   msg->insert(msg->end(), p, p + sizeof n);
123 }
124 
AppendInNetworkByteOrder(Message * msg,const std::int32_t w)125 void cvd::AppendInNetworkByteOrder(Message* msg, const std::int32_t w) {
126   std::uint32_t u{};
127   std::memcpy(&u, &w, sizeof u);
128   AppendInNetworkByteOrder(msg, u);
129 }
130 
AppendInNetworkByteOrder(Message * msg,const std::string & str)131 void cvd::AppendInNetworkByteOrder(Message* msg, const std::string& str) {
132   msg->insert(msg->end(), str.begin(), str.end());
133 }
134