src/Network/Socket.cc
author terom
Wed, 17 Dec 2008 00:40:22 +0000
changeset 381 9b35bc329d23
parent 380 d193dd1d8a7e
child 385 e56af22c04dd
permissions -rw-r--r--
separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
187
f41f894213ca restructure network code a bit
terom
parents:
diff changeset
     1
f41f894213ca restructure network code a bit
terom
parents:
diff changeset
     2
#include "Socket.hh"
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
     3
#include "../Engine.hh"
187
f41f894213ca restructure network code a bit
terom
parents:
diff changeset
     4
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
     5
#include <cerrno>
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
     6
#include <cstring>
187
f41f894213ca restructure network code a bit
terom
parents:
diff changeset
     7
#include <sstream>
f41f894213ca restructure network code a bit
terom
parents:
diff changeset
     8
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
     9
static std::string dump_addrinfo (addrinfo *r) {
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    10
    std::stringstream ss;
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    11
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    12
    ss << "ai_family=" << r->ai_family << ", ai_canonname=" << r->ai_canonname << ": " << strerror(errno);
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    13
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    14
    return ss.str();
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    15
}
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    16
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    17
static std::string dump_errno (void) {
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    18
    return std::string(strerror(errno));
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    19
}
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    20
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    21
NetworkSocket::NetworkSocket (int family, int socktype, int protocol, NetworkReactor *reactor) :
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    22
    sock_type(family, socktype, protocol), fd(-1), type(family, socktype, protocol), registered(0), reactor(reactor ? reactor : NetworkReactor::current)
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    23
{
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    24
    reset();
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    25
}
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    26
        
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    27
NetworkSocket::NetworkSocket (int fd, socket_type type, NetworkReactor *reactor) :
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    28
    sock_type(type), fd(fd), type(type), registered(0), reactor(reactor ? reactor : NetworkReactor::current)
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    29
{
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    30
    reset();
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    31
}
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    32
        
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    33
NetworkSocket::~NetworkSocket (void) {
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    34
    // close any remaining socket
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    35
    if (fd >= 0)
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    36
        force_close();
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    37
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    38
    // unregister from reactor?
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    39
    if (registered)
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    40
        reactor->remove_socket(this);
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    41
}
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    42
        
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    43
void NetworkSocket::reset (void) {
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    44
    bound = false;
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    45
    want_read = false;
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    46
    want_write = false;
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    47
}
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    48
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    49
void NetworkSocket::lazy_socket (int family, int socktype, int protocol) {
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    50
    // if we already have a socket, exit
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    51
    if (fd >= 0)
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    52
        return;
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    53
    
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    54
    // ignore if we've requested a specific sock_type
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    55
    if (
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    56
        (sock_type.family && family != sock_type.family) || 
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    57
        (sock_type.socktype && socktype != sock_type.socktype) || 
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    58
        (sock_type.protocol && protocol != sock_type.protocol)
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    59
    )
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    60
        throw NetworkSocketError(*this, "socket.create", "family/socktype/protocol mismatch");
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    61
    
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    62
    // create the socket or fail
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    63
    if ((fd = ::socket(family, socktype, protocol)) < 0)
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    64
        throw NetworkSocketErrno(*this, "socket");
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    65
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    66
    // update our family/type/protocol
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    67
    type.family = family;
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    68
    type.socktype = socktype;
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    69
    type.protocol = protocol;
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    70
}
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    71
        
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    72
void NetworkSocket::force_close (void) {
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    73
    // use closesocket
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    74
    if (::closesocket(fd))
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    75
        Engine::log(WARN, "socket.force_close") << "error closing socket: " << dump_errno();
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    76
    
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    77
    // reset state
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    78
    fd = -1;
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    79
    reset();
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    80
}
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    81
381
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
    82
