diff --git a/Makefile b/Makefile index 6ac0c8ed..de7fe6ea 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,13 @@ clean: find . -type f -name '*.obj' -delete find . -type f -name '*.so' -delete find . -type f -name '*.dylib' -delete + find . -type f -name '*.dill' -delete + +%-run: % example/main.dart + dart example/main.dill + +example/main.dill: ./**/*.dart + dart --snapshot="$@" example/main.dart mac: libangel_wings.dylib diff --git a/example/main.dill b/example/main.dill new file mode 100644 index 00000000..d3327efd Binary files /dev/null and b/example/main.dill differ diff --git a/lib/src/angel_wings.cc b/lib/src/angel_wings.cc index 2b19cd6b..f0907582 100644 --- a/lib/src/angel_wings.cc +++ b/lib/src/angel_wings.cc @@ -39,6 +39,8 @@ Dart_NativeFunction ResolveName(Dart_Handle name, int argc, bool *auto_setup_sco result = Dart_WingsSocket_bindIPv4; if (strcmp("Dart_WingsSocket_bindIPv6", cname) == 0) result = Dart_WingsSocket_bindIPv6; + if (strcmp("Dart_WingsSocket_getAddress", cname) == 0) + result = Dart_WingsSocket_getAddress; if (strcmp("Dart_WingsSocket_getPort", cname) == 0) result = Dart_WingsSocket_getPort; if (strcmp("Dart_WingsSocket_write", cname) == 0) diff --git a/lib/src/angel_wings.h b/lib/src/angel_wings.h index 65397365..0901a658 100644 --- a/lib/src/angel_wings.h +++ b/lib/src/angel_wings.h @@ -8,8 +8,10 @@ Dart_NativeFunction ResolveName(Dart_Handle name, int argc, bool *auto_setup_scope); Dart_Handle HandleError(Dart_Handle handle); +void wingsThrowError(const char *msg, const char *lib = "dart:core", const char *name = "StateError", int n = -1); void Dart_WingsSocket_bindIPv4(Dart_NativeArguments arguments); void Dart_WingsSocket_bindIPv6(Dart_NativeArguments arguments); +void Dart_WingsSocket_getAddress(Dart_NativeArguments arguments); void Dart_WingsSocket_getPort(Dart_NativeArguments arguments); void Dart_WingsSocket_write(Dart_NativeArguments arguments); void Dart_WingsSocket_closeDescriptor(Dart_NativeArguments arguments); diff --git a/lib/src/bind.cc b/lib/src/bind.cc index dcd4c686..0f3e0777 100644 --- a/lib/src/bind.cc +++ b/lib/src/bind.cc @@ -1,3 +1,4 @@ +#include #include "angel_wings.h" #include "wings_socket.h" using namespace wings; @@ -10,20 +11,22 @@ WingsSocket *wingsBindNewSocket(Dart_NativeArguments arguments, const WingsSocke void wingsReturnBound(Dart_NativeArguments arguments, WingsSocket *socket); -void Dart_WingsSocket_bindIPv4(Dart_NativeArguments arguments) +void Dart_WingsSocket_bind(sa_family_t af, Dart_NativeArguments arguments) { WingsSocketInfo info; getWingsSocketInfo(arguments, &info); - WingsSocket *socket = wingsFindSocket(arguments, info, AF_INET); + WingsSocket *socket = wingsFindSocket(arguments, info, af); wingsReturnBound(arguments, socket); } +void Dart_WingsSocket_bindIPv4(Dart_NativeArguments arguments) +{ + Dart_WingsSocket_bind(AF_INET, arguments); +} + void Dart_WingsSocket_bindIPv6(Dart_NativeArguments arguments) { - WingsSocketInfo info; - getWingsSocketInfo(arguments, &info); - WingsSocket *socket = wingsFindSocket(arguments, info, AF_INET6); - wingsReturnBound(arguments, socket); + Dart_WingsSocket_bind(AF_INET6, arguments); } void wingsReturnBound(Dart_NativeArguments arguments, WingsSocket *socket) @@ -36,18 +39,6 @@ void wingsReturnBound(Dart_NativeArguments arguments, WingsSocket *socket) Dart_SetReturnValue(arguments, ptrHandle); } -void wingsThrowStateError(const char *msg) -{ - Dart_Handle msgHandle = Dart_NewStringFromCString(msg); - Dart_Handle emptyHandle = Dart_NewStringFromCString(""); - Dart_Handle stateErrorHandle = Dart_NewStringFromCString("StateError"); - Dart_Handle dartCoreHandle = Dart_NewStringFromCString("dart:core"); - Dart_Handle dartCore = Dart_LookupLibrary(dartCoreHandle); - Dart_Handle stateError = Dart_GetType(dartCore, stateErrorHandle, 0, nullptr); - Dart_Handle errHandle = Dart_New(stateError, emptyHandle, 1, &msgHandle); - Dart_ThrowException(errHandle); -} - WingsSocket *wingsFindSocket(Dart_NativeArguments arguments, const WingsSocketInfo &info, int af) { // Find an existing server, if any. @@ -76,7 +67,7 @@ WingsSocket *wingsBindNewSocket(Dart_NativeArguments arguments, const WingsSocke if (sock < 0) { - wingsThrowStateError("Failed to create socket."); + wingsThrowError("Failed to create socket."); return nullptr; } @@ -85,7 +76,7 @@ WingsSocket *wingsBindNewSocket(Dart_NativeArguments arguments, const WingsSocke if (ret < 0) { - wingsThrowStateError("Cannot reuse address for socket."); + wingsThrowError("Cannot reuse address for socket."); return nullptr; } @@ -116,23 +107,23 @@ WingsSocket *wingsBindNewSocket(Dart_NativeArguments arguments, const WingsSocke if (ret < 0) { - wingsThrowStateError("Failed to bind socket."); + wingsThrowError("Failed to bind socket."); return nullptr; } if (listen(sock, SOMAXCONN) < 0) { - wingsThrowStateError("Failed to set SOMAXCONN on bound socket."); + wingsThrowError("Failed to set SOMAXCONN on bound socket."); return nullptr; } if (listen(sock, (int)info.backlog) < 0) { - wingsThrowStateError("Failed to set backlog on bound socket."); + wingsThrowError("Failed to set backlog on bound socket."); return nullptr; } - auto *out = new WingsSocket(sock, info); + auto *out = new WingsSocket(af, sock, info); globalSocketList.push_back(out); return out; } @@ -152,3 +143,24 @@ void getWingsSocketInfo(Dart_NativeArguments arguments, WingsSocketInfo *info) HandleError(Dart_IntegerToUint64(backlogHandle, &info->backlog)); HandleError(Dart_BooleanValue(v6OnlyHandle, &info->v6Only)); } + +void wingsThrowError(const char *msg, const char *lib, const char *name, int n) +{ + Dart_Handle msgHandle = Dart_NewStringFromCString(msg); + Dart_Handle emptyHandle = Dart_NewStringFromCString(""); + Dart_Handle stateErrorHandle = Dart_NewStringFromCString(name); + Dart_Handle dartCoreHandle = Dart_NewStringFromCString(lib); + Dart_Handle dartCore = Dart_LookupLibrary(dartCoreHandle); + Dart_Handle stateError = Dart_GetType(dartCore, stateErrorHandle, 0, nullptr); + + std::vector args; + args.push_back(msgHandle); + + if (n > -1) + { + args.push_back(Dart_NewInteger(n)); + } + + Dart_Handle errHandle = Dart_New(stateError, emptyHandle, args.size(), args.data()); + Dart_ThrowException(errHandle); +} \ No newline at end of file diff --git a/lib/src/libangel_wings.dylib b/lib/src/libangel_wings.dylib index 58a946f4..14834b3a 100644 Binary files a/lib/src/libangel_wings.dylib and b/lib/src/libangel_wings.dylib differ diff --git a/lib/src/util.cc b/lib/src/util.cc index 69b6b88c..cddde688 100644 --- a/lib/src/util.cc +++ b/lib/src/util.cc @@ -1,4 +1,5 @@ #include +#include #include "angel_wings.h" #include "wings_socket.h" using namespace wings; @@ -13,15 +14,125 @@ void Dart_WingsSocket_listen(Dart_NativeArguments arguments) socket->start(arguments); } -void Dart_WingsSocket_getPort(Dart_NativeArguments arguments) +struct wingsSockName +{ + sa_family_t family; + sockaddr_in v4; + sockaddr_in6 v6; + + struct sockaddr *ptr() const + { + if (family == AF_INET6) + { + return (sockaddr *)&v6; + } + else + { + return (sockaddr *)&v4; + } + } + + void *addrPtr() const + { + if (family == AF_INET6) + { + return (void *)&v6.sin6_addr; + } + else + { + return (void *)&v4.sin_addr; + } + } + + socklen_t length() const + { + if (family == AF_INET6) + { + return sizeof(v6); + } + else + { + return sizeof(v4); + } + } +}; + +void wingsThrowOSError() +{ + wingsThrowError(strerror(errno), "dart:io", "OSError", errno); +} + +bool wingsReadSocket(Dart_NativeArguments arguments, wingsSockName *out) { uint64_t ptr; Dart_Handle pointerHandle = Dart_GetNativeArgument(arguments, 0); HandleError(Dart_IntegerToUint64(pointerHandle, &ptr)); auto *socket = (WingsSocket *)ptr; - auto outHandle = Dart_NewIntegerFromUint64(socket->getInfo().port); - Dart_SetReturnValue(arguments, outHandle); + int fd = socket->getFD(); + + socklen_t len; + out->family = socket->getFamily(); + len = out->length(); + + int result; + + // result = connect(fd, out->ptr(), len); + + // if (result < 0) + // { + // wingsThrowOSError(); + // return false; + // } + + result = getsockname(fd, out->ptr(), &len); + + if (result == -1) + { + wingsThrowOSError(); + return false; + } + + return true; +} + +void Dart_WingsSocket_getAddress(Dart_NativeArguments arguments) +{ + wingsSockName sock; + if (wingsReadSocket(arguments, &sock)) + { + char addrBuf[INET6_ADDRSTRLEN + 1] = {0}; + + auto *result = inet_ntop(sock.family, sock.addrPtr(), addrBuf, sock.length()); + + if (result == NULL) + { + wingsThrowOSError(); + } + + Dart_Handle outHandle = Dart_NewStringFromCString(addrBuf); + Dart_SetReturnValue(arguments, outHandle); + } +} + +void Dart_WingsSocket_getPort(Dart_NativeArguments arguments) +{ + wingsSockName sock; + if (wingsReadSocket(arguments, &sock)) + { + Dart_Handle outHandle; + + if (sock.family == AF_INET6) + { + outHandle = Dart_NewIntegerFromUint64(ntohs(sock.v6.sin6_port)); + } + else + { + outHandle = Dart_NewIntegerFromUint64(ntohs(sock.v4.sin_port)); + } + + Dart_SetReturnValue(arguments, outHandle); + } } void Dart_WingsSocket_write(Dart_NativeArguments arguments) diff --git a/lib/src/wings_socket.cc b/lib/src/wings_socket.cc index 35de2883..e468dad5 100644 --- a/lib/src/wings_socket.cc +++ b/lib/src/wings_socket.cc @@ -11,7 +11,8 @@ bool WingsSocketInfo::operator==(const WingsSocketInfo &other) const port == other.port; } -WingsSocket::WingsSocket(int sockfd, const WingsSocketInfo &info) : sockfd(sockfd), info(info) +WingsSocket::WingsSocket(sa_family_t family, int sockfd, const WingsSocketInfo &info) + : sockfd(sockfd), info(info), family(family) { refCount = 0; workerThread = nullptr; @@ -28,6 +29,16 @@ const WingsSocketInfo &WingsSocket::getInfo() const return info; } +int WingsSocket::getFD() const +{ + return sockfd; +} + +sa_family_t WingsSocket::getFamily() const +{ + return family; +} + void WingsSocket::start(Dart_NativeArguments arguments) { // if (workerThread == nullptr) @@ -71,12 +82,12 @@ void WingsSocket::threadCallback(Dart_Port dest_port_id, if (addr.sa_family == AF_INET6) { - auto as6 = (sockaddr_in6*) &addr; + auto as6 = (sockaddr_in6 *)&addr; inet_ntop(addr.sa_family, &(as6->sin6_addr), addrBuf, len); } else { - auto as4 = (sockaddr_in*) &addr; + auto as4 = (sockaddr_in *)&addr; inet_ntop(AF_INET, &(as4->sin_addr), addrBuf, len); } diff --git a/lib/src/wings_socket.dart b/lib/src/wings_socket.dart index 3a9a3c38..f80ca39e 100644 --- a/lib/src/wings_socket.dart +++ b/lib/src/wings_socket.dart @@ -20,6 +20,9 @@ int bindWingsIPv6ServerSocket( bool v6Only, SendPort sendPort) native 'Dart_WingsSocket_bindIPV6'; +String getWingsServerSocketAddress(int pointer) + native 'Dart_WingsSocket_getAddress'; + int getWingsServerSocketPort(int pointer) native 'Dart_WingsSocket_getPort'; void writeToNativeSocket(int fd, Uint8List data) @@ -92,14 +95,15 @@ class WingsSocket extends Stream { addr.address, port, shared, backlog, v6Only, recv.sendPort); } - return WingsSocket._(ptr, recv).._address = addr; + return WingsSocket._(ptr, recv); //.._address = addr; } catch (e) { recv.close(); rethrow; } } - InternetAddress get address => _address; + InternetAddress get address => + _address ??= InternetAddress(getWingsServerSocketAddress(_pointer)); int get port => _port ??= getWingsServerSocketPort(_pointer); diff --git a/lib/src/wings_socket.h b/lib/src/wings_socket.h index a14cddf4..f9211bc3 100644 --- a/lib/src/wings_socket.h +++ b/lib/src/wings_socket.h @@ -28,16 +28,19 @@ struct WingsSocketInfo class WingsSocket { public: - explicit WingsSocket(int sockfd, const WingsSocketInfo &info); + WingsSocket(sa_family_t family, int sockfd, const WingsSocketInfo &info); void incrRef(Dart_Port port); const WingsSocketInfo &getInfo() const; void start(Dart_NativeArguments arguments); + int getFD() const; + sa_family_t getFamily() const; private: static void threadCallback(Dart_Port dest_port_id, Dart_CObject *message); WingsSocketInfo info; int sockfd; int refCount; + sa_family_t family; std::unique_ptr workerThread; std::vector sendPorts; }; diff --git a/libangel_wings.dylib b/libangel_wings.dylib index 58a946f4..14834b3a 100644 Binary files a/libangel_wings.dylib and b/libangel_wings.dylib differ