wac_network_connection.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. /*
  2. ** JNetLib
  3. ** Copyright (C) 2000-2007 Nullsoft, Inc.
  4. ** Author: Justin Frankel
  5. ** File: connection.cpp - JNL TCP connection implementation
  6. ** License: see jnetlib.h
  7. */
  8. #include "netinc.h"
  9. #include "util.h"
  10. #include "wac_network_connection.h"
  11. #include "wac_network_dns.h"
  12. #include "foundation\error.h"
  13. #include "../nu/strsafe.h"
  14. #pragma intrinsic(memcpy, memset)
  15. WAC_Network_Connection::WAC_Network_Connection()
  16. {
  17. init();
  18. }
  19. WAC_Network_Connection::WAC_Network_Connection( api_dns *dns, size_t sendbufsize, size_t recvbufsize )
  20. {
  21. init();
  22. open( dns, sendbufsize, recvbufsize );
  23. }
  24. void WAC_Network_Connection::init()
  25. {
  26. m_errorstr = 0;
  27. address = 0;
  28. m_dns = NULL;
  29. m_dns_owned = false;
  30. m_socket = -1;
  31. m_remote_port = 0;
  32. m_state = STATE_NOCONNECTION;
  33. m_host[ 0 ] = 0;
  34. saddr = 0;
  35. }
  36. WAC_Network_Connection::~WAC_Network_Connection()
  37. {
  38. /*
  39. ** Joshua Teitelbaum 1/27/2006
  40. ** virtualization for ssl, calling socket_shtudown()
  41. */
  42. socket_shutdown();
  43. if ( !saddr ) // free it if it was passed to us (by JNL_Listen, presumably)
  44. free( address ); // TODO: change this if we ever do round-robin DNS connecting or in any way change how we handle 'address'
  45. if ( m_dns_owned )
  46. delete static_cast<wa::Components::WAC_Network_AsyncDNS *>( m_dns );
  47. }
  48. void WAC_Network_Connection::set_dns( api_dns *dns )
  49. {
  50. if ( m_dns_owned )
  51. delete static_cast<wa::Components::WAC_Network_AsyncDNS *>( m_dns );
  52. m_dns = dns;
  53. m_dns_owned = false;
  54. }
  55. void WAC_Network_Connection::open( api_dns *dns, size_t sendbufsize, size_t recvbufsize )
  56. {
  57. if ( dns != API_DNS_AUTODNS && dns )
  58. {
  59. m_dns = dns;
  60. m_dns_owned = false;
  61. }
  62. else if ( !m_dns )
  63. {
  64. m_dns = new wa::Components::WAC_Network_AsyncDNS;
  65. m_dns_owned = true;
  66. }
  67. recv_buffer.reserve( recvbufsize );
  68. send_buffer.reserve( sendbufsize );
  69. }
  70. void WAC_Network_Connection::connect( SOCKET s, sockaddr *addr, socklen_t length )
  71. {
  72. close( 1 );
  73. m_socket = s;
  74. address = (sockaddr *)malloc( length );
  75. memcpy( address, addr, length );
  76. m_remote_port = 0;
  77. if ( m_socket != -1 )
  78. {
  79. SET_SOCK_BLOCK( m_socket, 0 );
  80. m_state = STATE_CONNECTED;
  81. }
  82. else
  83. {
  84. m_errorstr = _strdup( "invalid socket passed to connect" );
  85. m_state = STATE_ERROR;
  86. }
  87. }
  88. void WAC_Network_Connection::connect( const char *hostname, int port )
  89. {
  90. close( 1 );
  91. m_remote_port = (unsigned short)port;
  92. #ifdef _WIN32
  93. lstrcpynA( m_host, hostname, sizeof( m_host ) );
  94. #elif defined(__APPLE__)
  95. strlcpy( m_host, hostname, sizeof( m_host ) );
  96. #else
  97. strncpy( m_host, hostname, sizeof( m_host ) - 1 );
  98. m_host[ sizeof( m_host ) - 1 ] = 0;
  99. #endif
  100. //memset(&m_saddr,0,sizeof(m_saddr));
  101. if ( !m_host[ 0 ] )
  102. {
  103. m_errorstr = _strdup( "empty hostname" );
  104. m_state = STATE_ERROR;
  105. }
  106. else
  107. {
  108. m_state = STATE_RESOLVING;
  109. }
  110. }
  111. /*
  112. ** Joshua Teitelbaum 1/27/2006
  113. ** socket_shutdown
  114. ** virtualization for ssl
  115. */
  116. /* Virtual */
  117. void WAC_Network_Connection::socket_shutdown()
  118. {
  119. if ( m_socket >= 0 )
  120. {
  121. ::shutdown( m_socket, SHUT_RDWR );
  122. ::closesocket( m_socket );
  123. m_socket = -1;
  124. }
  125. }
  126. /*
  127. ** Joshua Teitelbaum 1/27/2006
  128. ** socket_recv
  129. ** virtualization for ssl
  130. */
  131. /* Virtual */
  132. ssize_t WAC_Network_Connection::socket_recv( char *buf, size_t len, int options )
  133. {
  134. return ::recv( m_socket, buf, (int)len, options );
  135. }
  136. /*
  137. ** Joshua Teitelbaum 1/27/2006
  138. ** socket_send
  139. ** virtualization for ssl
  140. */
  141. /* Virtual */
  142. ssize_t WAC_Network_Connection::socket_send( const char *buf, size_t len, int options )
  143. {
  144. return ::send( m_socket, buf, (int)len, options );
  145. }
  146. int WAC_Network_Connection::socket_connect()
  147. {
  148. return ::connect( m_socket, saddr->ai_addr, (int)saddr->ai_addrlen );
  149. }
  150. void WAC_Network_Connection::run( size_t max_send_bytes, size_t max_recv_bytes, size_t *bytes_sent, size_t *bytes_rcvd )
  151. {
  152. socklen_t socket_buffer_size = 0;
  153. socklen_t socket_buffer_size_len = sizeof( socket_buffer_size );
  154. socklen_t send_buffer_size;
  155. socklen_t recv_buffer_size;
  156. size_t bytes_allowed_to_send = ( max_send_bytes == (size_t)-1 ) ? send_buffer.size() : max_send_bytes;
  157. size_t bytes_allowed_to_recv = ( max_recv_bytes == (size_t)-1 ) ? recv_buffer.avail() : max_recv_bytes;
  158. if ( bytes_sent )
  159. *bytes_sent = 0;
  160. if ( bytes_rcvd )
  161. *bytes_rcvd = 0;
  162. switch ( m_state )
  163. {
  164. case STATE_RESOLVING:
  165. if ( saddr == 0 )
  166. {
  167. int a = m_dns->resolve( m_host, m_remote_port, &saddr, SOCK_STREAM );
  168. if ( !a )
  169. {
  170. m_state = STATE_RESOLVED;
  171. }
  172. else if ( a == 1 )
  173. {
  174. m_state = STATE_RESOLVING;
  175. break;
  176. }
  177. else
  178. {
  179. m_errorstr = _strdup( "resolving hostname" );
  180. m_state = STATE_ERROR;
  181. return;
  182. }
  183. }
  184. // fall through
  185. case STATE_RESOLVED:
  186. m_socket = ::socket( saddr->ai_family, saddr->ai_socktype, saddr->ai_protocol );
  187. if ( m_socket == -1 )
  188. {
  189. m_errorstr = _strdup( "creating socket" );
  190. m_state = STATE_ERROR;
  191. }
  192. else
  193. {
  194. SET_SOCK_BLOCK( m_socket, 0 );
  195. }
  196. socket_buffer_size = 0;
  197. socket_buffer_size_len = sizeof( socket_buffer_size );
  198. getsockopt( m_socket, SOL_SOCKET, SO_SNDBUF, (char *)&socket_buffer_size, &socket_buffer_size_len );
  199. send_buffer_size = (int)( send_buffer.avail() + send_buffer.size() );
  200. if ( send_buffer_size > 65536 )
  201. send_buffer_size = 65536;
  202. if ( socket_buffer_size < send_buffer_size )
  203. setsockopt( m_socket, SOL_SOCKET, SO_SNDBUF, (char *)&send_buffer_size, sizeof( send_buffer_size ) );
  204. getsockopt( m_socket, SOL_SOCKET, SO_SNDBUF, (char *)&socket_buffer_size, &socket_buffer_size_len );
  205. getsockopt( m_socket, SOL_SOCKET, SO_RCVBUF, (char *)&socket_buffer_size, &socket_buffer_size_len );
  206. recv_buffer_size = (int)recv_buffer.avail();
  207. if ( recv_buffer_size > 65536 )
  208. recv_buffer_size = 65536;
  209. if ( socket_buffer_size < recv_buffer_size )
  210. setsockopt( m_socket, SOL_SOCKET, SO_RCVBUF, (char *)&recv_buffer_size, sizeof( recv_buffer_size ) );
  211. getsockopt( m_socket, SOL_SOCKET, SO_RCVBUF, (char *)&socket_buffer_size, &socket_buffer_size_len );
  212. /*
  213. ** Joshua Teitelbaum 1/27/2006
  214. ** virtualization for ssl
  215. */
  216. if ( !socket_connect() )
  217. {
  218. address = saddr->ai_addr;
  219. m_state = STATE_CONNECTED;
  220. on_socket_connected();
  221. }
  222. else if ( ERRNO != EINPROGRESS )
  223. {
  224. m_errorstr = _strdup( "Connecting to host" );
  225. m_state = STATE_ERROR;
  226. }
  227. else
  228. {
  229. m_state = STATE_CONNECTING;
  230. }
  231. break;
  232. case STATE_CONNECTING:
  233. {
  234. fd_set f[ 3 ];
  235. FD_ZERO( &f[ 0 ] );
  236. FD_ZERO( &f[ 1 ] );
  237. FD_ZERO( &f[ 2 ] );
  238. FD_SET( m_socket, &f[ 0 ] );
  239. FD_SET( m_socket, &f[ 1 ] );
  240. FD_SET( m_socket, &f[ 2 ] );
  241. struct timeval tv;
  242. memset( &tv, 0, sizeof( tv ) );
  243. if ( select( (int)m_socket + 1, &f[ 0 ], &f[ 1 ], &f[ 2 ], &tv ) == -1 )
  244. {
  245. m_errorstr = _strdup( "Connecting to host (calling select())" );
  246. m_state = STATE_ERROR;
  247. }
  248. else if ( FD_ISSET( m_socket, &f[ 1 ] ) )
  249. {
  250. m_state = STATE_CONNECTED;
  251. on_socket_connected();
  252. }
  253. else if ( FD_ISSET( m_socket, &f[ 2 ] ) )
  254. {
  255. m_errorstr = _strdup( "Connecting to host" );
  256. m_state = STATE_ERROR;
  257. }
  258. }
  259. break;
  260. case STATE_CONNECTED:
  261. case STATE_CLOSING:
  262. /* --- send --- */
  263. {
  264. size_t sent = send_buffer.drain( this, bytes_allowed_to_send );
  265. if ( bytes_sent )
  266. *bytes_sent += sent;
  267. if ( m_state == STATE_CLOSED )
  268. break;
  269. /* --- receive --- */
  270. size_t received = recv_buffer.fill( this, bytes_allowed_to_recv );
  271. if ( bytes_rcvd )
  272. *bytes_rcvd += received;
  273. }
  274. if ( m_state == STATE_CLOSING )
  275. {
  276. if ( send_buffer.empty() ) m_state = STATE_CLOSED;
  277. }
  278. break;
  279. default:
  280. break;
  281. }
  282. }
  283. void WAC_Network_Connection::on_socket_connected( void )
  284. {
  285. return;
  286. }
  287. void WAC_Network_Connection::close( int quick )
  288. {
  289. if ( quick || m_state == STATE_RESOLVING || m_state == STATE_CONNECTING )
  290. {
  291. m_state = STATE_CLOSED;
  292. /*
  293. ** Joshua Teitelbaum 1/27/2006
  294. ** virualization for ssl
  295. */
  296. socket_shutdown();
  297. m_socket = -1;
  298. recv_buffer.clear();
  299. send_buffer.clear();
  300. m_remote_port = 0;
  301. m_host[ 0 ] = 0;
  302. //memset(&m_saddr,0,sizeof(m_saddr));
  303. }
  304. else
  305. {
  306. if ( m_state == STATE_CONNECTED )
  307. m_state = STATE_CLOSING;
  308. }
  309. }
  310. size_t WAC_Network_Connection::send_bytes_in_queue( void )
  311. {
  312. return send_buffer.size();
  313. }
  314. size_t WAC_Network_Connection::send_bytes_available( void )
  315. {
  316. return send_buffer.avail();
  317. }
  318. int WAC_Network_Connection::send( const void *data, size_t length )
  319. {
  320. if ( length > send_bytes_available() )
  321. return -1;
  322. send_buffer.write( data, length );
  323. return 0;
  324. }
  325. int WAC_Network_Connection::send_string( const char *line )
  326. {
  327. return send( line, strlen( line ) );
  328. }
  329. size_t WAC_Network_Connection::recv_bytes_available( void )
  330. {
  331. return recv_buffer.size();
  332. }
  333. size_t WAC_Network_Connection::peek_bytes( void *data, size_t maxlength )
  334. {
  335. if ( data )
  336. return recv_buffer.peek( data, maxlength );
  337. else
  338. return min( maxlength, recv_bytes_available() );
  339. }
  340. size_t WAC_Network_Connection::recv_bytes( void *data, size_t maxlength )
  341. {
  342. if ( data )
  343. return recv_buffer.read( data, maxlength );
  344. else
  345. return recv_buffer.advance( maxlength );
  346. }
  347. int WAC_Network_Connection::recv_lines_available( void )
  348. {
  349. int l = (int)recv_bytes_available();
  350. int lcount = 0;
  351. int lastch = 0;
  352. for ( int pos = 0; pos < l; pos++ )
  353. {
  354. char t;
  355. if ( recv_buffer.at( pos, &t, 1 ) != 1 )
  356. return lcount;
  357. if ( ( t == '\r' || t == '\n' ) && ( ( lastch != '\r' && lastch != '\n' ) || lastch == t ) )
  358. lcount++;
  359. lastch = t;
  360. }
  361. return lcount;
  362. }
  363. int WAC_Network_Connection::recv_line( char *line, size_t maxlength )
  364. {
  365. while ( maxlength-- )
  366. {
  367. char t;
  368. if ( recv_buffer.read( &t, 1 ) == 0 )
  369. {
  370. *line = 0;
  371. return 0;
  372. }
  373. if ( t == '\r' || t == '\n' )
  374. {
  375. char r;
  376. if ( recv_buffer.peek( &r, 1 ) != 0 )
  377. {
  378. if ( ( r == '\r' || r == '\n' ) && r != t )
  379. recv_buffer.advance( 1 );
  380. }
  381. *line = 0;
  382. return 0;
  383. }
  384. *line++ = t;
  385. }
  386. return 1;
  387. }
  388. unsigned long WAC_Network_Connection::get_interface( void )
  389. {
  390. if ( m_socket == -1 )
  391. return 0;
  392. struct sockaddr_in sin;
  393. memset( &sin, 0, sizeof( sin ) );
  394. socklen_t len = sizeof( sin );
  395. if ( ::getsockname( m_socket, (struct sockaddr *)&sin, &len ) )
  396. return 0;
  397. return (unsigned long)sin.sin_addr.s_addr;
  398. }
  399. unsigned long WAC_Network_Connection::get_remote()
  400. {
  401. // TODO: IPv6
  402. if ( address )
  403. {
  404. sockaddr_in *ipv4 = (sockaddr_in *)address;
  405. return ipv4->sin_addr.s_addr;
  406. }
  407. return 0;
  408. }
  409. unsigned short WAC_Network_Connection::get_remote_port()
  410. {
  411. return m_remote_port;
  412. }
  413. /* RingBuffer client function */
  414. size_t WAC_Network_Connection::Read( void *dest, size_t len )
  415. {
  416. if ( !len )
  417. return 0;
  418. int res = (int)socket_recv( (char *)dest, len, 0 );
  419. if ( res == 0 || ( res < 0 && ERRNO != EWOULDBLOCK ) )
  420. {
  421. m_state = STATE_CLOSED;
  422. return 0;
  423. }
  424. if ( res > 0 )
  425. return res;
  426. else
  427. return 0;
  428. }
  429. /* RingBuffer client function */
  430. size_t WAC_Network_Connection::Write( const void *dest, size_t len )
  431. {
  432. if ( !len )
  433. return 0;
  434. int res = (int)socket_send( (const char *)dest, len, 0 );
  435. if ( res == -1 && ERRNO != EWOULDBLOCK )
  436. {
  437. return 0;
  438. // m_state=STATE_CLOSED;
  439. }
  440. if ( res > 0 )
  441. return res;
  442. else
  443. return 0;
  444. }
  445. int WAC_Network_Connection::set_recv_buffer_size( size_t new_buffer_size )
  446. {
  447. return recv_buffer.expand( new_buffer_size );
  448. }
  449. void WAC_Network_Connection::reuse()
  450. {
  451. if ( m_state == STATE_CLOSED )
  452. {
  453. m_state = STATE_CONNECTED;
  454. recv_buffer.clear();
  455. }
  456. }
  457. #define CBCLASS WAC_Network_Connection
  458. START_DISPATCH;
  459. VCB( API_CONNECTION_OPEN, open )
  460. case API_CONNECTION_CONNECT: connect( *(char **)( params[ 0 ] ), *(int *)( params[ 1 ] ) ); return 1;
  461. VCB( API_CONNECTION_RUN, run )
  462. CB( API_CONNECTION_GETSTATE, get_state )
  463. CB( API_CONNECTION_GETERROR, get_errstr )
  464. VCB( API_CONNECTION_CLOSE, close )
  465. VCB( API_CONNECTION_FLUSHSEND, flush_send )
  466. CB( API_CONNECTION_GETSENDBYTESINQUEUE, send_bytes_in_queue )
  467. CB( API_CONNECTION_GETSENDBYTESAVAILABLE, send_bytes_available )
  468. CB( API_CONNECTION_SEND, send )
  469. CB( API_CONNECTION_SENDBYTES, send_bytes )
  470. CB( API_CONNECTION_SENDSTRING, send_string )
  471. CB( API_CONNECTION_GETRECEIVEBYTESAVAILABLE, recv_bytes_available )
  472. CB( API_CONNECTION_RECEIVEBYTES, recv_bytes )
  473. CB( API_CONNECTION_GETRECEIVELINESAVAILABLE, recv_lines_available )
  474. CB( API_CONNECTION_RECEIVELINE, recv_line )
  475. CB( API_CONNECTION_PEEKBYTES, peek_bytes )
  476. CB( API_CONNECTION_GETINTERFACE, get_interface )
  477. CB( API_CONNECTION_GETREMOTEADDRESS, get_remote )
  478. CB( API_CONNECTION_GETREMOTEPORT, get_remote_port )
  479. END_DISPATCH;
  480. #undef CBCLASS