Changeset 515
- Timestamp:
- 02/27/08 17:39:09 (7 months ago)
- Files:
-
- 1 modified
-
trunk/thune/net.c (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/thune/net.c
r510 r515 62 62 63 63 64 #define ur_sockType(cell) ((cell)->num.id._pad0) 65 66 64 67 // Values in the socket port context. 65 68 #define SV_FD 0 … … 113 116 114 117 if( ! _makeAddrName( (struct sockaddr_in*) addr->ptr.v, 115 ur_cstring(ut, hc), ur_int(tos) ) )118 ur_cstring(ut, hc), ur_int(tos) ) ) 116 119 { 117 120 ur_throwErr( UR_ERR_SCRIPT, "gethostbyname failed" ); … … 169 172 170 173 174 static 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 171 201 /* 172 202 ('udp port -- port!) 173 203 ('udp [port host host-port 'nowait] -- port!) 204 ('tcp [host host-port] -- port!) 174 205 175 206 The UPortDevice open method must return the following: … … 181 212 { 182 213 struct sockaddr_in addr; 214 int addrBuilt = 0; 183 215 int port = 0; 216 int hostPort = 0; 184 217 int blocking = 1; 218 int stype; 185 219 UCell* initAddr = 0; 186 220 UCell* spec = 0; … … 196 230 if( ! ur_isAWord(res) ) 197 231 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 199 238 return 0; 200 239 … … 203 242 UCell* it; 204 243 UCell* end; 205 int hostPort;206 244 UAtom atom_nb = 0; 207 245 UBlock* blk = ur_block(spec); … … 209 247 UR_ITER_BLOCK( it, end, blk, spec ); 210 248 211 port = hostPort = 0;212 213 249 while( it != end ) 214 250 { 215 251 if( ur_is(it, UT_INT) ) 216 252 { 217 if( port)253 if( initAddr ) 218 254 hostPort = ur_int(it); 219 255 else … … 236 272 if( initAddr && hostPort ) 237 273 { 238 if( ! _makeAddrName( &addr, ur_cstring(ut, initAddr), hostPort ) )274 if( ! _makeAddrName( &addr, ur_cstring(ut, initAddr), hostPort ) ) 239 275 { 240 276 ur_throwErr( UR_ERR_ACCESS, "gethostbyname failed" ); 241 277 return -1; 242 278 } 279 addrBuilt = 1; 243 280 } 244 281 } … … 248 285 int socket; 249 286 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 257 313 if( socket < 0 ) 258 314 return -1; … … 266 322 ur_initType(val, UT_INT); // SV_FD 267 323 ur_int(val) = socket; 324 ur_sockType(val) = stype; 268 325 269 326 binN = ur_makeBinary( sizeof(struct sockaddr), &bin ); … … 352 409 fromlen = sizeof(struct sockaddr_in); 353 410 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 } 356 420 if( count == -1 ) 357 421 { … … 404 468 if( buf ) 405 469 { 406 UBinary* bin;407 470 int n; 408 471 SOCKET fd = ur_int(val); 409 472 int len = end - buf; 410 473 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 415 486 if( n == -1 ) 416 487 { 417 ur_throwErr( UR_ERR_ACCESS, "send to%d", SOCKET_ERR );488 ur_throwErr( UR_ERR_ACCESS, "send %d", SOCKET_ERR ); 418 489 419 490 // An error occured; the socket must not be used again. … … 425 496 { 426 497 ur_throwErr( UR_ERR_ACCESS, 427 "send toonly sent %d of %d bytes", n, len );498 "send only sent %d of %d bytes", n, len ); 428 499 return; 429 500 }
