Better error-message when bind fails.

See #26790.

R=sgjesse@google.com

Committed: 34aed6a08b

Reverted: a1005bad7e

Committed: 8c4954492f

Reverted: 5ebcd3cda0

Committed: eaeb260244

Review URL: https://codereview.chromium.org/2205913003 .

Reverted: 90a194be3c
This commit is contained in:
Florian Loitsch 2016-08-04 14:45:01 +02:00
parent 5948909120
commit ef4933df25
12 changed files with 61 additions and 2 deletions

View file

@ -1,5 +1,10 @@
## 1.19.0
### Core library changes
* `dart:io`
* Report a better error when a bind fails because of a bad source address.
### Tool Changes
* `dartfmt` - upgraded to v0.2.9

View file

@ -121,6 +121,7 @@ namespace bin {
V(Socket_CreateConnect, 3) \
V(Socket_CreateBindConnect, 4) \
V(Socket_CreateBindDatagram, 4) \
V(Socket_IsBindError, 2) \
V(Socket_Available, 1) \
V(Socket_Read, 2) \
V(Socket_RecvFrom, 1) \

View file

@ -234,6 +234,12 @@ void FUNCTION_NAME(Socket_CreateBindConnect)(Dart_NativeArguments args) {
}
}
void FUNCTION_NAME(Socket_IsBindError)(Dart_NativeArguments args) {
intptr_t error_number =
DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 1));
bool is_bind_error = Socket::IsBindError(error_number);
Dart_SetReturnValue(args, is_bind_error ? Dart_True() : Dart_False());
}
void FUNCTION_NAME(Socket_CreateBindDatagram)(Dart_NativeArguments args) {
RawAddr addr;

View file

@ -278,6 +278,9 @@ class Socket {
// specified as the port component of the passed RawAddr structure.
static intptr_t CreateBindConnect(const RawAddr& addr,
const RawAddr& source_addr);
// Returns true if the given error-number is because the system was not able
// to bind the socket to a specific IP.
static bool IsBindError(intptr_t error_number);
// Creates a datagram socket which is bound. The port to bind
// to is specified as the port component of the RawAddr structure.
static intptr_t CreateBindDatagram(const RawAddr& addr, bool reuseAddress);

View file

@ -101,6 +101,12 @@ intptr_t Socket::CreateBindConnect(const RawAddr& addr,
}
bool Socket::IsBindError(intptr_t error_number) {
return error_number == EADDRINUSE || error_number == EADDRNOTAVAIL ||
error_number == EINVAL;
}
intptr_t Socket::Available(intptr_t fd) {
return FDUtils::AvailableBytes(fd);
}

View file

@ -45,6 +45,12 @@ intptr_t Socket::CreateBindConnect(const RawAddr& addr,
}
bool Socket::IsBindError(intptr_t error_number) {
UNIMPLEMENTED();
return false;
}
intptr_t Socket::Available(intptr_t fd) {
UNIMPLEMENTED();
return -1;

View file

@ -101,6 +101,12 @@ intptr_t Socket::CreateBindConnect(const RawAddr& addr,
}
bool Socket::IsBindError(intptr_t error_number) {
return error_number == EADDRINUSE || error_number == EADDRNOTAVAIL ||
error_number == EINVAL;
}
intptr_t Socket::Available(intptr_t fd) {
return FDUtils::AvailableBytes(fd);
}

View file

@ -103,6 +103,12 @@ intptr_t Socket::CreateBindConnect(const RawAddr& addr,
}
bool Socket::IsBindError(intptr_t error_number) {
return error_number == EADDRINUSE || error_number == EADDRNOTAVAIL ||
error_number == EINVAL;
}
intptr_t Socket::Available(intptr_t fd) {
return FDUtils::AvailableBytes(fd);
}

View file

@ -431,7 +431,13 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject {
if (result is OSError) {
// Keep first error, if present.
if (error == null) {
error = createError(result, "Connection failed", address, port);
int errorCode = result.errorCode;
if (errorCode != null && socket.isBindError(errorCode)) {
error = createError(result, "Bind failed", sourceAddress);
} else {
error =
createError(result, "Connection failed", address, port);
}
}
connectNext();
} else {
@ -1075,6 +1081,7 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject {
nativeCreateBindConnect(
List<int> addr, int port, List<int> sourceAddr)
native "Socket_CreateBindConnect";
bool isBindError(int errorNumber) native "Socket_IsBindError";
nativeCreateBindListen(List<int> addr, int port, int backlog, bool v6Only,
bool shared)
native "ServerSocket_CreateBindListen";

View file

@ -35,6 +35,12 @@ void FUNCTION_NAME(Socket_CreateBindConnect)(Dart_NativeArguments args) {
}
void FUNCTION_NAME(Socket_IsBindError)(Dart_NativeArguments args) {
Dart_ThrowException(DartUtils::NewDartArgumentError(
"Sockets unsupported on this platform"));
}
void FUNCTION_NAME(Socket_CreateBindDatagram)(Dart_NativeArguments args) {
Dart_ThrowException(DartUtils::NewDartArgumentError(
"Sockets unsupported on this platform"));

View file

@ -250,6 +250,12 @@ intptr_t Socket::CreateBindConnect(const RawAddr& addr,
}
bool Socket::IsBindError(intptr_t error_number) {
return error_number == WSAEADDRINUSE || error_number == WSAEADDRNOTAVAIL ||
error_number == WSAEINVAL;
}
void Socket::GetError(intptr_t fd, OSError* os_error) {
Handle* handle = reinterpret_cast<Handle*>(fd);
os_error->SetCodeAndMessage(OSError::kSystem, handle->last_error());

View file

@ -43,7 +43,8 @@ Future testArguments(connectFunction) async {
await throws(() => connectFunction('127.0.0.1',
server.port,
sourceAddress: sourceAddress),
(e) => e is SocketException);
(e) => e is SocketException &&
e.address == new InternetAddress('8.8.8.8'));
}
// Address family mismatch.
for (sourceAddress in ['::1', InternetAddress.LOOPBACK_IP_V6]) {