void NetworkSocket::bind (const NetworkEndpoint &addr) {
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    83
    // get our addrinfo
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    84
    addrinfo *r, *results = addr.get_addrinfo(type.family, type.socktype, type.protocol, AI_PASSIVE);
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    85
    
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    86
    // find the right address to bind to
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    87
    for (r = results; r; r = r->ai_next) {
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    88
        // create socket if needed, warn on errors
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    89
        try {
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    90
            lazy_socket(r->ai_family, r->ai_socktype, r->ai_protocol);
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    91
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    92
        } catch (NetworkSocketError &e) {
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    93
            Engine::log(WARN, "socket.bind") << "unable to create socket for " << dump_addrinfo(r) << ": " << e.what();
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    94
            continue;
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    95
        }
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    96
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    97
        // bind it, warn on errors
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
    98
        if (::bind(fd, r->ai_addr, r->ai_addrlen)) {
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
    99
            Engine::log(WARN, "socket.bind") << "unable to bind on " << dump_addrinfo(r) << ": " << dump_errno();
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   100
            
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   101
            // close the bad socket
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   102
            force_close();
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   103
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   104
            continue;
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   105
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   106
        } else {
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   107
            // we have a bound socket, break
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   108
            break;
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   109
        }
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   110
    }
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   111
   
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   112
    // release our addrinfo
381
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
   113
    addr.free_addrinfo(results);
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   114
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   115
    // if we failed to bind, r is a NULL pointer
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   116
    if (r == NULL)
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   117
        throw NetworkSocketError(*this, "bind", "unable to bind on any addresses");
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   118
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   119
    // mark ourselves as bound
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   120
    bound = true;
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   121
}
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   122
        
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   123
void NetworkSocket::listen (int backlog) {
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   124
    // just call listen
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   125
    if (::listen(fd, backlog))
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   126
        throw NetworkSocketErrno(*this, "listen");
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   127
}
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   128
        
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   129
NetworkAddress NetworkSocket::get_local_address (void) {
381
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
   130
    NetworkAddress addr;
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   131
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   132
    // do getsockname()
381
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
   133
    if (::getsockname(fd, addr.get_sockaddr(), addr.get_socklen_ptr()))
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   134
        throw NetworkSocketErrno(*this, "getsockname");
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   135
381
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
   136
    // update
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
   137
    addr.update();
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
   138
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   139
    // return addr
381
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
   140
    return addr;
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   141
}
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   142
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   143
NetworkAddress NetworkSocket::get_remote_address (void) {
381
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
   144
    NetworkAddress addr;
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   145
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   146
    // do getpeername()
381
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
   147
    if (::getpeername(fd, addr.get_sockaddr(), addr.get_socklen_ptr()))
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   148
        throw NetworkSocketErrno(*this, "getpeername");
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   149
381
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
   150
    // update
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
   151
    addr.update();
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
   152
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   153
    // return addr
381
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
   154
    return addr;
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   155
}
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   156
        
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   157
void NetworkSocket::set_nonblocking (bool nonblocking) {
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   158
    // linux-specific
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   159
    if (fcntl(fd, F_SETFL, O_NONBLOCK, nonblocking ? 1 : 0) == -1)
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   160
        throw NetworkSocketErrno(*this, "fcntl(F_SETFL, O_NONBLOCK)");
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   161
}
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   162
 
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   163
NetworkSocket* NetworkSocket::accept (NetworkAddress *src) {
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   164
    int new_fd;
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   165
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   166
    // try and get the FD
381
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
   167
    // pass src sock* pointers if provided
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
   168
    if ((new_fd = ::accept(
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
   169
            fd, 
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
   170
            src ? src->get_sockaddr() : NULL,
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
   171
            src ? src->get_socklen_ptr() : NULL
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
   172
    )) < 0)
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   173
        throw NetworkSocketErrno(*this, "accept");
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   174
    
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   175
    // allocate new NetworkSocket for new_fd
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   176
    NetworkSocket *socket = new NetworkSocket(new_fd, type, reactor);
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   177
    
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   178
    // update src
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   179
    if (src)
381
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
   180
        src->update();
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   181
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   182
    // done
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   183
    return socket;
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   184
}
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   185
        
381
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
   186
