]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
1 | /* |
2 | * Copyright (c) 2017 Uber Technologies, Inc. | |
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 | #ifndef JAEGERTRACING_TESTUTILS_TUDPTRANSPORT_H | |
18 | #define JAEGERTRACING_TESTUTILS_TUDPTRANSPORT_H | |
19 | ||
20 | #include "jaegertracing/Compilers.h" | |
21 | ||
22 | #ifdef WIN32 | |
23 | #include <winsock2.h> | |
24 | #else | |
25 | #include <sys/socket.h> | |
26 | #endif | |
27 | ||
28 | #include <thrift/transport/TVirtualTransport.h> | |
29 | ||
30 | #include "jaegertracing/utils/UDPTransporter.h" | |
31 | ||
32 | namespace jaegertracing { | |
33 | namespace testutils { | |
34 | ||
35 | class TUDPTransport | |
36 | : public apache::thrift::transport::TVirtualTransport<TUDPTransport> { | |
37 | public: | |
38 | explicit TUDPTransport(const net::IPAddress& addr) | |
39 | : _socket() | |
40 | , _serverAddr(addr) | |
41 | { | |
42 | _socket.open(AF_INET, SOCK_DGRAM); | |
43 | _socket.bind(_serverAddr); | |
44 | if (_serverAddr.port() == 0) { | |
45 | ::sockaddr_storage addrStorage; | |
46 | ::socklen_t addrLen = sizeof(addrStorage); | |
47 | const auto returnCode = | |
48 | ::getsockname(_socket.handle(), | |
49 | reinterpret_cast<::sockaddr*>(&addrStorage), | |
50 | &addrLen); | |
51 | if (returnCode == 0) { | |
52 | _serverAddr = net::IPAddress(addrStorage, addrLen); | |
53 | } | |
54 | } | |
55 | } | |
56 | ||
57 | bool isOpen() override { return _socket.handle() >= 0; } | |
58 | ||
59 | void open() override {} | |
60 | ||
61 | void close() override { _socket.close(); } | |
62 | ||
63 | net::IPAddress addr() const { return _serverAddr; } | |
64 | ||
65 | uint32_t read(uint8_t* buf, uint32_t len) | |
66 | { | |
67 | ::sockaddr_storage clientAddr; | |
68 | auto clientAddrLen = static_cast<::socklen_t>(sizeof(clientAddr)); | |
69 | const auto numRead = | |
70 | ::recvfrom(_socket.handle(), | |
71 | #ifdef WIN32 | |
72 | reinterpret_cast<char*>(buf), // this cast is safe | |
73 | #else | |
74 | buf, | |
75 | #endif | |
76 | len, | |
77 | 0, | |
78 | reinterpret_cast<::sockaddr*>(&clientAddr), | |
79 | &clientAddrLen); | |
80 | _clientAddr = net::IPAddress(clientAddr, clientAddrLen); | |
81 | // the return value conrreponds to the size of the data read from the | |
82 | // socket. upon error, recvfrom return -1. In this case, we return 0 to | |
83 | // say that noothing was read. | |
84 | return std::max<long>(0, numRead); | |
85 | } | |
86 | ||
87 | void write(const uint8_t* buf, uint32_t len) | |
88 | { | |
89 | ::sendto(_socket.handle(), | |
90 | #ifdef WIN32 | |
91 | reinterpret_cast<const char*>(buf), // this cast is safe | |
92 | #else | |
93 | buf, | |
94 | #endif | |
95 | len, | |
96 | 0, | |
97 | reinterpret_cast<const ::sockaddr*>(&_clientAddr.addr()), | |
98 | _clientAddr.addrLen()); | |
99 | } | |
100 | ||
101 | private: | |
102 | net::Socket _socket; | |
103 | net::IPAddress _serverAddr; | |
104 | net::IPAddress _clientAddr; | |
105 | ::socklen_t _clientAddrLen; | |
106 | }; | |
107 | ||
108 | } // namespace testutils | |
109 | } // namespace jaegertracing | |
110 | ||
111 | #endif // JAEGERTRACING_TESTUTILS_TUDPTRANSPORT_H |