winnet.c 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373
  1. /*
  2. * Windows networking abstraction.
  3. *
  4. * Due to this clean abstraction it was possible
  5. * to easily implement IPv6 support :)
  6. *
  7. * IPv6 patch 1 (27 October 2000) Jeroen Massar <jeroen@unfix.org>
  8. * - Preliminary hacked IPv6 support.
  9. * - Connecting to IPv6 address (eg fec0:4242:4242:100:2d0:b7ff:fe8f:5d42) works.
  10. * - Connecting to IPv6 hostname (eg heaven.ipv6.unfix.org) works.
  11. * - Compiles as either IPv4 or IPv6.
  12. *
  13. * IPv6 patch 2 (29 October 2000) Jeroen Massar <jeroen@unfix.org>
  14. * - When compiled as IPv6 it also allows connecting to IPv4 hosts.
  15. * - Added some more documentation.
  16. *
  17. * IPv6 patch 3 (18 November 2000) Jeroen Massar <jeroen@unfix.org>
  18. * - It now supports dynamically loading the IPv6 resolver dll's.
  19. * This way we should be able to distribute one (1) binary
  20. * which supports both IPv4 and IPv6.
  21. * - getaddrinfo() and getnameinfo() are loaded dynamicaly if possible.
  22. * - in6addr_any is defined in this file so we don't need to link to wship6.lib
  23. * - The patch is now more unified so that we can still
  24. * remove all IPv6 support by undef'ing IPV6.
  25. * But where it fallsback to IPv4 it uses the IPv4 code which is already in place...
  26. * - Canonical name resolving works.
  27. *
  28. * IPv6 patch 4 (07 January 2001) Jeroen Massar <jeroen@unfix.org>
  29. * - patch against CVS of today, will be submitted to the bugs list
  30. * as a 'cvs diff -u' on Simon's request...
  31. *
  32. */
  33. /*
  34. * Define IPV6 to have IPv6 on-the-fly-loading support.
  35. * This means that one doesn't have to have an IPv6 stack to use it.
  36. * But if an IPv6 stack is found it is used with a fallback to IPv4.
  37. */
  38. /* #define IPV6 1 */
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <assert.h>
  42. #define DEFINE_PLUG_METHOD_MACROS
  43. #include "putty.h"
  44. #include "network.h"
  45. #include "tree234.h"
  46. #include <ws2tcpip.h>
  47. #ifdef IPV6
  48. #include <tpipv6.h>
  49. #endif
  50. #define ipv4_is_loopback(addr) \
  51. ((p_ntohl(addr.s_addr) & 0xFF000000L) == 0x7F000000L)
  52. struct Socket_tag {
  53. const struct socket_function_table *fn;
  54. /* the above variable absolutely *must* be the first in this structure */
  55. char *error;
  56. SOCKET s;
  57. Plug plug;
  58. void *private_ptr;
  59. bufchain output_data;
  60. int connected;
  61. int writable;
  62. int frozen; /* this causes readability notifications to be ignored */
  63. int frozen_readable; /* this means we missed at least one readability
  64. * notification while we were frozen */
  65. int localhost_only; /* for listening sockets */
  66. char oobdata[1];
  67. int sending_oob;
  68. int oobinline;
  69. int pending_error; /* in case send() returns error */
  70. };
  71. /*
  72. * We used to typedef struct Socket_tag *Socket.
  73. *
  74. * Since we have made the networking abstraction slightly more
  75. * abstract, Socket no longer means a tcp socket (it could mean
  76. * an ssl socket). So now we must use Actual_Socket when we know
  77. * we are talking about a tcp socket.
  78. */
  79. typedef struct Socket_tag *Actual_Socket;
  80. struct SockAddr_tag {
  81. char *error;
  82. /*
  83. * Which address family this address belongs to. AF_INET for
  84. * IPv4; AF_INET6 for IPv6; AF_UNSPEC indicates that name
  85. * resolution has not been done and a simple host name is held
  86. * in this SockAddr structure.
  87. */
  88. int family;
  89. unsigned long address; /* Address IPv4 style. */
  90. #ifdef IPV6
  91. struct addrinfo *ai; /* Address IPv6 style. */
  92. #endif
  93. char hostname[512]; /* Store an unresolved host name. */
  94. };
  95. static tree234 *sktree;
  96. static int cmpfortree(void *av, void *bv)
  97. {
  98. Actual_Socket a = (Actual_Socket) av, b = (Actual_Socket) bv;
  99. unsigned long as = (unsigned long) a->s, bs = (unsigned long) b->s;
  100. if (as < bs)
  101. return -1;
  102. if (as > bs)
  103. return +1;
  104. return 0;
  105. }
  106. static int cmpforsearch(void *av, void *bv)
  107. {
  108. Actual_Socket b = (Actual_Socket) bv;
  109. unsigned long as = (unsigned long) av, bs = (unsigned long) b->s;
  110. if (as < bs)
  111. return -1;
  112. if (as > bs)
  113. return +1;
  114. return 0;
  115. }
  116. #define NOTHING
  117. #define DECL_WINSOCK_FUNCTION(linkage, rettype, name, params) \
  118. typedef rettype (WINAPI *t_##name) params; \
  119. linkage t_##name p_##name
  120. #define GET_WINSOCK_FUNCTION(name) \
  121. p_##name = (t_##name) GetProcAddress(winsock_module, #name)
  122. DECL_WINSOCK_FUNCTION(NOTHING, int, WSAAsyncSelect,
  123. (SOCKET, HWND, u_int, long));
  124. DECL_WINSOCK_FUNCTION(NOTHING, int, WSAEventSelect, (SOCKET, WSAEVENT, long));
  125. DECL_WINSOCK_FUNCTION(NOTHING, int, select,
  126. (int, fd_set FAR *, fd_set FAR *,
  127. fd_set FAR *, const struct timeval FAR *));
  128. DECL_WINSOCK_FUNCTION(NOTHING, int, WSAGetLastError, (void));
  129. DECL_WINSOCK_FUNCTION(NOTHING, int, WSAEnumNetworkEvents,
  130. (SOCKET, WSAEVENT, LPWSANETWORKEVENTS));
  131. DECL_WINSOCK_FUNCTION(static, int, WSAStartup, (WORD, LPWSADATA));
  132. DECL_WINSOCK_FUNCTION(static, int, WSACleanup, (void));
  133. DECL_WINSOCK_FUNCTION(static, int, closesocket, (SOCKET));
  134. DECL_WINSOCK_FUNCTION(static, u_long, ntohl, (u_long));
  135. DECL_WINSOCK_FUNCTION(static, u_long, htonl, (u_long));
  136. DECL_WINSOCK_FUNCTION(static, u_short, htons, (u_short));
  137. DECL_WINSOCK_FUNCTION(static, u_short, ntohs, (u_short));
  138. DECL_WINSOCK_FUNCTION(static, struct hostent FAR *, gethostbyname,
  139. (const char FAR *));
  140. DECL_WINSOCK_FUNCTION(static, struct servent FAR *, getservbyname,
  141. (const char FAR *, const char FAR *));
  142. DECL_WINSOCK_FUNCTION(static, unsigned long, inet_addr, (const char FAR *));
  143. DECL_WINSOCK_FUNCTION(static, char FAR *, inet_ntoa, (struct in_addr));
  144. DECL_WINSOCK_FUNCTION(static, int, connect,
  145. (SOCKET, const struct sockaddr FAR *, int));
  146. DECL_WINSOCK_FUNCTION(static, int, bind,
  147. (SOCKET, const struct sockaddr FAR *, int));
  148. DECL_WINSOCK_FUNCTION(static, int, setsockopt,
  149. (SOCKET, int, int, const char FAR *, int));
  150. DECL_WINSOCK_FUNCTION(static, SOCKET, socket, (int, int, int));
  151. DECL_WINSOCK_FUNCTION(static, int, listen, (SOCKET, int));
  152. DECL_WINSOCK_FUNCTION(static, int, send, (SOCKET, const char FAR *, int, int));
  153. DECL_WINSOCK_FUNCTION(static, int, ioctlsocket,
  154. (SOCKET, long, u_long FAR *));
  155. DECL_WINSOCK_FUNCTION(static, SOCKET, accept,
  156. (SOCKET, struct sockaddr FAR *, int FAR *));
  157. DECL_WINSOCK_FUNCTION(static, int, recv, (SOCKET, char FAR *, int, int));
  158. DECL_WINSOCK_FUNCTION(static, int, WSAIoctl,
  159. (SOCKET, DWORD, LPVOID, DWORD, LPVOID, DWORD,
  160. LPDWORD, LPWSAOVERLAPPED,
  161. LPWSAOVERLAPPED_COMPLETION_ROUTINE));
  162. static HMODULE winsock_module;
  163. void sk_init(void)
  164. {
  165. WORD winsock_ver;
  166. WSADATA wsadata;
  167. winsock_ver = MAKEWORD(2, 0);
  168. winsock_module = LoadLibrary("WS2_32.DLL");
  169. if (!winsock_module) {
  170. winsock_module = LoadLibrary("WSOCK32.DLL");
  171. winsock_ver = MAKEWORD(1, 1);
  172. }
  173. if (!winsock_module)
  174. fatalbox("Unable to load any WinSock library");
  175. GET_WINSOCK_FUNCTION(WSAAsyncSelect);
  176. GET_WINSOCK_FUNCTION(WSAEventSelect);
  177. GET_WINSOCK_FUNCTION(select);
  178. GET_WINSOCK_FUNCTION(WSAGetLastError);
  179. GET_WINSOCK_FUNCTION(WSAEnumNetworkEvents);
  180. GET_WINSOCK_FUNCTION(WSAStartup);
  181. GET_WINSOCK_FUNCTION(WSACleanup);
  182. GET_WINSOCK_FUNCTION(closesocket);
  183. GET_WINSOCK_FUNCTION(ntohl);
  184. GET_WINSOCK_FUNCTION(htonl);
  185. GET_WINSOCK_FUNCTION(htons);
  186. GET_WINSOCK_FUNCTION(ntohs);
  187. GET_WINSOCK_FUNCTION(gethostbyname);
  188. GET_WINSOCK_FUNCTION(getservbyname);
  189. GET_WINSOCK_FUNCTION(inet_addr);
  190. GET_WINSOCK_FUNCTION(inet_ntoa);
  191. GET_WINSOCK_FUNCTION(connect);
  192. GET_WINSOCK_FUNCTION(bind);
  193. GET_WINSOCK_FUNCTION(setsockopt);
  194. GET_WINSOCK_FUNCTION(socket);
  195. GET_WINSOCK_FUNCTION(listen);
  196. GET_WINSOCK_FUNCTION(send);
  197. GET_WINSOCK_FUNCTION(ioctlsocket);
  198. GET_WINSOCK_FUNCTION(accept);
  199. GET_WINSOCK_FUNCTION(recv);
  200. GET_WINSOCK_FUNCTION(WSAIoctl);
  201. if (p_WSAStartup(winsock_ver, &wsadata)) {
  202. fatalbox("Unable to initialise WinSock");
  203. }
  204. if (LOBYTE(wsadata.wVersion) != LOBYTE(winsock_ver)) {
  205. p_WSACleanup();
  206. fatalbox("WinSock version is incompatible with %d.%d",
  207. LOBYTE(winsock_ver), HIBYTE(winsock_ver));
  208. }
  209. sktree = newtree234(cmpfortree);
  210. }
  211. void sk_cleanup(void)
  212. {
  213. Actual_Socket s;
  214. int i;
  215. if (sktree) {
  216. for (i = 0; (s = index234(sktree, i)) != NULL; i++) {
  217. p_closesocket(s->s);
  218. }
  219. freetree234(sktree);
  220. sktree = NULL;
  221. }
  222. p_WSACleanup();
  223. if (winsock_module)
  224. FreeLibrary(winsock_module);
  225. }
  226. char *winsock_error_string(int error)
  227. {
  228. switch (error) {
  229. case WSAEACCES:
  230. return "Network error: Permission denied";
  231. case WSAEADDRINUSE:
  232. return "Network error: Address already in use";
  233. case WSAEADDRNOTAVAIL:
  234. return "Network error: Cannot assign requested address";
  235. case WSAEAFNOSUPPORT:
  236. return
  237. "Network error: Address family not supported by protocol family";
  238. case WSAEALREADY:
  239. return "Network error: Operation already in progress";
  240. case WSAECONNABORTED:
  241. return "Network error: Software caused connection abort";
  242. case WSAECONNREFUSED:
  243. return "Network error: Connection refused";
  244. case WSAECONNRESET:
  245. return "Network error: Connection reset by peer";
  246. case WSAEDESTADDRREQ:
  247. return "Network error: Destination address required";
  248. case WSAEFAULT:
  249. return "Network error: Bad address";
  250. case WSAEHOSTDOWN:
  251. return "Network error: Host is down";
  252. case WSAEHOSTUNREACH:
  253. return "Network error: No route to host";
  254. case WSAEINPROGRESS:
  255. return "Network error: Operation now in progress";
  256. case WSAEINTR:
  257. return "Network error: Interrupted function call";
  258. case WSAEINVAL:
  259. return "Network error: Invalid argument";
  260. case WSAEISCONN:
  261. return "Network error: Socket is already connected";
  262. case WSAEMFILE:
  263. return "Network error: Too many open files";
  264. case WSAEMSGSIZE:
  265. return "Network error: Message too long";
  266. case WSAENETDOWN:
  267. return "Network error: Network is down";
  268. case WSAENETRESET:
  269. return "Network error: Network dropped connection on reset";
  270. case WSAENETUNREACH:
  271. return "Network error: Network is unreachable";
  272. case WSAENOBUFS:
  273. return "Network error: No buffer space available";
  274. case WSAENOPROTOOPT:
  275. return "Network error: Bad protocol option";
  276. case WSAENOTCONN:
  277. return "Network error: Socket is not connected";
  278. case WSAENOTSOCK:
  279. return "Network error: Socket operation on non-socket";
  280. case WSAEOPNOTSUPP:
  281. return "Network error: Operation not supported";
  282. case WSAEPFNOSUPPORT:
  283. return "Network error: Protocol family not supported";
  284. case WSAEPROCLIM:
  285. return "Network error: Too many processes";
  286. case WSAEPROTONOSUPPORT:
  287. return "Network error: Protocol not supported";
  288. case WSAEPROTOTYPE:
  289. return "Network error: Protocol wrong type for socket";
  290. case WSAESHUTDOWN:
  291. return "Network error: Cannot send after socket shutdown";
  292. case WSAESOCKTNOSUPPORT:
  293. return "Network error: Socket type not supported";
  294. case WSAETIMEDOUT:
  295. return "Network error: Connection timed out";
  296. case WSAEWOULDBLOCK:
  297. return "Network error: Resource temporarily unavailable";
  298. case WSAEDISCON:
  299. return "Network error: Graceful shutdown in progress";
  300. default:
  301. return "Unknown network error";
  302. }
  303. }
  304. SockAddr sk_namelookup(const char *host, char **canonicalname)
  305. {
  306. SockAddr ret = snew(struct SockAddr_tag);
  307. unsigned long a;
  308. struct hostent *h = NULL;
  309. char realhost[8192];
  310. /* Clear the structure and default to IPv4. */
  311. memset(ret, 0, sizeof(struct SockAddr_tag));
  312. ret->family = 0; /* We set this one when we have resolved the host. */
  313. *realhost = '\0';
  314. if ((a = p_inet_addr(host)) == (unsigned long) INADDR_NONE) {
  315. #ifdef IPV6
  316. /* Try to get the getaddrinfo() function from wship6.dll */
  317. /* This way one doesn't need to have IPv6 dll's to use PuTTY and
  318. * it will fallback to IPv4. */
  319. typedef int (CALLBACK * FGETADDRINFO) (const char *nodename,
  320. const char *servname,
  321. const struct addrinfo *
  322. hints,
  323. struct addrinfo ** res);
  324. FGETADDRINFO fGetAddrInfo = NULL;
  325. HINSTANCE dllWSHIP6 = LoadLibrary("wship6.dll");
  326. if (dllWSHIP6)
  327. fGetAddrInfo = (FGETADDRINFO) GetProcAddress(dllWSHIP6,
  328. "getaddrinfo");
  329. /*
  330. * Use fGetAddrInfo when it's available (which usually also
  331. * means IPv6 is installed...)
  332. */
  333. if (fGetAddrInfo) {
  334. /*debug(("Resolving \"%s\" with getaddrinfo() (IPv4+IPv6 capable)...\n", host)); */
  335. if (fGetAddrInfo(host, NULL, NULL, &ret->ai) == 0)
  336. ret->family = ret->ai->ai_family;
  337. } else
  338. #endif
  339. {
  340. /*
  341. * Otherwise use the IPv4-only gethostbyname...
  342. * (NOTE: we don't use gethostbyname as a
  343. * fallback!)
  344. */
  345. if (ret->family == 0) {
  346. /*debug(("Resolving \"%s\" with gethostbyname() (IPv4 only)...\n", host)); */
  347. if ( (h = p_gethostbyname(host)) )
  348. ret->family = AF_INET;
  349. }
  350. }
  351. /*debug(("Done resolving...(family is %d) AF_INET = %d, AF_INET6 = %d\n", ret->family, AF_INET, AF_INET6)); */
  352. if (ret->family == 0) {
  353. DWORD err = p_WSAGetLastError();
  354. ret->error = (err == WSAENETDOWN ? "Network is down" :
  355. err ==
  356. WSAHOST_NOT_FOUND ? "Host does not exist" : err
  357. == WSATRY_AGAIN ? "Host not found" :
  358. #ifdef IPV6
  359. fGetAddrInfo ? "getaddrinfo: unknown error" :
  360. #endif
  361. "gethostbyname: unknown error");
  362. #ifdef DEBUG
  363. {
  364. LPVOID lpMsgBuf;
  365. FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  366. FORMAT_MESSAGE_FROM_SYSTEM |
  367. FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err,
  368. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  369. (LPTSTR) & lpMsgBuf, 0, NULL);
  370. /*debug(("Error %ld: %s (h=%lx)\n", err, lpMsgBuf, h)); */
  371. /* Free the buffer. */
  372. LocalFree(lpMsgBuf);
  373. }
  374. #endif
  375. } else {
  376. ret->error = NULL;
  377. #ifdef IPV6
  378. /* If we got an address info use that... */
  379. if (ret->ai) {
  380. typedef int (CALLBACK * FGETNAMEINFO)
  381. (const struct sockaddr FAR * sa, socklen_t salen,
  382. char FAR * host, size_t hostlen, char FAR * serv,
  383. size_t servlen, int flags);
  384. FGETNAMEINFO fGetNameInfo = NULL;
  385. /* Are we in IPv4 fallback mode? */
  386. /* We put the IPv4 address into the a variable so we can further-on use the IPv4 code... */
  387. if (ret->family == AF_INET)
  388. memcpy(&a,
  389. (char *) &((SOCKADDR_IN *) ret->ai->
  390. ai_addr)->sin_addr, sizeof(a));
  391. /* Now let's find that canonicalname... */
  392. if ((dllWSHIP6)
  393. && (fGetNameInfo =
  394. (FGETNAMEINFO) GetProcAddress(dllWSHIP6,
  395. "getnameinfo"))) {
  396. if (fGetNameInfo
  397. ((struct sockaddr *) ret->ai->ai_addr,
  398. ret->family ==
  399. AF_INET ? sizeof(SOCKADDR_IN) :
  400. sizeof(SOCKADDR_IN6), realhost,
  401. sizeof(realhost), NULL, 0, 0) != 0) {
  402. strncpy(realhost, host, sizeof(realhost));
  403. }
  404. }
  405. }
  406. /* We used the IPv4-only gethostbyname()... */
  407. else
  408. #endif
  409. {
  410. memcpy(&a, h->h_addr, sizeof(a));
  411. /* This way we are always sure the h->h_name is valid :) */
  412. strncpy(realhost, h->h_name, sizeof(realhost));
  413. }
  414. }
  415. #ifdef IPV6
  416. FreeLibrary(dllWSHIP6);
  417. #endif
  418. } else {
  419. /*
  420. * This must be a numeric IPv4 address because it caused a
  421. * success return from inet_addr.
  422. */
  423. ret->family = AF_INET;
  424. strncpy(realhost, host, sizeof(realhost));
  425. }
  426. ret->address = p_ntohl(a);
  427. realhost[lenof(realhost)-1] = '\0';
  428. *canonicalname = snewn(1+strlen(realhost), char);
  429. strcpy(*canonicalname, realhost);
  430. return ret;
  431. }
  432. SockAddr sk_nonamelookup(const char *host)
  433. {
  434. SockAddr ret = snew(struct SockAddr_tag);
  435. ret->error = NULL;
  436. ret->family = AF_UNSPEC;
  437. strncpy(ret->hostname, host, lenof(ret->hostname));
  438. ret->hostname[lenof(ret->hostname)-1] = '\0';
  439. return ret;
  440. }
  441. void sk_getaddr(SockAddr addr, char *buf, int buflen)
  442. {
  443. #ifdef IPV6
  444. if (addr->family == AF_INET6) {
  445. FIXME; /* I don't know how to get a text form of an IPv6 address. */
  446. } else
  447. #endif
  448. if (addr->family == AF_INET) {
  449. struct in_addr a;
  450. a.s_addr = p_htonl(addr->address);
  451. strncpy(buf, p_inet_ntoa(a), buflen);
  452. buf[buflen-1] = '\0';
  453. } else {
  454. assert(addr->family == AF_UNSPEC);
  455. strncpy(buf, addr->hostname, buflen);
  456. buf[buflen-1] = '\0';
  457. }
  458. }
  459. int sk_hostname_is_local(char *name)
  460. {
  461. return !strcmp(name, "localhost");
  462. }
  463. static INTERFACE_INFO local_interfaces[16];
  464. static int n_local_interfaces; /* 0=not yet, -1=failed, >0=number */
  465. static int ipv4_is_local_addr(struct in_addr addr)
  466. {
  467. if (ipv4_is_loopback(addr))
  468. return 1; /* loopback addresses are local */
  469. if (!n_local_interfaces) {
  470. SOCKET s = p_socket(AF_INET, SOCK_DGRAM, 0);
  471. DWORD retbytes;
  472. if (p_WSAIoctl &&
  473. p_WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0,
  474. local_interfaces, sizeof(local_interfaces),
  475. &retbytes, NULL, NULL) == 0)
  476. n_local_interfaces = retbytes / sizeof(INTERFACE_INFO);
  477. else
  478. logevent(NULL, "Unable to get list of local IP addresses");
  479. }
  480. if (n_local_interfaces > 0) {
  481. int i;
  482. for (i = 0; i < n_local_interfaces; i++) {
  483. SOCKADDR_IN *address =
  484. (SOCKADDR_IN *)&local_interfaces[i].iiAddress;
  485. if (address->sin_addr.s_addr == addr.s_addr)
  486. return 1; /* this address is local */
  487. }
  488. }
  489. return 0; /* this address is not local */
  490. }
  491. int sk_address_is_local(SockAddr addr)
  492. {
  493. #ifdef IPV6
  494. if (addr->family == AF_INET6) {
  495. FIXME; /* someone who can compile for IPV6 had better do this bit */
  496. } else
  497. #endif
  498. if (addr->family == AF_INET) {
  499. struct in_addr a;
  500. a.s_addr = p_htonl(addr->address);
  501. return ipv4_is_local_addr(a);
  502. } else {
  503. assert(addr->family == AF_UNSPEC);
  504. return 0; /* we don't know; assume not */
  505. }
  506. }
  507. int sk_addrtype(SockAddr addr)
  508. {
  509. return (addr->family == AF_INET ? ADDRTYPE_IPV4 :
  510. #ifdef IPV6
  511. addr->family == AF_INET6 ? ADDRTYPE_IPV6 :
  512. #endif
  513. ADDRTYPE_NAME);
  514. }
  515. void sk_addrcopy(SockAddr addr, char *buf)
  516. {
  517. assert(addr->family != AF_UNSPEC);
  518. #ifdef IPV6
  519. if (addr->family == AF_INET6) {
  520. memcpy(buf, (char*) addr->ai, 16);
  521. } else
  522. #endif
  523. if (addr->family == AF_INET) {
  524. struct in_addr a;
  525. a.s_addr = p_htonl(addr->address);
  526. memcpy(buf, (char*) &a.s_addr, 4);
  527. }
  528. }
  529. void sk_addr_free(SockAddr addr)
  530. {
  531. sfree(addr);
  532. }
  533. static Plug sk_tcp_plug(Socket sock, Plug p)
  534. {
  535. Actual_Socket s = (Actual_Socket) sock;
  536. Plug ret = s->plug;
  537. if (p)
  538. s->plug = p;
  539. return ret;
  540. }
  541. static void sk_tcp_flush(Socket s)
  542. {
  543. /*
  544. * We send data to the socket as soon as we can anyway,
  545. * so we don't need to do anything here. :-)
  546. */
  547. }
  548. static void sk_tcp_close(Socket s);
  549. static int sk_tcp_write(Socket s, const char *data, int len);
  550. static int sk_tcp_write_oob(Socket s, const char *data, int len);
  551. static void sk_tcp_set_private_ptr(Socket s, void *ptr);
  552. static void *sk_tcp_get_private_ptr(Socket s);
  553. static void sk_tcp_set_frozen(Socket s, int is_frozen);
  554. static const char *sk_tcp_socket_error(Socket s);
  555. extern char *do_select(SOCKET skt, int startup);
  556. Socket sk_register(void *sock, Plug plug)
  557. {
  558. static const struct socket_function_table fn_table = {
  559. sk_tcp_plug,
  560. sk_tcp_close,
  561. sk_tcp_write,
  562. sk_tcp_write_oob,
  563. sk_tcp_flush,
  564. sk_tcp_set_private_ptr,
  565. sk_tcp_get_private_ptr,
  566. sk_tcp_set_frozen,
  567. sk_tcp_socket_error
  568. };
  569. DWORD err;
  570. char *errstr;
  571. Actual_Socket ret;
  572. /*
  573. * Create Socket structure.
  574. */
  575. ret = snew(struct Socket_tag);
  576. ret->fn = &fn_table;
  577. ret->error = NULL;
  578. ret->plug = plug;
  579. bufchain_init(&ret->output_data);
  580. ret->writable = 1; /* to start with */
  581. ret->sending_oob = 0;
  582. ret->frozen = 1;
  583. ret->frozen_readable = 0;
  584. ret->localhost_only = 0; /* unused, but best init anyway */
  585. ret->pending_error = 0;
  586. ret->s = (SOCKET)sock;
  587. if (ret->s == INVALID_SOCKET) {
  588. err = p_WSAGetLastError();
  589. ret->error = winsock_error_string(err);
  590. return (Socket) ret;
  591. }
  592. ret->oobinline = 0;
  593. /* Set up a select mechanism. This could be an AsyncSelect on a
  594. * window, or an EventSelect on an event object. */
  595. errstr = do_select(ret->s, 1);
  596. if (errstr) {
  597. ret->error = errstr;
  598. return (Socket) ret;
  599. }
  600. add234(sktree, ret);
  601. return (Socket) ret;
  602. }
  603. Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
  604. int nodelay, int keepalive, Plug plug)
  605. {
  606. static const struct socket_function_table fn_table = {
  607. sk_tcp_plug,
  608. sk_tcp_close,
  609. sk_tcp_write,
  610. sk_tcp_write_oob,
  611. sk_tcp_flush,
  612. sk_tcp_set_private_ptr,
  613. sk_tcp_get_private_ptr,
  614. sk_tcp_set_frozen,
  615. sk_tcp_socket_error
  616. };
  617. SOCKET s;
  618. #ifdef IPV6
  619. SOCKADDR_IN6 a6;
  620. #endif
  621. SOCKADDR_IN a;
  622. DWORD err;
  623. char *errstr;
  624. Actual_Socket ret;
  625. short localport;
  626. /*
  627. * Create Socket structure.
  628. */
  629. ret = snew(struct Socket_tag);
  630. ret->fn = &fn_table;
  631. ret->error = NULL;
  632. ret->plug = plug;
  633. bufchain_init(&ret->output_data);
  634. ret->connected = 0; /* to start with */
  635. ret->writable = 0; /* to start with */
  636. ret->sending_oob = 0;
  637. ret->frozen = 0;
  638. ret->frozen_readable = 0;
  639. ret->localhost_only = 0; /* unused, but best init anyway */
  640. ret->pending_error = 0;
  641. /*
  642. * Open socket.
  643. */
  644. assert(addr->family != AF_UNSPEC);
  645. s = p_socket(addr->family, SOCK_STREAM, 0);
  646. ret->s = s;
  647. if (s == INVALID_SOCKET) {
  648. err = p_WSAGetLastError();
  649. ret->error = winsock_error_string(err);
  650. return (Socket) ret;
  651. }
  652. ret->oobinline = oobinline;
  653. if (oobinline) {
  654. BOOL b = TRUE;
  655. p_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (void *) &b, sizeof(b));
  656. }
  657. if (nodelay) {
  658. BOOL b = TRUE;
  659. p_setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (void *) &b, sizeof(b));
  660. }
  661. if (keepalive) {
  662. BOOL b = TRUE;
  663. p_setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void *) &b, sizeof(b));
  664. }
  665. /*
  666. * Bind to local address.
  667. */
  668. if (privport)
  669. localport = 1023; /* count from 1023 downwards */
  670. else
  671. localport = 0; /* just use port 0 (ie winsock picks) */
  672. /* Loop round trying to bind */
  673. while (1) {
  674. int retcode;
  675. #ifdef IPV6
  676. if (addr->family == AF_INET6) {
  677. memset(&a6, 0, sizeof(a6));
  678. a6.sin6_family = AF_INET6;
  679. /*a6.sin6_addr = in6addr_any; *//* == 0 */
  680. a6.sin6_port = p_htons(localport);
  681. } else
  682. #endif
  683. {
  684. a.sin_family = AF_INET;
  685. a.sin_addr.s_addr = p_htonl(INADDR_ANY);
  686. a.sin_port = p_htons(localport);
  687. }
  688. #ifdef IPV6
  689. retcode = p_bind(s, (addr->family == AF_INET6 ?
  690. (struct sockaddr *) &a6 :
  691. (struct sockaddr *) &a),
  692. (addr->family ==
  693. AF_INET6 ? sizeof(a6) : sizeof(a)));
  694. #else
  695. retcode = p_bind(s, (struct sockaddr *) &a, sizeof(a));
  696. #endif
  697. if (retcode != SOCKET_ERROR) {
  698. err = 0;
  699. break; /* done */
  700. } else {
  701. err = p_WSAGetLastError();
  702. if (err != WSAEADDRINUSE) /* failed, for a bad reason */
  703. break;
  704. }
  705. if (localport == 0)
  706. break; /* we're only looping once */
  707. localport--;
  708. if (localport == 0)
  709. break; /* we might have got to the end */
  710. }
  711. if (err) {
  712. ret->error = winsock_error_string(err);
  713. return (Socket) ret;
  714. }
  715. /*
  716. * Connect to remote address.
  717. */
  718. #ifdef IPV6
  719. if (addr->family == AF_INET6) {
  720. memset(&a, 0, sizeof(a));
  721. a6.sin6_family = AF_INET6;
  722. a6.sin6_port = p_htons((short) port);
  723. a6.sin6_addr =
  724. ((struct sockaddr_in6 *) addr->ai->ai_addr)->sin6_addr;
  725. } else
  726. #endif
  727. {
  728. a.sin_family = AF_INET;
  729. a.sin_addr.s_addr = p_htonl(addr->address);
  730. a.sin_port = p_htons((short) port);
  731. }
  732. /* Set up a select mechanism. This could be an AsyncSelect on a
  733. * window, or an EventSelect on an event object. */
  734. errstr = do_select(s, 1);
  735. if (errstr) {
  736. ret->error = errstr;
  737. return (Socket) ret;
  738. }
  739. if ((
  740. #ifdef IPV6
  741. p_connect(s, ((addr->family == AF_INET6) ?
  742. (struct sockaddr *) &a6 : (struct sockaddr *) &a),
  743. (addr->family == AF_INET6) ? sizeof(a6) : sizeof(a))
  744. #else
  745. p_connect(s, (struct sockaddr *) &a, sizeof(a))
  746. #endif
  747. ) == SOCKET_ERROR) {
  748. err = p_WSAGetLastError();
  749. /*
  750. * We expect a potential EWOULDBLOCK here, because the
  751. * chances are the front end has done a select for
  752. * FD_CONNECT, so that connect() will complete
  753. * asynchronously.
  754. */
  755. if ( err != WSAEWOULDBLOCK ) {
  756. ret->error = winsock_error_string(err);
  757. return (Socket) ret;
  758. }
  759. } else {
  760. /*
  761. * If we _don't_ get EWOULDBLOCK, the connect has completed
  762. * and we should set the socket as writable.
  763. */
  764. ret->writable = 1;
  765. }
  766. add234(sktree, ret);
  767. /* We're done with 'addr' now. */
  768. sk_addr_free(addr);
  769. return (Socket) ret;
  770. }
  771. Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only)
  772. {
  773. static const struct socket_function_table fn_table = {
  774. sk_tcp_plug,
  775. sk_tcp_close,
  776. sk_tcp_write,
  777. sk_tcp_write_oob,
  778. sk_tcp_flush,
  779. sk_tcp_set_private_ptr,
  780. sk_tcp_get_private_ptr,
  781. sk_tcp_set_frozen,
  782. sk_tcp_socket_error
  783. };
  784. SOCKET s;
  785. #ifdef IPV6
  786. SOCKADDR_IN6 a6;
  787. #endif
  788. SOCKADDR_IN a;
  789. DWORD err;
  790. char *errstr;
  791. Actual_Socket ret;
  792. int retcode;
  793. int on = 1;
  794. /*
  795. * Create Socket structure.
  796. */
  797. ret = snew(struct Socket_tag);
  798. ret->fn = &fn_table;
  799. ret->error = NULL;
  800. ret->plug = plug;
  801. bufchain_init(&ret->output_data);
  802. ret->writable = 0; /* to start with */
  803. ret->sending_oob = 0;
  804. ret->frozen = 0;
  805. ret->frozen_readable = 0;
  806. ret->localhost_only = local_host_only;
  807. ret->pending_error = 0;
  808. /*
  809. * Open socket.
  810. */
  811. s = p_socket(AF_INET, SOCK_STREAM, 0);
  812. ret->s = s;
  813. if (s == INVALID_SOCKET) {
  814. err = p_WSAGetLastError();
  815. ret->error = winsock_error_string(err);
  816. return (Socket) ret;
  817. }
  818. ret->oobinline = 0;
  819. p_setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *)&on, sizeof(on));
  820. #ifdef IPV6
  821. if (addr->family == AF_INET6) {
  822. memset(&a6, 0, sizeof(a6));
  823. a6.sin6_family = AF_INET6;
  824. /* FIXME: srcaddr is ignored for IPv6, because I (SGT) don't
  825. * know how to do it. :-) */
  826. if (local_host_only)
  827. a6.sin6_addr = in6addr_loopback;
  828. else
  829. a6.sin6_addr = in6addr_any;
  830. a6.sin6_port = p_htons(port);
  831. } else
  832. #endif
  833. {
  834. int got_addr = 0;
  835. a.sin_family = AF_INET;
  836. /*
  837. * Bind to source address. First try an explicitly
  838. * specified one...
  839. */
  840. if (srcaddr) {
  841. a.sin_addr.s_addr = p_inet_addr(srcaddr);
  842. if (a.sin_addr.s_addr != INADDR_NONE) {
  843. /* Override localhost_only with specified listen addr. */
  844. ret->localhost_only = ipv4_is_loopback(a.sin_addr);
  845. got_addr = 1;
  846. }
  847. }
  848. /*
  849. * ... and failing that, go with one of the standard ones.
  850. */
  851. if (!got_addr) {
  852. if (local_host_only)
  853. a.sin_addr.s_addr = p_htonl(INADDR_LOOPBACK);
  854. else
  855. a.sin_addr.s_addr = p_htonl(INADDR_ANY);
  856. }
  857. a.sin_port = p_htons((short)port);
  858. }
  859. #ifdef IPV6
  860. retcode = p_bind(s, (addr->family == AF_INET6 ?
  861. (struct sockaddr *) &a6 :
  862. (struct sockaddr *) &a),
  863. (addr->family ==
  864. AF_INET6 ? sizeof(a6) : sizeof(a)));
  865. #else
  866. retcode = p_bind(s, (struct sockaddr *) &a, sizeof(a));
  867. #endif
  868. if (retcode != SOCKET_ERROR) {
  869. err = 0;
  870. } else {
  871. err = p_WSAGetLastError();
  872. }
  873. if (err) {
  874. ret->error = winsock_error_string(err);
  875. return (Socket) ret;
  876. }
  877. if (p_listen(s, SOMAXCONN) == SOCKET_ERROR) {
  878. p_closesocket(s);
  879. ret->error = winsock_error_string(err);
  880. return (Socket) ret;
  881. }
  882. /* Set up a select mechanism. This could be an AsyncSelect on a
  883. * window, or an EventSelect on an event object. */
  884. errstr = do_select(s, 1);
  885. if (errstr) {
  886. ret->error = errstr;
  887. return (Socket) ret;
  888. }
  889. add234(sktree, ret);
  890. return (Socket) ret;
  891. }
  892. static void sk_tcp_close(Socket sock)
  893. {
  894. extern char *do_select(SOCKET skt, int startup);
  895. Actual_Socket s = (Actual_Socket) sock;
  896. del234(sktree, s);
  897. do_select(s->s, 0);
  898. p_closesocket(s->s);
  899. sfree(s);
  900. }
  901. /*
  902. * The function which tries to send on a socket once it's deemed
  903. * writable.
  904. */
  905. void try_send(Actual_Socket s)
  906. {
  907. while (s->sending_oob || bufchain_size(&s->output_data) > 0) {
  908. int nsent;
  909. DWORD err;
  910. void *data;
  911. int len, urgentflag;
  912. if (s->sending_oob) {
  913. urgentflag = MSG_OOB;
  914. len = s->sending_oob;
  915. data = &s->oobdata;
  916. } else {
  917. urgentflag = 0;
  918. bufchain_prefix(&s->output_data, &data, &len);
  919. }
  920. nsent = p_send(s->s, data, len, urgentflag);
  921. noise_ultralight(nsent);
  922. if (nsent <= 0) {
  923. err = (nsent < 0 ? p_WSAGetLastError() : 0);
  924. if ((err < WSABASEERR && nsent < 0) || err == WSAEWOULDBLOCK) {
  925. /*
  926. * Perfectly normal: we've sent all we can for the moment.
  927. *
  928. * (Some WinSock send() implementations can return
  929. * <0 but leave no sensible error indication -
  930. * WSAGetLastError() is called but returns zero or
  931. * a small number - so we check that case and treat
  932. * it just like WSAEWOULDBLOCK.)
  933. */
  934. s->writable = FALSE;
  935. return;
  936. } else if (nsent == 0 ||
  937. err == WSAECONNABORTED || err == WSAECONNRESET) {
  938. /*
  939. * If send() returns CONNABORTED or CONNRESET, we
  940. * unfortunately can't just call plug_closing(),
  941. * because it's quite likely that we're currently
  942. * _in_ a call from the code we'd be calling back
  943. * to, so we'd have to make half the SSH code
  944. * reentrant. Instead we flag a pending error on
  945. * the socket, to be dealt with (by calling
  946. * plug_closing()) at some suitable future moment.
  947. */
  948. s->pending_error = err;
  949. return;
  950. } else {
  951. /* We're inside the Windows frontend here, so we know
  952. * that the frontend handle is unnecessary. */
  953. logevent(NULL, winsock_error_string(err));
  954. fatalbox("%s", winsock_error_string(err));
  955. }
  956. } else {
  957. if (s->sending_oob) {
  958. if (nsent < len) {
  959. memmove(s->oobdata, s->oobdata+nsent, len-nsent);
  960. s->sending_oob = len - nsent;
  961. } else {
  962. s->sending_oob = 0;
  963. }
  964. } else {
  965. bufchain_consume(&s->output_data, nsent);
  966. }
  967. }
  968. }
  969. }
  970. static int sk_tcp_write(Socket sock, const char *buf, int len)
  971. {
  972. Actual_Socket s = (Actual_Socket) sock;
  973. /*
  974. * Add the data to the buffer list on the socket.
  975. */
  976. bufchain_add(&s->output_data, buf, len);
  977. /*
  978. * Now try sending from the start of the buffer list.
  979. */
  980. if (s->writable)
  981. try_send(s);
  982. return bufchain_size(&s->output_data);
  983. }
  984. static int sk_tcp_write_oob(Socket sock, const char *buf, int len)
  985. {
  986. Actual_Socket s = (Actual_Socket) sock;
  987. /*
  988. * Replace the buffer list on the socket with the data.
  989. */
  990. bufchain_clear(&s->output_data);
  991. assert(len <= sizeof(s->oobdata));
  992. memcpy(s->oobdata, buf, len);
  993. s->sending_oob = len;
  994. /*
  995. * Now try sending from the start of the buffer list.
  996. */
  997. if (s->writable)
  998. try_send(s);
  999. return s->sending_oob;
  1000. }
  1001. int select_result(WPARAM wParam, LPARAM lParam)
  1002. {
  1003. int ret, open;
  1004. DWORD err;
  1005. char buf[20480]; /* nice big buffer for plenty of speed */
  1006. Actual_Socket s;
  1007. u_long atmark;
  1008. /* wParam is the socket itself */
  1009. if (wParam == 0)
  1010. return 1; /* boggle */
  1011. s = find234(sktree, (void *) wParam, cmpforsearch);
  1012. if (!s)
  1013. return 1; /* boggle */
  1014. if ((err = WSAGETSELECTERROR(lParam)) != 0) {
  1015. /*
  1016. * An error has occurred on this socket. Pass it to the
  1017. * plug.
  1018. */
  1019. return plug_closing(s->plug, winsock_error_string(err), err, 0);
  1020. }
  1021. noise_ultralight(lParam);
  1022. switch (WSAGETSELECTEVENT(lParam)) {
  1023. case FD_CONNECT:
  1024. s->connected = s->writable = 1;
  1025. break;
  1026. case FD_READ:
  1027. /* In the case the socket is still frozen, we don't even bother */
  1028. if (s->frozen) {
  1029. s->frozen_readable = 1;
  1030. break;
  1031. }
  1032. /*
  1033. * We have received data on the socket. For an oobinline
  1034. * socket, this might be data _before_ an urgent pointer,
  1035. * in which case we send it to the back end with type==1
  1036. * (data prior to urgent).
  1037. */
  1038. if (s->oobinline) {
  1039. atmark = 1;
  1040. p_ioctlsocket(s->s, SIOCATMARK, &atmark);
  1041. /*
  1042. * Avoid checking the return value from ioctlsocket(),
  1043. * on the grounds that some WinSock wrappers don't
  1044. * support it. If it does nothing, we get atmark==1,
  1045. * which is equivalent to `no OOB pending', so the
  1046. * effect will be to non-OOB-ify any OOB data.
  1047. */
  1048. } else
  1049. atmark = 1;
  1050. ret = p_recv(s->s, buf, sizeof(buf), 0);
  1051. noise_ultralight(ret);
  1052. if (ret < 0) {
  1053. err = p_WSAGetLastError();
  1054. if (err == WSAEWOULDBLOCK) {
  1055. break;
  1056. }
  1057. }
  1058. if (ret < 0) {
  1059. return plug_closing(s->plug, winsock_error_string(err), err,
  1060. 0);
  1061. } else if (0 == ret) {
  1062. return plug_closing(s->plug, NULL, 0, 0);
  1063. } else {
  1064. return plug_receive(s->plug, atmark ? 0 : 1, buf, ret);
  1065. }
  1066. break;
  1067. case FD_OOB:
  1068. /*
  1069. * This will only happen on a non-oobinline socket. It
  1070. * indicates that we can immediately perform an OOB read
  1071. * and get back OOB data, which we will send to the back
  1072. * end with type==2 (urgent data).
  1073. */
  1074. ret = p_recv(s->s, buf, sizeof(buf), MSG_OOB);
  1075. noise_ultralight(ret);
  1076. if (ret <= 0) {
  1077. char *str = (ret == 0 ? "Internal networking trouble" :
  1078. winsock_error_string(p_WSAGetLastError()));
  1079. /* We're inside the Windows frontend here, so we know
  1080. * that the frontend handle is unnecessary. */
  1081. logevent(NULL, str);
  1082. fatalbox("%s", str);
  1083. } else {
  1084. return plug_receive(s->plug, 2, buf, ret);
  1085. }
  1086. break;
  1087. case FD_WRITE:
  1088. {
  1089. int bufsize_before, bufsize_after;
  1090. s->writable = 1;
  1091. bufsize_before = s->sending_oob + bufchain_size(&s->output_data);
  1092. try_send(s);
  1093. bufsize_after = s->sending_oob + bufchain_size(&s->output_data);
  1094. if (bufsize_after < bufsize_before)
  1095. plug_sent(s->plug, bufsize_after);
  1096. }
  1097. break;
  1098. case FD_CLOSE:
  1099. /* Signal a close on the socket. First read any outstanding data. */
  1100. open = 1;
  1101. do {
  1102. ret = p_recv(s->s, buf, sizeof(buf), 0);
  1103. if (ret < 0) {
  1104. err = p_WSAGetLastError();
  1105. if (err == WSAEWOULDBLOCK)
  1106. break;
  1107. return plug_closing(s->plug, winsock_error_string(err),
  1108. err, 0);
  1109. } else {
  1110. if (ret)
  1111. open &= plug_receive(s->plug, 0, buf, ret);
  1112. else
  1113. open &= plug_closing(s->plug, NULL, 0, 0);
  1114. }
  1115. } while (ret > 0);
  1116. return open;
  1117. case FD_ACCEPT:
  1118. {
  1119. struct sockaddr_in isa;
  1120. int addrlen = sizeof(struct sockaddr_in);
  1121. SOCKET t; /* socket of connection */
  1122. memset(&isa, 0, sizeof(struct sockaddr_in));
  1123. err = 0;
  1124. t = p_accept(s->s,(struct sockaddr *)&isa,&addrlen);
  1125. if (t == INVALID_SOCKET)
  1126. {
  1127. err = p_WSAGetLastError();
  1128. if (err == WSATRY_AGAIN)
  1129. break;
  1130. }
  1131. if (s->localhost_only && !ipv4_is_local_addr(isa.sin_addr)) {
  1132. p_closesocket(t); /* dodgy WinSock let nonlocal through */
  1133. } else if (plug_accepting(s->plug, (void*)t)) {
  1134. p_closesocket(t); /* denied or error */
  1135. }
  1136. }
  1137. }
  1138. return 1;
  1139. }
  1140. /*
  1141. * Deal with socket errors detected in try_send().
  1142. */
  1143. void net_pending_errors(void)
  1144. {
  1145. int i;
  1146. Actual_Socket s;
  1147. /*
  1148. * This might be a fiddly business, because it's just possible
  1149. * that handling a pending error on one socket might cause
  1150. * others to be closed. (I can't think of any reason this might
  1151. * happen in current SSH implementation, but to maintain
  1152. * generality of this network layer I'll assume the worst.)
  1153. *
  1154. * So what we'll do is search the socket list for _one_ socket
  1155. * with a pending error, and then handle it, and then search
  1156. * the list again _from the beginning_. Repeat until we make a
  1157. * pass with no socket errors present. That way we are
  1158. * protected against the socket list changing under our feet.
  1159. */
  1160. do {
  1161. for (i = 0; (s = index234(sktree, i)) != NULL; i++) {
  1162. if (s->pending_error) {
  1163. /*
  1164. * An error has occurred on this socket. Pass it to the
  1165. * plug.
  1166. */
  1167. plug_closing(s->plug,
  1168. winsock_error_string(s->pending_error),
  1169. s->pending_error, 0);
  1170. break;
  1171. }
  1172. }
  1173. } while (s);
  1174. }
  1175. /*
  1176. * Each socket abstraction contains a `void *' private field in
  1177. * which the client can keep state.
  1178. */
  1179. static void sk_tcp_set_private_ptr(Socket sock, void *ptr)
  1180. {
  1181. Actual_Socket s = (Actual_Socket) sock;
  1182. s->private_ptr = ptr;
  1183. }
  1184. static void *sk_tcp_get_private_ptr(Socket sock)
  1185. {
  1186. Actual_Socket s = (Actual_Socket) sock;
  1187. return s->private_ptr;
  1188. }
  1189. /*
  1190. * Special error values are returned from sk_namelookup and sk_new
  1191. * if there's a problem. These functions extract an error message,
  1192. * or return NULL if there's no problem.
  1193. */
  1194. const char *sk_addr_error(SockAddr addr)
  1195. {
  1196. return addr->error;
  1197. }
  1198. static const char *sk_tcp_socket_error(Socket sock)
  1199. {
  1200. Actual_Socket s = (Actual_Socket) sock;
  1201. return s->error;
  1202. }
  1203. static void sk_tcp_set_frozen(Socket sock, int is_frozen)
  1204. {
  1205. Actual_Socket s = (Actual_Socket) sock;
  1206. if (s->frozen == is_frozen)
  1207. return;
  1208. s->frozen = is_frozen;
  1209. if (!is_frozen && s->frozen_readable) {
  1210. char c;
  1211. p_recv(s->s, &c, 1, MSG_PEEK);
  1212. }
  1213. s->frozen_readable = 0;
  1214. }
  1215. /*
  1216. * For Plink: enumerate all sockets currently active.
  1217. */
  1218. SOCKET first_socket(int *state)
  1219. {
  1220. Actual_Socket s;
  1221. *state = 0;
  1222. s = index234(sktree, (*state)++);
  1223. return s ? s->s : INVALID_SOCKET;
  1224. }
  1225. SOCKET next_socket(int *state)
  1226. {
  1227. Actual_Socket s = index234(sktree, (*state)++);
  1228. return s ? s->s : INVALID_SOCKET;
  1229. }
  1230. int net_service_lookup(char *service)
  1231. {
  1232. struct servent *se;
  1233. se = p_getservbyname(service, NULL);
  1234. if (se != NULL)
  1235. return p_ntohs(se->s_port);
  1236. else
  1237. return 0;
  1238. }
  1239. SockAddr platform_get_x11_unix_address(int displaynum, char **canonicalname)
  1240. {
  1241. SockAddr ret = snew(struct SockAddr_tag);
  1242. memset(ret, 0, sizeof(struct SockAddr_tag));
  1243. ret->error = "unix sockets not supported on this platform";
  1244. return ret;
  1245. }