Changeset 515 for trunk/thune/net.c

Show
Ignore:
Timestamp:
02/27/08 17:39:09 (9 months ago)
Author:
krobillard
Message:

Can now open TCP client ports.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/thune/net.c

    r510 r515  
    6262 
    6363 
     64#define ur_sockType(cell)   ((cell)->num.id._pad0) 
     65 
     66 
    6467// Values in the socket port context. 
    6568#define SV_FD       0 
     
    113116 
    114117        if( ! _makeAddrName( (struct sockaddr_in*) addr->ptr.v, 
    115                              ur_cstring(ut,hc), ur_int(tos) ) )  
     118                             ur_cstring(ut, hc), ur_int(tos) ) )  
    116119        { 
    117120            ur_throwErr( UR_ERR_SCRIPT, "gethostbyname failed" ); 
     
    169172 
    170173 
     174static int _openTcpClient( UThread* ut, struct sockaddr_in* addr ) 
     175{ 
     176    SOCKET fd; 
     177 
     178 
     179    fd = socket( PF_INET, SOCK_STREAM, 0 ); 
     180#ifdef _WIN32 
     181    if( fd == INVALID_SOCKET ) 
     182#else 
     183    if( fd < 0 ) 
     184#endif 
     185    { 
     186        ur_throwErr( UR_ERR_ACCESS, "socket %s", SOCKET_ERR ); 
     187        return -1; 
     188    } 
     189 
     190    if( connect( fd, (struct sockaddr*) addr, sizeof(struct sockaddr_in) ) < 0 ) 
     191    { 
     192        closesocket( fd ); 
     193        ur_throwErr( UR_ERR_ACCESS, "connect %s", SOCKET_ERR ); 
     194        return -1; 
     195    } 
     196 
     197    return fd; 
     198} 
     199 
     200 
    171201/* 
    172202  ('udp port -- port!) 
    173203  ('udp [port host host-port 'nowait] -- port!) 
     204  ('tcp [host host-port] -- port!) 
    174205 
    175206  The UPortDevice open method must return the following: 
     
    181212{ 
    182213    struct sockaddr_in addr; 
     214    int addrBuilt = 0; 
    183215    int port = 0; 
     216    int hostPort = 0; 
    184217    int blocking = 1; 
     218    int stype; 
    185219    UCell* initAddr = 0; 
    186220    UCell* spec = 0; 
     
    196230    if( ! ur_isAWord(res) ) 
    197231        return 0; 
    198     if( ur_atom(res) != ur_intern("udp", 3) ) 
     232 
     233    if( ur_atom(res) == ur_intern("udp", 3) ) 
     234        stype = SOCK_DGRAM; 
     235    else if( ur_atom(res) == ur_intern("tcp", 3) ) 
     236        stype = SOCK_STREAM; 
     237    else 
    199238        return 0; 
    200239 
     
    203242        UCell* it; 
    204243        UCell* end; 
    205         int hostPort; 
    206244        UAtom atom_nb = 0; 
    207245        UBlock* blk = ur_block(spec); 
     
    209247        UR_ITER_BLOCK( it, end, blk, spec ); 
    210248 
    211         port = hostPort = 0; 
    212  
    213249        while( it != end ) 
    214250        { 
    215251            if( ur_is(it, UT_INT) ) 
    216252            { 
    217                 if( port ) 
     253                if( initAddr ) 
    218254                    hostPort = ur_int(it); 
    219255                else 
     
    236272        if( initAddr && hostPort ) 
    237273        { 
    238             if( ! _makeAddrName( &addr, ur_cstring(ut,initAddr), hostPort ) ) 
     274            if( ! _makeAddrName( &addr, ur_cstring(ut, initAddr), hostPort ) ) 
    239275            { 
    240276                ur_throwErr( UR_ERR_ACCESS, "gethostbyname failed" ); 
    241277                return -1; 
    242278            } 
     279            addrBuilt = 1; 
    243280        } 
    244281    } 
     
    248285        int socket; 
    249286 
    250         if( ! ur_userAllows( ut, "Open socket on port %d", port ) ) 
    251         { 
    252             ur_throwErr( UR_ERR_ACCESS, "User denied open" ); 
    253             return -1; 
    254         } 
    255  
    256         socket = _openUdpSocket( ut, port, blocking ); 
     287        if( stype == SOCK_DGRAM ) 
     288        { 
     289            if( ! ur_userAllows( ut, "Open socket on port %d", port ) ) 
     290            { 
     291                ur_throwErr( UR_ERR_ACCESS, "User denied open" ); 
     292                return -1; 
     293            } 
     294            socket = _openUdpSocket( ut, port, blocking ); 
     295        } 
     296        else 
     297        { 
     298            if( ! addrBuilt ) 
     299            { 
     300                ur_throwErr( UR_ERR_SCRIPT, 
     301                             "TCP port requires hostname and port" ); 
     302                return -1; 
     303            } 
     304            if( ! ur_userAllows( ut, "Open TCP connection to %s:%d", 
     305                                 ur_cstring(ut, initAddr), hostPort ) ) 
     306            { 
     307                ur_throwErr( UR_ERR_ACCESS, "User denied open" ); 
     308                return -1; 
     309            } 
     310            socket = _openTcpClient( ut, &addr ); 
     311        } 
     312 
    257313        if( socket < 0 ) 
    258314            return -1; 
     
    266322            ur_initType(val, UT_INT);       // SV_FD 
    267323            ur_int(val) = socket; 
     324            ur_sockType(val) = stype; 
    268325 
    269326            binN = ur_makeBinary( sizeof(struct sockaddr), &bin ); 
     
    352409            fromlen = sizeof(struct sockaddr_in); 
    353410 
    354             count = recvfrom( ur_int(val), bin->ptr.c, RECV_BUF_SIZE, 0, 
    355                               (struct sockaddr*) addr->ptr.v, &fromlen ); 
     411            if( ur_sockType(val) == SOCK_STREAM ) 
     412            { 
     413                count = recv( ur_int(val), bin->ptr.c, RECV_BUF_SIZE, 0 ); 
     414            } 
     415            else 
     416            { 
     417                count = recvfrom( ur_int(val), bin->ptr.c, RECV_BUF_SIZE, 0, 
     418                                  (struct sockaddr*) addr->ptr.v, &fromlen ); 
     419            } 
    356420            if( count == -1 ) 
    357421            { 
     
    404468        if( buf ) 
    405469        { 
    406             UBinary* bin; 
    407470            int n; 
    408471            SOCKET fd = ur_int(val); 
    409472            int len = end - buf; 
    410473 
    411             bin = ur_bin( blk->ptr.cells + SV_ADDR ); 
    412  
    413             n = sendto( fd, buf, len, 0, (struct sockaddr*) bin->ptr.v, 
    414                         sizeof(struct sockaddr) ); 
     474            if( ur_sockType(val) == SOCK_STREAM ) 
     475            { 
     476                n = send( fd, buf, len, 0 ); 
     477            } 
     478            else 
     479            { 
     480                UBinary* bin = ur_bin( blk->ptr.cells + SV_ADDR ); 
     481 
     482                n = sendto( fd, buf, len, 0, (struct sockaddr*) bin->ptr.v, 
     483                            sizeof(struct sockaddr) ); 
     484            } 
     485 
    415486            if( n == -1 ) 
    416487            { 
    417                 ur_throwErr( UR_ERR_ACCESS, "sendto %d", SOCKET_ERR ); 
     488                ur_throwErr( UR_ERR_ACCESS, "send %d", SOCKET_ERR ); 
    418489 
    419490                // An error occured; the socket must not be used again. 
     
    425496            { 
    426497                ur_throwErr( UR_ERR_ACCESS, 
    427                              "sendto only sent %d of %d bytes", n, len ); 
     498                             "send only sent %d of %d bytes", n, len ); 
    428499                return; 
    429500            }