void NetworkSocket::connect (const NetworkEndpoint &addr) {
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   187
    // get our addrinfo
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   188
    addrinfo *r, *results = addr.get_addrinfo(type.family, type.socktype, type.protocol);
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   189
    
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   190
    // find the right address to bind to
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   191
    for (r = results; r; r = r->ai_next) {
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   192
        // create socket if needed, warn on errors
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   193
        try {
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   194
            lazy_socket(r->ai_family, r->ai_socktype, r->ai_protocol);
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   195
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   196
        } catch (NetworkSocketError &e) {
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   197
            Engine::log(WARN, "socket.connect") << "unable to create socket for " << dump_addrinfo(r) << ": " << e.what();
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   198
            continue;
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   199
        }
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   200
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   201
        // connect it, warn on errors
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   202
        if (::connect(fd, r->ai_addr, r->ai_addrlen)) {
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   203
            Engine::log(WARN, "socket.connect") << "unable to connect to " << dump_addrinfo(r) << ": " << dump_errno();
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   204
            
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   205
            // close unless bound, to not keep invalid sockets hanging around
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   206
            if (!bound)
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   207
                force_close();
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   208
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   209
            continue;
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   210
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   211
        } else {
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   212
            // we have a connected socket, break
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   213
            break;
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   214
        }
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   215
    }
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   216
   
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   217
    // release our addrinfo
381
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
   218
    addr.free_addrinfo(results);
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   219
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   220
    // if we failed to connect, r is a NULL pointer
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   221
    if (r == NULL)
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   222
        throw NetworkSocketError(*this, "connect", "unable to connect to any addresses");
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   223
}
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   224
        
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   225
size_t NetworkSocket::send (const char *buf, size_t size, const NetworkAddress *dest) {
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   226
    ssize_t ret;
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   227
    
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   228
    // use send or sendto?
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   229
    if (dest) {
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   230
        // sendto()
381
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
   231
        if ((ret = ::sendto(fd, buf, size, 0, dest->get_sockaddr(), dest->get_socklen())) < 0 && errno != EAGAIN)
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   232
            throw NetworkSocketErrno(*this, "sendto");
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   233
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   234
    } else {
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   235
        // send()
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   236
        if ((ret = ::send(fd, buf, size, 0)) < 0 && errno != EAGAIN)
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   237
            throw NetworkSocketErrno(*this, "send");
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   238
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   239
    }
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   240
    
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   241
    // sanity-check
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   242
    if (ret == 0) {
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   243
        // XXX: not sure what this means...
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   244
        Engine::log(ERROR, "socket.send") << "send[to] returned zero, trying again...";
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   245
        return 0;
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   246
    }
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   247
    
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   248
    // EAGAIN? 
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   249
    if (ret < 0) {
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   250
        // set want_write so we get a sig_write
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   251
        want_write = true;
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   252
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   253
        return 0;
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   254
    }
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   255
    
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   256
    // return number of bytes sent
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   257
    return ret;
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   258
}
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   259
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   260
size_t NetworkSocket::recv (char *buf, size_t size, NetworkAddress *src) {
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   261
    ssize_t ret;
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   262
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   263
    // use recv or recvfrom?
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   264
    if (src) {
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   265
        // recvfrom()
381
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
   266
        if ((ret = ::recvfrom(fd, buf, size, 0, src->get_sockaddr(), src->get_socklen_ptr())) < 0 && errno != EAGAIN)
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   267
            throw NetworkSocketErrno(*this, "recvfrom");
381
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
   268
        
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
   269
        // update if valid
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
   270
        if (ret > 0)
9b35bc329d23 separate sockaddr stuff out of NetworkAddress... now called NetworkEndpoint
terom
parents: 380
diff changeset
   271
            src->update();
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   272
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   273
    } else {
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   274
        // recv
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   275
        if ((ret = ::recv(fd, buf, size, 0)) < 0 && errno != EAGAIN)
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   276
            throw NetworkSocketErrno(*this, "recv");
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   277
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   278
    }
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   279
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   280
    // EOF?
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   281
    if (ret == 0)
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   282
        throw NetworkSocketEOFError(*this, "recv");
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   283
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   284
    // EAGAIN?
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   285
    if (ret < 0)
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   286
        return 0;
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   287
    
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   288
    // return number of bytes received
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   289
    return ret;
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   290
}
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   291
        
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   292
void NetworkSocket::close (void) {
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   293
    // use closesocket
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   294
    if (::closesocket(fd))
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   295
        throw NetworkSocketErrno(*this, "close");
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   296
    
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   297
    // reset
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   298
    fd = -1;
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   299
    reset();
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   300
}
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 187
diff changeset
   301
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   302
void NetworkSocket::register_poll (void) { 
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   303
    if (registered) return; 
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   304
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   305
    reactor->add_socket(this); 
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   306
    registered = true; 
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   307
}
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   308
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   309
/*
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   310
 * NetworkSocketError
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   311
 */
187
f41f894213ca restructure network code a bit
terom
parents:
diff changeset
   312
std::string NetworkSocketError::build_str (const NetworkSocket &socket, const char *op, const char *err) {
f41f894213ca restructure network code a bit
terom
parents:
diff changeset
   313
    std::stringstream ss;
f41f894213ca restructure network code a bit
terom
parents:
diff changeset
   314
f41f894213ca restructure network code a bit
terom
parents:
diff changeset
   315
    ss << "socket #" << socket.get_socket() << " " << op << ": " << err;
f41f894213ca restructure network code a bit
terom
parents:
diff changeset
   316
f41f894213ca restructure network code a bit
terom
parents:
diff changeset
   317
    return ss.str();
f41f894213ca restructure network code a bit
terom
parents:
diff changeset
   318
}
f41f894213ca restructure network code a bit
terom
parents:
diff changeset
   319
f41f894213ca restructure network code a bit
terom
parents:
diff changeset
   320
NetworkSocketError::NetworkSocketError (const NetworkSocket &socket, const char *op, const char *err) :
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   321
    Error(build_str(socket, op, err)) 
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   322
{
187
f41f894213ca restructure network code a bit
terom
parents:
diff changeset
   323
    // nothing
f41f894213ca restructure network code a bit
terom
parents:
diff changeset
   324
}
f41f894213ca restructure network code a bit
terom
parents:
diff changeset
   325
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   326
NetworkSocketErrno::NetworkSocketErrno (const NetworkSocket &socket, const char *op) :
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   327
    NetworkSocketError(socket, op, strerror(errno)) 
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   328
{ 
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   329
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   330
}
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   331