1
0

connection.cpp 10 KB

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