int connected; /* irrelevant for listening sockets */
int writable;
int frozen; /* this causes readability notifications to be ignored */
- int frozen_readable; /* this means we missed at least one readability
- * notification while we were frozen */
int localhost_only; /* for listening sockets */
char oobdata[1];
int sending_oob;
}
}
-int sk_hostname_is_local(char *name)
+int sk_hostname_is_local(const char *name)
{
return !strcmp(name, "localhost") ||
!strcmp(name, "::1") ||
ret->writable = 1; /* to start with */
ret->sending_oob = 0;
ret->frozen = 1;
- ret->frozen_readable = 0;
ret->localhost_only = 0; /* unused, but best init anyway */
ret->pending_error = 0;
ret->oobpending = FALSE;
ret->writable = 0; /* to start with */
ret->sending_oob = 0;
ret->frozen = 0;
- ret->frozen_readable = 0;
ret->localhost_only = 0; /* unused, but best init anyway */
ret->pending_error = 0;
ret->parent = ret->child = NULL;
ret->writable = 0; /* to start with */
ret->sending_oob = 0;
ret->frozen = 0;
- ret->frozen_readable = 0;
ret->localhost_only = local_host_only;
ret->pending_error = 0;
ret->parent = ret->child = NULL;
return buf;
}
+/*
+ * Deal with socket errors detected in try_send().
+ */
+static void socket_error_callback(void *vs)
+{
+ Actual_Socket s = (Actual_Socket)vs;
+
+ /*
+ * Just in case other socket work has caused this socket to vanish
+ * or become somehow non-erroneous before this callback arrived...
+ */
+ if (!find234(sktree, s, NULL) || !s->pending_error)
+ return;
+
+ /*
+ * An error has occurred on this socket. Pass it to the plug.
+ */
+ plug_closing(s->plug, strerror(s->pending_error), s->pending_error, 0);
+}
+
/*
* The function which tries to send on a socket once it's deemed
* writable.
*/
uxsel_tell(s);
/*
- * Notify the front end that it might want to call us.
+ * Arrange to be called back from the top level to
+ * deal with the error condition on this socket.
*/
- frontend_net_error_pending();
+ queue_toplevel_callback(socket_error_callback, s);
return;
}
} else {
*/
/* In the case the socket is still frozen, we don't even bother */
- if (s->frozen) {
- s->frozen_readable = 1;
+ if (s->frozen)
break;
- }
/*
* We have received data on the socket. For an oobinline
return 1;
}
-/*
- * Deal with socket errors detected in try_send().
- */
-void net_pending_errors(void)
-{
- int i;
- Actual_Socket s;
-
- /*
- * This might be a fiddly business, because it's just possible
- * that handling a pending error on one socket might cause
- * others to be closed. (I can't think of any reason this might
- * happen in current SSH implementation, but to maintain
- * generality of this network layer I'll assume the worst.)
- *
- * So what we'll do is search the socket list for _one_ socket
- * with a pending error, and then handle it, and then search
- * the list again _from the beginning_. Repeat until we make a
- * pass with no socket errors present. That way we are
- * protected against the socket list changing under our feet.
- */
-
- do {
- for (i = 0; (s = index234(sktree, i)) != NULL; i++) {
- if (s->pending_error) {
- /*
- * An error has occurred on this socket. Pass it to the
- * plug.
- */
- plug_closing(s->plug, strerror(s->pending_error),
- s->pending_error, 0);
- break;
- }
- }
- } while (s);
-}
-
/*
* Each socket abstraction contains a `void *' private field in
* which the client can keep state.
if (s->frozen == is_frozen)
return;
s->frozen = is_frozen;
- if (!is_frozen && s->frozen_readable) {
- char c;
- recv(s->s, &c, 1, MSG_PEEK);
- }
- s->frozen_readable = 0;
uxsel_tell(s);
}