fd-socket.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. /*
  2. * fd-socket.c: implementation of Socket that just talks to two
  3. * existing input and output file descriptors.
  4. */
  5. #include <stdio.h>
  6. #include <assert.h>
  7. #include <errno.h>
  8. #include <unistd.h>
  9. #include <fcntl.h>
  10. #include "tree234.h"
  11. #include "putty.h"
  12. #include "network.h"
  13. typedef struct FdSocket {
  14. int outfd, infd, inerrfd; /* >= 0 if socket is open */
  15. DeferredSocketOpener *opener; /* non-NULL if not opened yet */
  16. bufchain pending_output_data;
  17. bufchain pending_input_data;
  18. ProxyStderrBuf psb;
  19. enum { EOF_NO, EOF_PENDING, EOF_SENT } outgoingeof;
  20. int pending_error;
  21. SockAddr *addr;
  22. int port;
  23. Plug *plug;
  24. Socket sock;
  25. } FdSocket;
  26. static void fdsocket_select_result_input(int fd, int event);
  27. static void fdsocket_select_result_output(int fd, int event);
  28. static void fdsocket_select_result_input_error(int fd, int event);
  29. /*
  30. * Trees to look up the fds in.
  31. */
  32. static tree234 *fdsocket_by_outfd;
  33. static tree234 *fdsocket_by_infd;
  34. static tree234 *fdsocket_by_inerrfd;
  35. static int fdsocket_infd_cmp(void *av, void *bv)
  36. {
  37. FdSocket *a = (FdSocket *)av;
  38. FdSocket *b = (FdSocket *)bv;
  39. if (a->infd < b->infd)
  40. return -1;
  41. if (a->infd > b->infd)
  42. return +1;
  43. return 0;
  44. }
  45. static int fdsocket_infd_find(void *av, void *bv)
  46. {
  47. int a = *(int *)av;
  48. FdSocket *b = (FdSocket *)bv;
  49. if (a < b->infd)
  50. return -1;
  51. if (a > b->infd)
  52. return +1;
  53. return 0;
  54. }
  55. static int fdsocket_inerrfd_cmp(void *av, void *bv)
  56. {
  57. FdSocket *a = (FdSocket *)av;
  58. FdSocket *b = (FdSocket *)bv;
  59. if (a->inerrfd < b->inerrfd)
  60. return -1;
  61. if (a->inerrfd > b->inerrfd)
  62. return +1;
  63. return 0;
  64. }
  65. static int fdsocket_inerrfd_find(void *av, void *bv)
  66. {
  67. int a = *(int *)av;
  68. FdSocket *b = (FdSocket *)bv;
  69. if (a < b->inerrfd)
  70. return -1;
  71. if (a > b->inerrfd)
  72. return +1;
  73. return 0;
  74. }
  75. static int fdsocket_outfd_cmp(void *av, void *bv)
  76. {
  77. FdSocket *a = (FdSocket *)av;
  78. FdSocket *b = (FdSocket *)bv;
  79. if (a->outfd < b->outfd)
  80. return -1;
  81. if (a->outfd > b->outfd)
  82. return +1;
  83. return 0;
  84. }
  85. static int fdsocket_outfd_find(void *av, void *bv)
  86. {
  87. int a = *(int *)av;
  88. FdSocket *b = (FdSocket *)bv;
  89. if (a < b->outfd)
  90. return -1;
  91. if (a > b->outfd)
  92. return +1;
  93. return 0;
  94. }
  95. static Plug *fdsocket_plug(Socket *s, Plug *p)
  96. {
  97. FdSocket *fds = container_of(s, FdSocket, sock);
  98. Plug *ret = fds->plug;
  99. if (p)
  100. fds->plug = p;
  101. return ret;
  102. }
  103. static void fdsocket_close(Socket *s)
  104. {
  105. FdSocket *fds = container_of(s, FdSocket, sock);
  106. if (fds->opener)
  107. deferred_socket_opener_free(fds->opener);
  108. if (fds->outfd >= 0) {
  109. del234(fdsocket_by_outfd, fds);
  110. uxsel_del(fds->outfd);
  111. close(fds->outfd);
  112. }
  113. if (fds->infd >= 0) {
  114. del234(fdsocket_by_infd, fds);
  115. uxsel_del(fds->infd);
  116. close(fds->infd);
  117. }
  118. if (fds->inerrfd >= 0) {
  119. del234(fdsocket_by_inerrfd, fds);
  120. uxsel_del(fds->inerrfd);
  121. close(fds->inerrfd);
  122. }
  123. bufchain_clear(&fds->pending_input_data);
  124. bufchain_clear(&fds->pending_output_data);
  125. if (fds->addr)
  126. sk_addr_free(fds->addr);
  127. delete_callbacks_for_context(fds);
  128. sfree(fds);
  129. }
  130. static void fdsocket_error_callback(void *vs)
  131. {
  132. FdSocket *fds = (FdSocket *)vs;
  133. /*
  134. * Just in case other socket work has caused this socket to vanish
  135. * or become somehow non-erroneous before this callback arrived...
  136. */
  137. if (!fds->pending_error)
  138. return;
  139. /*
  140. * An error has occurred on this socket. Pass it to the plug.
  141. */
  142. plug_closing_errno(fds->plug, fds->pending_error);
  143. }
  144. static int fdsocket_try_send(FdSocket *fds)
  145. {
  146. int sent = 0;
  147. if (fds->opener)
  148. return sent;
  149. while (bufchain_size(&fds->pending_output_data) > 0) {
  150. ssize_t ret;
  151. ptrlen data = bufchain_prefix(&fds->pending_output_data);
  152. ret = write(fds->outfd, data.ptr, data.len);
  153. noise_ultralight(NOISE_SOURCE_IOID, ret);
  154. if (ret < 0 && errno != EWOULDBLOCK) {
  155. if (!fds->pending_error) {
  156. fds->pending_error = errno;
  157. queue_toplevel_callback(fdsocket_error_callback, fds);
  158. }
  159. return 0;
  160. } else if (ret <= 0) {
  161. break;
  162. } else {
  163. bufchain_consume(&fds->pending_output_data, ret);
  164. sent += ret;
  165. }
  166. }
  167. if (fds->outgoingeof == EOF_PENDING) {
  168. del234(fdsocket_by_outfd, fds);
  169. close(fds->outfd);
  170. uxsel_del(fds->outfd);
  171. fds->outfd = -1;
  172. fds->outgoingeof = EOF_SENT;
  173. }
  174. if (bufchain_size(&fds->pending_output_data) == 0)
  175. uxsel_del(fds->outfd);
  176. else
  177. uxsel_set(fds->outfd, SELECT_W, fdsocket_select_result_output);
  178. return sent;
  179. }
  180. static size_t fdsocket_write(Socket *s, const void *data, size_t len)
  181. {
  182. FdSocket *fds = container_of(s, FdSocket, sock);
  183. assert(fds->outgoingeof == EOF_NO);
  184. bufchain_add(&fds->pending_output_data, data, len);
  185. fdsocket_try_send(fds);
  186. return bufchain_size(&fds->pending_output_data);
  187. }
  188. static size_t fdsocket_write_oob(Socket *s, const void *data, size_t len)
  189. {
  190. /*
  191. * oob data is treated as inband; nasty, but nothing really
  192. * better we can do
  193. */
  194. return fdsocket_write(s, data, len);
  195. }
  196. static void fdsocket_write_eof(Socket *s)
  197. {
  198. FdSocket *fds = container_of(s, FdSocket, sock);
  199. assert(fds->outgoingeof == EOF_NO);
  200. fds->outgoingeof = EOF_PENDING;
  201. fdsocket_try_send(fds);
  202. }
  203. static void fdsocket_set_frozen(Socket *s, bool is_frozen)
  204. {
  205. FdSocket *fds = container_of(s, FdSocket, sock);
  206. if (fds->infd < 0)
  207. return;
  208. if (is_frozen)
  209. uxsel_del(fds->infd);
  210. else
  211. uxsel_set(fds->infd, SELECT_R, fdsocket_select_result_input);
  212. }
  213. static const char *fdsocket_socket_error(Socket *s)
  214. {
  215. return NULL;
  216. }
  217. static void fdsocket_select_result_input(int fd, int event)
  218. {
  219. FdSocket *fds;
  220. char buf[20480];
  221. int retd;
  222. if (!(fds = find234(fdsocket_by_infd, &fd, fdsocket_infd_find)))
  223. return;
  224. retd = read(fds->infd, buf, sizeof(buf));
  225. if (retd > 0) {
  226. plug_receive(fds->plug, 0, buf, retd);
  227. } else {
  228. del234(fdsocket_by_infd, fds);
  229. uxsel_del(fds->infd);
  230. close(fds->infd);
  231. fds->infd = -1;
  232. if (retd < 0) {
  233. plug_closing_errno(fds->plug, errno);
  234. } else {
  235. plug_closing_normal(fds->plug);
  236. }
  237. }
  238. }
  239. static void fdsocket_select_result_output(int fd, int event)
  240. {
  241. FdSocket *fds;
  242. if (!(fds = find234(fdsocket_by_outfd, &fd, fdsocket_outfd_find)))
  243. return;
  244. if (fdsocket_try_send(fds))
  245. plug_sent(fds->plug, bufchain_size(&fds->pending_output_data));
  246. }
  247. static void fdsocket_select_result_input_error(int fd, int event)
  248. {
  249. FdSocket *fds;
  250. char buf[20480];
  251. int retd;
  252. if (!(fds = find234(fdsocket_by_inerrfd, &fd, fdsocket_inerrfd_find)))
  253. return;
  254. retd = read(fd, buf, sizeof(buf));
  255. if (retd > 0) {
  256. log_proxy_stderr(fds->plug, &fds->sock, &fds->psb, buf, retd);
  257. } else {
  258. del234(fdsocket_by_inerrfd, fds);
  259. uxsel_del(fds->inerrfd);
  260. close(fds->inerrfd);
  261. fds->inerrfd = -1;
  262. }
  263. }
  264. static const SocketVtable FdSocket_sockvt = {
  265. .plug = fdsocket_plug,
  266. .close = fdsocket_close,
  267. .write = fdsocket_write,
  268. .write_oob = fdsocket_write_oob,
  269. .write_eof = fdsocket_write_eof,
  270. .set_frozen = fdsocket_set_frozen,
  271. .socket_error = fdsocket_socket_error,
  272. .endpoint_info = nullsock_endpoint_info,
  273. };
  274. static void fdsocket_connect_success_callback(void *ctx)
  275. {
  276. FdSocket *fds = (FdSocket *)ctx;
  277. plug_log(fds->plug, &fds->sock, PLUGLOG_CONNECT_SUCCESS,
  278. fds->addr, fds->port, NULL, 0);
  279. }
  280. void setup_fd_socket(Socket *s, int infd, int outfd, int inerrfd)
  281. {
  282. FdSocket *fds = container_of(s, FdSocket, sock);
  283. assert(fds->sock.vt == &FdSocket_sockvt);
  284. if (fds->opener) {
  285. deferred_socket_opener_free(fds->opener);
  286. fds->opener = NULL;
  287. }
  288. fds->infd = infd;
  289. fds->outfd = outfd;
  290. fds->inerrfd = inerrfd;
  291. if (fds->outfd >= 0) {
  292. if (!fdsocket_by_outfd)
  293. fdsocket_by_outfd = newtree234(fdsocket_outfd_cmp);
  294. add234(fdsocket_by_outfd, fds);
  295. }
  296. if (fds->infd >= 0) {
  297. if (!fdsocket_by_infd)
  298. fdsocket_by_infd = newtree234(fdsocket_infd_cmp);
  299. add234(fdsocket_by_infd, fds);
  300. uxsel_set(fds->infd, SELECT_R, fdsocket_select_result_input);
  301. }
  302. if (fds->inerrfd >= 0) {
  303. assert(fds->inerrfd != fds->infd);
  304. if (!fdsocket_by_inerrfd)
  305. fdsocket_by_inerrfd = newtree234(fdsocket_inerrfd_cmp);
  306. add234(fdsocket_by_inerrfd, fds);
  307. uxsel_set(fds->inerrfd, SELECT_R, fdsocket_select_result_input_error);
  308. }
  309. queue_toplevel_callback(fdsocket_connect_success_callback, fds);
  310. }
  311. void fd_socket_set_psb_prefix(Socket *s, const char *prefix)
  312. {
  313. FdSocket *fds = container_of(s, FdSocket, sock);
  314. assert(fds->sock.vt == &FdSocket_sockvt);
  315. psb_set_prefix(&fds->psb, prefix);
  316. }
  317. static FdSocket *make_fd_socket_internal(SockAddr *addr, int port, Plug *plug)
  318. {
  319. FdSocket *fds;
  320. fds = snew(FdSocket);
  321. fds->sock.vt = &FdSocket_sockvt;
  322. fds->addr = addr;
  323. fds->port = port;
  324. fds->plug = plug;
  325. fds->outgoingeof = EOF_NO;
  326. fds->pending_error = 0;
  327. fds->opener = NULL;
  328. fds->infd = fds->outfd = fds->inerrfd = -1;
  329. bufchain_init(&fds->pending_input_data);
  330. bufchain_init(&fds->pending_output_data);
  331. psb_init(&fds->psb);
  332. return fds;
  333. }
  334. Socket *make_fd_socket(int infd, int outfd, int inerrfd,
  335. SockAddr *addr, int port, Plug *plug)
  336. {
  337. FdSocket *fds = make_fd_socket_internal(addr, port, plug);
  338. setup_fd_socket(&fds->sock, infd, outfd, inerrfd);
  339. return &fds->sock;
  340. }
  341. Socket *make_deferred_fd_socket(DeferredSocketOpener *opener,
  342. SockAddr *addr, int port, Plug *plug)
  343. {
  344. FdSocket *fds = make_fd_socket_internal(addr, port, plug);
  345. fds->opener = opener;
  346. return &fds->sock;
  347. }