UDPInterface.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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 "exception/Except.h"
  16. #include "interface/Interface.h"
  17. #include "interface/MultiInterface.h"
  18. #include "interface/UDPInterface.h"
  19. #include "interface/addressable/UDPAddrInterface.h"
  20. #include "interface/UDPInterface_pvt.h"
  21. #include "memory/Allocator.h"
  22. #include "interface/InterfaceController.h"
  23. #include "util/platform/Sockaddr.h"
  24. #include "wire/Message.h"
  25. int UDPInterface_beginConnection(const char* address,
  26. uint8_t cryptoKey[32],
  27. String* password,
  28. struct UDPInterface* udp)
  29. {
  30. struct UDPInterface_pvt* udpif = (struct UDPInterface_pvt*) udp;
  31. struct Sockaddr_storage ss;
  32. if (Sockaddr_parse(address, &ss)) {
  33. return UDPInterface_beginConnection_BAD_ADDRESS;
  34. }
  35. if (Sockaddr_getFamily(&ss.addr) != Sockaddr_getFamily(udp->addr)) {
  36. return UDPInterface_beginConnection_ADDRESS_MISMATCH;
  37. }
  38. struct Sockaddr* addr = &ss.addr;
  39. char* addrPtr = NULL;
  40. int addrLen = Sockaddr_getAddress(&ss.addr, &addrPtr);
  41. Assert_true(addrLen > 0);
  42. struct Allocator* tempAlloc = Allocator_child(udpif->alloc);
  43. if (Bits_isZero(addrPtr, addrLen)) {
  44. // unspec'd address, convert to loopback
  45. if (Sockaddr_getFamily(addr) == Sockaddr_AF_INET) {
  46. addr = Sockaddr_clone(Sockaddr_LOOPBACK, tempAlloc);
  47. } else if (Sockaddr_getFamily(addr) == Sockaddr_AF_INET6) {
  48. addr = Sockaddr_clone(Sockaddr_LOOPBACK6, tempAlloc);
  49. } else {
  50. Assert_failure("Sockaddr which is not AF_INET nor AF_INET6");
  51. }
  52. Sockaddr_setPort(addr, Sockaddr_getPort(&ss.addr));
  53. }
  54. struct Interface* iface = MultiInterface_ifaceForKey(udpif->multiIface, addr);
  55. int ret = InterfaceController_registerPeer(udpif->ic, cryptoKey, password, false, false, iface);
  56. Allocator_free(tempAlloc);
  57. if (ret) {
  58. Allocator_free(iface->allocator);
  59. switch(ret) {
  60. case InterfaceController_registerPeer_BAD_KEY:
  61. return UDPInterface_beginConnection_BAD_KEY;
  62. case InterfaceController_registerPeer_OUT_OF_SPACE:
  63. return UDPInterface_beginConnection_OUT_OF_SPACE;
  64. default:
  65. return UDPInterface_beginConnection_UNKNOWN_ERROR;
  66. }
  67. }
  68. return 0;
  69. }
  70. struct UDPInterface* UDPInterface_new(struct EventBase* base,
  71. struct Sockaddr* bindAddr,
  72. struct Allocator* allocator,
  73. struct Except* exHandler,
  74. struct Log* logger,
  75. struct InterfaceController* ic)
  76. {
  77. struct AddrInterface* udpBase =
  78. UDPAddrInterface_new(base, bindAddr, allocator, exHandler, logger);
  79. struct UDPInterface_pvt* context = Allocator_malloc(allocator, sizeof(struct UDPInterface_pvt));
  80. Bits_memcpyConst(context, (&(struct UDPInterface_pvt) {
  81. .pub = {
  82. .addr = udpBase->addr
  83. },
  84. .udpBase = udpBase,
  85. .logger = logger,
  86. .ic = ic,
  87. .alloc = allocator
  88. }), sizeof(struct UDPInterface_pvt));
  89. context->multiIface =
  90. MultiInterface_new(context->pub.addr->addrLen, &udpBase->generic, ic, logger);
  91. return &context->pub;
  92. }