// ensure that the socket is in a good state.
#define ENSURE_HEALTH(retval) \
- if (!_was_connected) return retval; /* never has been. */ \
+ if (!was_connected()) return retval; /* never has been. */ \
if (!_socket) { RECOGNIZE_DISCO; return retval; /* not set. */ }
#define CHECK_BOGUS(retval) \
spocket::~spocket()
{
-#ifdef DEBUG_SPOCKET
FUNCDEF("destructor");
+#ifdef DEBUG_SPOCKET
LOG(a_sprintf("closing spocket: ") + text_form());
#endif
disconnect();
// ints and since _where currently does not get destroyed.
astring spocket::text_form()
{
- a_sprintf sock_string("socket=%d", _socket);
- if (is_root_server())
- sock_string += a_sprintf("root-socket=%d", _server_socket);
-
- return a_sprintf("%s spocket: %s, %s, %s",
- (is_client()? "client" :
- (is_root_server()? "root-server" : "server") ),
- (connected()? "connected" :
- (was_connected()? "unconnected (was once)" : "never-connected") ),
- sock_string.s(),
- _where->text_form().s());
+ FUNCDEF("text_form");
+ astring to_return = is_client()? "client" :
+ (is_root_server()? "root-server" : "server");
+ to_return += " spocket: ";
+ if (connected()) {
+ to_return += "connected, ";
+ } else {
+ if (was_connected()) to_return += "unconnected (was once), ";
+ else to_return += "never-connected, ";
+ }
+ to_return += a_sprintf("socket=%u, ", _socket);
+ if (is_root_server()) {
+ to_return += a_sprintf("root-socket=%u, ", _server_socket);
+ }
+ to_return += _where->text_form().s();
+ return to_return;
}
void spocket::bind_client(const internet_address &addr)
outcome spocket::disconnect()
{
-#ifdef DEBUG_SPOCKET
FUNCDEF("disconnect");
-#endif
RECOGNIZE_DISCO;
if (_socket) {
#ifdef DEBUG_SPOCKET
bool spocket::connected()
{
-#ifdef DEBUG_SPOCKET
FUNCDEF("connected");
-#endif
ENSURE_HEALTH(false);
- if (_type != CONNECTED) return _was_connected;
+ if (_type != CONNECTED) return was_connected();
+
+ if (!_socket) return false;
// do examination on spocket.
int sel_mode = 0;
GRAB_LOCK;
- int ret = _socks->select(_socket, sel_mode);
- if (ret == 0) {
- return true; // we are happy.
- }
- if ( (ret & SI_DISCONNECTED) || (ret & SI_ERRONEOUS) ) {
- RECOGNIZE_DISCO;
+ try {
+ int ret = _socks->select(_socket, sel_mode);
+ if (ret == 0) {
+ return true; // we are happy.
+ }
+ if ( (ret & SI_DISCONNECTED) || (ret & SI_ERRONEOUS) ) {
+ RECOGNIZE_DISCO;
+ return false;
+ }
+ return true;
+ } catch (...) {
+ LOG("caught exception thrown from select, returning false.");
return false;
}
- return true;
}
outcome spocket::await_readable(int timeout)
{
-#ifdef DEBUG_SPOCKET
FUNCDEF("await_readable");
-#endif
CHECK_BOGUS(NO_CONNECTION);
ENSURE_HEALTH(NO_CONNECTION);
GRAB_LOCK;
outcome spocket::await_writable(int timeout)
{
-#ifdef DEBUG_SPOCKET
FUNCDEF("await_writable");
-#endif
CHECK_BOGUS(NO_CONNECTION);
ENSURE_HEALTH(NO_CONNECTION);
GRAB_LOCK;
CHECK_BOGUS(NO_CONNECTION);
{
GRAB_LOCK; // short lock.
- if ( (_was_connected && !_client) || _server_socket) {
+ if ( (was_connected() && !_client) || _server_socket) {
#ifdef DEBUG_SPOCKET
LOG("this object was already opened as a server!");
#endif
}
_socket = int(::socket(AF_INET, sock_type, proto));
if ( (_socket == basis::un_int(INVALID_SOCKET)) || !_socket) {
- _socket = NIL;
+ _socket = 0;
LOG("Failed to open the client's connecting spocket.");
return ACCESS_DENIED;
}
//moving to always re-resolving before a connect. otherwise we have somewhat
//hard to predict behavior about when the re-resolve will happen.
) {
- // we know we need to resolve if the address is NIL or if the re-resolve
+ // we know we need to resolve if the address is NULL_POINTER or if the re-resolve
// interval has elapsed.
astring full_host;
byte_array ip_addr = _stack->full_resolve(_where->hostname, full_host);
// we don't lock in here; we should not be locking on the server socket.
- sock = NIL; // reset.
+ sock = NULL_POINTER; // reset.
if (_socket) {
#ifdef DEBUG_SPOCKET
_server_socket = int(::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
#ifdef DEBUG_SPOCKET
LOG(a_sprintf("srv sock is %d", _server_socket));
-#endif
-
-#ifdef DEBUG_SPOCKET
LOG(astring("creating server socket now for ") + _where->text_form());
#endif
// now try accepting a connection on the spocket.
sockaddr new_sock;
socklen_t sock_len = sizeof(new_sock);
- int accepted = int(::accept(_server_socket, &new_sock, &sock_len));
+ basis::un_int accepted = int(::accept(_server_socket, &new_sock, &sock_len));
int error = critical_events::system_error();
- if (accepted == INVALID_SOCKET) {
+ if (!accepted || (accepted == INVALID_SOCKET)) {
if (error == SOCK_EWOULDBLOCK) return NO_CONNECTION;
#ifdef DEBUG_SPOCKET
LOG(astring("Accept got no client, with an error of ")
#endif
}
- // create the spocket address that we will connect to.
#ifdef DEBUG_SPOCKET
- LOG(astring("accepted a client socket for ") + _where->text_form());
+ LOG(astring("accepted a client on our socket: ") + _where->text_form());
#endif
// NOTE: normally, our network code sets the spocket to be kept alive (using
// keep alives), but we are trying to have a minimal spocket usage and
// a minimal network load for this test scenario.
+ // create the spocket address that we will connect to.
sock = new spocket(*_where);
*sock->_remote = _stack->convert(new_sock);
sock->_socket = accepted;
outcome spocket::send(const abyte *buffer, int size, int &len_sent)
{
-#ifdef DEBUG_SPOCKET
FUNCDEF("send");
-#endif
CHECK_BOGUS(OKAY);
if (_type != CONNECTED) return BAD_INPUT;
GRAB_LOCK;
outcome spocket::receive(byte_array &buffer, int &size)
{
-#ifdef DEBUG_SPOCKET
FUNCDEF("receive");
-#endif
CHECK_BOGUS(NONE_READY);
if (_type != CONNECTED) return BAD_INPUT;
if (size <= 0) return BAD_INPUT;
outcome spocket::receive(abyte *buffer, int &size)
{
-#ifdef DEBUG_SPOCKET
FUNCDEF("receive");
-#endif
CHECK_BOGUS(NONE_READY);
if (_type != CONNECTED) return BAD_INPUT;
ENSURE_HEALTH(NO_CONNECTION);
outcome spocket::receive_from(byte_array &buffer, int &size,
internet_address &where_from)
{
-#ifdef DEBUG_SPOCKET
FUNCDEF("receive_from");
-#endif
where_from = internet_address();
CHECK_BOGUS(NONE_READY);
if (_type == CONNECTED) return BAD_INPUT;
outcome spocket::receive_from(abyte *buffer, int &size,
internet_address &where_from)
{
-#ifdef DEBUG_SPOCKET
FUNCDEF("receive_from");
-#endif
where_from = internet_address();
CHECK_BOGUS(NONE_READY);
if (_type == CONNECTED) return BAD_INPUT;