Sockaddr.c 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. #include "util/events/libuv/UvWrapper.h"
  16. #include "benc/String.h"
  17. #include "memory/Allocator.h"
  18. #include "util/platform/Sockaddr.h"
  19. #include "util/CString.h"
  20. #include "util/Bits.h"
  21. #include "util/Hex.h"
  22. #include "util/Hash.h"
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <stddef.h>
  26. #include <stdint.h>
  27. struct Sockaddr_pvt
  28. {
  29. struct Sockaddr pub;
  30. struct sockaddr_storage ss;
  31. };
  32. struct Sockaddr_in_pvt
  33. {
  34. struct Sockaddr pub;
  35. struct sockaddr_in si;
  36. };
  37. struct Sockaddr_in6_pvt
  38. {
  39. struct Sockaddr pub;
  40. struct sockaddr_in6 si;
  41. };
  42. const struct Sockaddr* const Sockaddr_LOOPBACK_be =
  43. (const struct Sockaddr*) &((const struct Sockaddr_in_pvt) {
  44. .pub = { .addrLen = sizeof(struct Sockaddr_in_pvt) },
  45. .si = {
  46. .sin_family = AF_INET,
  47. .sin_addr = { .s_addr = 0x7f000001 }
  48. }
  49. });
  50. const struct Sockaddr* const Sockaddr_LOOPBACK_le =
  51. (const struct Sockaddr*) &((const struct Sockaddr_in_pvt) {
  52. .pub = { .addrLen = sizeof(struct Sockaddr_in_pvt) },
  53. .si = {
  54. .sin_family = AF_INET,
  55. .sin_addr = { .s_addr = 0x0100007f }
  56. }
  57. });
  58. const struct Sockaddr* const Sockaddr_LOOPBACK6 =
  59. (const struct Sockaddr*) &((const struct Sockaddr_in6_pvt) {
  60. .pub = { .addrLen = sizeof(struct Sockaddr_in6_pvt) },
  61. .si = {
  62. .sin6_family = AF_INET6,
  63. .sin6_addr = { .s6_addr = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}
  64. }
  65. });
  66. struct Sockaddr* Sockaddr_fromNative(const void* ss, int addrLen, struct Allocator* alloc)
  67. {
  68. struct Sockaddr_pvt* out = Allocator_calloc(alloc, addrLen + Sockaddr_OVERHEAD, 1);
  69. Bits_memcpy(&out->ss, ss, addrLen);
  70. out->pub.addrLen = addrLen + Sockaddr_OVERHEAD;
  71. Sockaddr_normalizeNative(&out->ss);
  72. return &out->pub;
  73. }
  74. int Sockaddr_parse(const char* str, struct Sockaddr_storage* out)
  75. {
  76. struct Sockaddr_storage unusedOut;
  77. if (!out) {
  78. out = &unusedOut;
  79. }
  80. Bits_memset(out, 0, sizeof(struct Sockaddr_storage));
  81. char* lastColon = CString_strrchr(str, ':');
  82. if (!lastColon || lastColon == CString_strchr(str, ':')) {
  83. // IPv4
  84. int port = 0;
  85. int addrLen;
  86. if (lastColon) {
  87. addrLen = (lastColon - str);
  88. port = atoi(lastColon+1);
  89. if (port > 65535 || port < 0) {
  90. return -1;
  91. }
  92. } else {
  93. addrLen = CString_strlen(str);
  94. }
  95. uint8_t addr[16] = {0};
  96. if (addrLen > 15 || addrLen < 7) {
  97. return -1;
  98. }
  99. Bits_memcpy(addr, str, addrLen);
  100. struct sockaddr_in* in = ((struct sockaddr_in*) Sockaddr_asNative(&out->addr));
  101. if (uv_inet_pton(AF_INET, (char*) addr, &in->sin_addr) != 0) {
  102. return -1;
  103. }
  104. out->addr.addrLen = sizeof(struct sockaddr_in) + Sockaddr_OVERHEAD;
  105. in->sin_port = Endian_hostToBigEndian16(port);
  106. in->sin_family = AF_INET;
  107. } else {
  108. // IPv6
  109. int port = 0;
  110. int addrLen;
  111. if (*str == '[') {
  112. str++;
  113. {
  114. char* endBracket = CString_strchr(str, ']');
  115. if (!endBracket) {
  116. return -1;
  117. }
  118. addrLen = (endBracket - str);
  119. }
  120. if (str[addrLen+1] == ':') {
  121. port = atoi(&str[addrLen+2]);
  122. if (port > 65535 || port < 0) {
  123. return -1;
  124. }
  125. }
  126. } else {
  127. addrLen = CString_strlen(str);
  128. }
  129. uint8_t addr[40] = {0};
  130. if (addrLen > 39 || addrLen < 2) {
  131. return -1;
  132. }
  133. Bits_memcpy(addr, str, addrLen);
  134. struct sockaddr_in6* in6 = (struct sockaddr_in6*) Sockaddr_asNative(&out->addr);
  135. int ret = uv_inet_pton(AF_INET6, (char*) addr, &in6->sin6_addr);
  136. if (ret != 0) {
  137. return -1;
  138. }
  139. out->addr.addrLen = sizeof(struct sockaddr_in6) + Sockaddr_OVERHEAD;
  140. in6->sin6_port = Endian_hostToBigEndian16(port);
  141. in6->sin6_family = AF_INET6;
  142. }
  143. return 0;
  144. }
  145. struct Sockaddr* Sockaddr_clone(const struct Sockaddr* addr, struct Allocator* alloc)
  146. {
  147. return Sockaddr_fromNative(Sockaddr_asNativeConst(addr),
  148. addr->addrLen - Sockaddr_OVERHEAD,
  149. alloc);
  150. }
  151. char* Sockaddr_print(struct Sockaddr* sockaddr, struct Allocator* alloc)
  152. {
  153. if (sockaddr->addrLen < (2 + Sockaddr_OVERHEAD)
  154. || sockaddr->addrLen > Sockaddr_MAXSIZE + Sockaddr_OVERHEAD) {
  155. return "invalid";
  156. }
  157. struct Sockaddr_pvt* addr = (struct Sockaddr_pvt*) sockaddr;
  158. void* inAddr;
  159. uint16_t port;
  160. switch (addr->ss.ss_family) {
  161. case AF_INET:
  162. inAddr = &((struct sockaddr_in*) &addr->ss)->sin_addr;
  163. port = Endian_bigEndianToHost16(((struct sockaddr_in*)&addr->ss)->sin_port);
  164. break;
  165. case AF_INET6:
  166. inAddr = &((struct sockaddr_in6*) &addr->ss)->sin6_addr;
  167. port = Endian_bigEndianToHost16(((struct sockaddr_in6*)&addr->ss)->sin6_port);
  168. break;
  169. default: {
  170. uint8_t buff[Sockaddr_MAXSIZE * 2 + 1] = {0};
  171. Hex_encode(buff, sizeof(buff), (uint8_t*)&addr->ss, sockaddr->addrLen);
  172. String* out = String_printf(alloc, "unknown (%s)", buff);
  173. return out->bytes;
  174. }
  175. };
  176. #define BUFF_SZ 64
  177. char printedAddr[BUFF_SZ] = {0};
  178. int ret = uv_inet_ntop(addr->ss.ss_family, inAddr, printedAddr, BUFF_SZ - 1);
  179. if (ret != 0) {
  180. return "invalid";
  181. }
  182. if (port) {
  183. int totalLength = CString_strlen(printedAddr) + CString_strlen("[]:65535") + 1;
  184. char* out = Allocator_calloc(alloc, totalLength, 1);
  185. const char* format = (addr->ss.ss_family == AF_INET6) ? "[%s]:%u" : "%s:%u";
  186. snprintf(out, totalLength, format, printedAddr, port);
  187. return out;
  188. }
  189. int totalLength = CString_strlen(printedAddr) + 1;
  190. char* out = Allocator_calloc(alloc, totalLength, 1);
  191. Bits_memcpy(out, printedAddr, totalLength);
  192. return out;
  193. }
  194. static uint16_t* getPortPtr(struct Sockaddr* sockaddr)
  195. {
  196. if (sockaddr->addrLen < (2 + Sockaddr_OVERHEAD)) {
  197. return NULL;
  198. }
  199. struct Sockaddr_pvt* sa = (struct Sockaddr_pvt*) sockaddr;
  200. switch (sa->ss.ss_family) {
  201. case AF_INET: return &((struct sockaddr_in*)&sa->ss)->sin_port;
  202. case AF_INET6: return &((struct sockaddr_in6*)&sa->ss)->sin6_port;
  203. }
  204. return NULL;
  205. }
  206. int Sockaddr_getPort(struct Sockaddr* sockaddr)
  207. {
  208. uint16_t* pp = getPortPtr(sockaddr);
  209. return (pp) ? Endian_bigEndianToHost16(*pp) : -1;
  210. }
  211. int Sockaddr_setPort(struct Sockaddr* sockaddr, uint16_t port)
  212. {
  213. uint16_t* pp = getPortPtr(sockaddr);
  214. if (pp) {
  215. *pp = Endian_hostToBigEndian16(port);
  216. return 0;
  217. }
  218. return -1;
  219. }
  220. int Sockaddr_getAddress(struct Sockaddr* sockaddr, void* addrPtr)
  221. {
  222. if (sockaddr->addrLen < (2 + Sockaddr_OVERHEAD)) {
  223. return -1;
  224. }
  225. struct Sockaddr_pvt* sa = (struct Sockaddr_pvt*) sockaddr;
  226. if (addrPtr) {
  227. void** ap = (void**) addrPtr;
  228. switch (sa->ss.ss_family) {
  229. case AF_INET: *ap = &((struct sockaddr_in*)&sa->ss)->sin_addr; break;
  230. case AF_INET6: *ap = &((struct sockaddr_in6*)&sa->ss)->sin6_addr; break;
  231. }
  232. }
  233. switch (sa->ss.ss_family) {
  234. case AF_INET: return 4;
  235. case AF_INET6: return 16;
  236. }
  237. return -1;
  238. }
  239. const int Sockaddr_AF_INET = AF_INET;
  240. const int Sockaddr_AF_INET6 = AF_INET6;
  241. int Sockaddr_getFamily(struct Sockaddr* sockaddr)
  242. {
  243. if (sockaddr->addrLen < (2 + Sockaddr_OVERHEAD)) {
  244. return -1;
  245. }
  246. struct Sockaddr_pvt* sa = (struct Sockaddr_pvt*) sockaddr;
  247. return sa->ss.ss_family;
  248. }
  249. struct Sockaddr* Sockaddr_fromBytes(const uint8_t* bytes, int addrFamily, struct Allocator* alloc)
  250. {
  251. struct sockaddr_storage ss;
  252. Bits_memset(&ss, 0, sizeof(struct sockaddr_storage));
  253. int addrLen;
  254. switch (addrFamily) {
  255. case AF_INET: {
  256. ss.ss_family = AF_INET;
  257. Bits_memcpyConst(&((struct sockaddr_in*)&ss)->sin_addr, bytes, 4);
  258. addrLen = sizeof(struct sockaddr_in);
  259. break;
  260. }
  261. case AF_INET6: {
  262. ss.ss_family = AF_INET6;
  263. Bits_memcpyConst(&((struct sockaddr_in6*)&ss)->sin6_addr, bytes, 16);
  264. addrLen = sizeof(struct sockaddr_in6);
  265. break;
  266. }
  267. default: Assert_failure("unrecognized address type [%d]", addrFamily);
  268. }
  269. struct Sockaddr_pvt* out = Allocator_calloc(alloc, addrLen + Sockaddr_OVERHEAD, 1);
  270. Bits_memcpy(&out->ss, &ss, addrLen);
  271. out->pub.addrLen = addrLen + Sockaddr_OVERHEAD;
  272. return &out->pub;
  273. }
  274. void Sockaddr_normalizeNative(void* nativeSockaddr)
  275. {
  276. #if defined(freebsd) || defined(openbsd) || defined(darwin)
  277. ((struct sockaddr*)nativeSockaddr)->sa_len = 0;
  278. #endif
  279. }
  280. struct Sockaddr* Sockaddr_fromName(char* name, struct Allocator* alloc)
  281. {
  282. struct addrinfo* servinfo;
  283. if (getaddrinfo(name, 0, NULL, &servinfo) == 0) {
  284. struct Sockaddr* adr;
  285. adr = Sockaddr_fromNative(servinfo->ai_addr, servinfo->ai_addrlen, alloc);
  286. freeaddrinfo(servinfo);
  287. return adr;
  288. }
  289. return NULL;
  290. }
  291. uint32_t Sockaddr_hash(const struct Sockaddr* addr)
  292. {
  293. return Hash_compute((uint8_t*)addr, addr->addrLen);
  294. }
  295. int Sockaddr_compare(const struct Sockaddr* a, const struct Sockaddr* b)
  296. {
  297. return Bits_memcmp(a, b, a->addrLen);
  298. }