jsocket.hpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. // Socket abstraction
  14. #ifndef __JSOCKIO_H__
  15. #define __JSOCKIO_H__
  16. #ifndef _VER_C5
  17. #include <time.h>
  18. #endif
  19. #include "jiface.hpp"
  20. #include "jexcept.hpp"
  21. #include "jthread.hpp"
  22. #if 0 // spurious mplink closed tracing info
  23. # define _TRACELINKCLOSED
  24. #endif
  25. #define DEFAULT_LISTEN_QUEUE_SIZE 200 // maximum for windows 2000 server
  26. #define DEFAULT_LINGER_TIME 1000 // seconds
  27. #ifndef WAIT_FOREVER
  28. #define WAIT_FOREVER ((unsigned)-1)
  29. #endif
  30. enum JSOCKET_ERROR_CODES {
  31. JSOCKERR_ok = 0,
  32. JSOCKERR_not_opened = -1, // accept,name,peer_name,read,write
  33. JSOCKERR_bad_address = -2, // connect
  34. JSOCKERR_connection_failed = -3, // connect
  35. JSOCKERR_broken_pipe = -4, // read,write
  36. JSOCKERR_invalid_access_mode = -5, // accept
  37. JSOCKERR_timeout_expired = -6, // read
  38. JSOCKERR_port_in_use = -7, // create
  39. JSOCKERR_cancel_accept = -8, // accept
  40. JSOCKERR_connectionless_socket = -9, // accept, cancel_accept
  41. JSOCKERR_graceful_close = -10, // read,send
  42. JSOCKERR_handle_too_large = -11, // select, connect etc (linux only)
  43. JSOCKERR_bad_netaddr = -12, // get/set net address
  44. JSOCKERR_ipv6_not_implemented = -13 // various
  45. };
  46. // Block operation flags
  47. #define BF_ASYNC_TRANSFER 0 // send_block sends immediately (default)
  48. #define BF_SYNC_TRANSFER_PULL 1 // send_block waits until receiver ready (i.e. receives first)
  49. #define BF_LZW_COMPRESS 2 // compress using LZW compression
  50. #define BF_REC_COMPRESS 4 // compress using record difference compression
  51. #define BF_RELIABLE_TRANSFER 8 // retries on socket failure
  52. #define BF_SYNC_TRANSFER_PUSH 16 // send_block pushes that has data (i.e. sends first)
  53. // shutdown options
  54. #define SHUTDOWN_READ 0
  55. #define SHUTDOWN_WRITE 1
  56. #define SHUTDOWN_READWRITE 2
  57. #ifndef _WIN32
  58. #define BLOCK_POLLED_SINGLE_CONNECTS // NB this is much slower in windows
  59. #define CENTRAL_NODE_RANDOM_DELAY
  60. #else
  61. #define USERECVSEM // to singlethread BF_SYNC_TRANSFER_PUSH
  62. #endif
  63. //
  64. // Abstract socket interface
  65. //
  66. class jlib_decl IpAddress
  67. {
  68. unsigned netaddr[4] = { 0, 0, 0, 0 };
  69. public:
  70. IpAddress() = default;
  71. IpAddress(const IpAddress& other) { ipset(other); }
  72. explicit IpAddress(const char *text) { ipset(text); }
  73. bool ipset(const char *text); // sets to NULL if fails or text=NULL
  74. void ipset(const IpAddress& other) { memcpy(&netaddr,&other.netaddr,sizeof(netaddr)); }
  75. bool ipequals(const IpAddress & other) const;
  76. int ipcompare(const IpAddress & other) const; // depreciated
  77. unsigned iphash(unsigned prev=0) const;
  78. unsigned fasthash() const;
  79. bool isNull() const; // is null
  80. bool isHost() const; // is primary host NIC ip
  81. bool isLoopBack() const; // is loopback (localhost: 127.0.0.1 or ::1)
  82. bool isLocal() const; // matches local interface
  83. bool isIp4() const;
  84. StringBuffer &getIpText(StringBuffer & out) const;
  85. void ipserialize(MemoryBuffer & out) const;
  86. void ipdeserialize(MemoryBuffer & in);
  87. unsigned ipdistance(const IpAddress &ip,unsigned offset=0) const; // network order distance (offset: 0-3 word (leat sig.), 0=Ipv4)
  88. unsigned getIP4() const;
  89. void setIP4(unsigned);
  90. bool ipincrement(unsigned count,byte minoctet=0,byte maxoctet=255,unsigned short minipv6piece=0,unsigned maxipv6piece=0xffff);
  91. unsigned ipsetrange( const char *text); // e.g. 10.173.72.1-65 ('-' may be omitted)
  92. // returns number in range (use ipincrement to iterate through)
  93. size32_t getNetAddress(size32_t maxsz,void *dst) const; // for internal use - returns 0 if address doesn't fit
  94. void setNetAddress(size32_t sz,const void *src); // for internal use
  95. inline bool operator == ( const IpAddress & other) const { return ipequals(other); }
  96. inline IpAddress & operator = ( const IpAddress &other )
  97. {
  98. ipset(other);
  99. return *this;
  100. }
  101. };
  102. struct IpComparator
  103. {
  104. bool operator()(const IpAddress &a, const IpAddress &b) const
  105. {
  106. // return true if the first argument goes before the second argument, and false otherwise
  107. return a.ipcompare(b) < 0;
  108. }
  109. };
  110. class jlib_decl IpAddressArray : public StructArrayOf<IpAddress>
  111. {
  112. public:
  113. StringBuffer &getText(StringBuffer &text);
  114. void fromText(const char *s,unsigned defport);
  115. };
  116. extern jlib_decl IpAddress & queryHostIP();
  117. extern jlib_decl IpAddress & queryLocalIP();
  118. extern jlib_decl const char * GetCachedHostName();
  119. inline StringBuffer & GetHostName(StringBuffer &str) { return str.append(GetCachedHostName()); }
  120. extern jlib_decl IpAddress &GetHostIp(IpAddress &ip);
  121. extern jlib_decl IpAddress &localHostToNIC(IpAddress &ip);
  122. class jlib_decl SocketEndpoint : extends IpAddress
  123. {
  124. public:
  125. SocketEndpoint() = default;
  126. SocketEndpoint(const char *name,unsigned short _port=0) { set(name,_port); };
  127. SocketEndpoint(unsigned short _port) { setLocalHost(_port); };
  128. SocketEndpoint(unsigned short _port, const IpAddress & _ip) { set(_port,_ip); };
  129. SocketEndpoint(const SocketEndpoint &other) = default;
  130. void deserialize(MemoryBuffer & in);
  131. void serialize(MemoryBuffer & out) const;
  132. bool set(const char *name,unsigned short _port=0);
  133. inline void set(const SocketEndpoint & value) { ipset(value); port = value.port; }
  134. inline void setLocalHost(unsigned short _port) { port = _port; GetHostIp(*this); } // NB *not* localhost(127.0.0.1)
  135. inline void set(unsigned short _port, const IpAddress & _ip) { ipset(_ip); port = _port; };
  136. inline bool equals(const SocketEndpoint &ep) const { return ((port==ep.port)&&ipequals(ep)); }
  137. void getUrlStr(char * str, size32_t len) const; // in form ip4:port or [ip6]:port
  138. StringBuffer &getUrlStr(StringBuffer &str) const; // in form ip4:port or [ip6]:port
  139. inline SocketEndpoint & operator = ( const SocketEndpoint &other )
  140. {
  141. ipset(other);
  142. port = other.port;
  143. return *this;
  144. }
  145. bool operator == (const SocketEndpoint &other) const { return equals(other); }
  146. bool operator != (const SocketEndpoint &other) const { return !equals(other); }
  147. bool operator < (const SocketEndpoint &other) const { int cp = ipcompare(other); return cp<0 || (cp==0 && (port < other.port)); }
  148. unsigned hash(unsigned prev) const;
  149. unsigned short port = 0;
  150. // Ensure that all the bytes in the data structure are initialised to avoid complains from valgrind when it is written to a socket
  151. unsigned short portPadding = 0;
  152. };
  153. class jlib_decl SocketEndpointArray : public StructArrayOf<SocketEndpoint>
  154. {
  155. public:
  156. StringBuffer &getText(StringBuffer &text) const;
  157. bool fromName(const char *name, unsigned defport);
  158. void fromText(const char *s,unsigned defport);
  159. };
  160. interface ISocketEndpointHashTable: implements IInterface
  161. {
  162. virtual void add(const SocketEndpoint &ep, IInterface *i)=0; // takes ownership
  163. virtual void remove(const SocketEndpoint &ep)=0; // releases
  164. virtual IInterface *find(const SocketEndpoint &ep)=0; // does not link
  165. };
  166. extern jlib_decl ISocketEndpointHashTable *createSocketEndpointHashTable();
  167. class jlib_decl IpSubNet
  168. {
  169. unsigned net[4];
  170. unsigned mask[4];
  171. public:
  172. IpSubNet() {set(NULL,NULL); }
  173. IpSubNet(const char *_net,const char *_mask) { set(_net,_mask); }
  174. bool set(const char *_net,const char *_mask); // _net NULL means match everything
  175. // _mask NULL means match exact
  176. bool test(const IpAddress &ip) const;
  177. StringBuffer &getNetText(StringBuffer &text) const;
  178. StringBuffer &getMaskText(StringBuffer &text) const;
  179. bool isNull() const;
  180. bool operator==(IpSubNet const &other) const
  181. {
  182. if ((0 == memcmp(net, other.net, sizeof(net))) && (0 == memcmp(mask, other.mask, sizeof(mask))))
  183. return true;
  184. return false;
  185. }
  186. };
  187. class jlib_decl ISocket : extends IInterface
  188. {
  189. public:
  190. //
  191. // Create client socket connected to a TCP server socket
  192. static ISocket* connect( const SocketEndpoint &ep );
  193. // general connect
  194. static ISocket* connect_timeout( const SocketEndpoint &ep , unsigned timeout);
  195. // connect where should must take longer than timeout (in ms) to connect
  196. static ISocket* connect_wait( const SocketEndpoint &ep, unsigned timems);
  197. // connect where should try connecting for *at least* time specified
  198. // (e.g. if don't know that server listening yet)
  199. // if 0 specified for time then does single (blocking) connect try
  200. // Create client socket connected to a UDP server socket
  201. //
  202. static ISocket* udp_connect( unsigned short port, char const* host);
  203. static ISocket* udp_connect( const SocketEndpoint &ep);
  204. //
  205. // Create server TCP socket
  206. //
  207. static ISocket* create( unsigned short port,
  208. int listen_queue_size = DEFAULT_LISTEN_QUEUE_SIZE);
  209. //
  210. // Create server TCP socket listening a specific IP
  211. //
  212. static ISocket* create_ip( unsigned short port,
  213. const char *host,
  214. int listen_queue_size = DEFAULT_LISTEN_QUEUE_SIZE);
  215. //
  216. // Create server UDP socket
  217. //
  218. static ISocket* udp_create( unsigned short port);
  219. // Create client socket connected to a multicast server socket
  220. //
  221. static ISocket* multicast_connect( unsigned short port, const char *mcgroupip, unsigned _ttl);
  222. static ISocket* multicast_connect( const SocketEndpoint &ep, unsigned _ttl);
  223. //
  224. // Create server multicast socket
  225. //
  226. static ISocket* multicast_create( unsigned short port, const char *mcgroupip, unsigned _ttl);
  227. static ISocket* multicast_create( unsigned short port, const IpAddress &mcgroupip, unsigned _ttl);
  228. //
  229. // Creates an ISocket for an already created socket
  230. //
  231. static ISocket* attach(int s,bool tcpip=true);
  232. virtual void read(void* buf, size32_t min_size, size32_t max_size, size32_t &size_read,
  233. unsigned timeoutsecs = WAIT_FOREVER) = 0;
  234. virtual void readtms(void* buf, size32_t min_size, size32_t max_size, size32_t &size_read,
  235. unsigned timeout) = 0;
  236. virtual void read(void* buf, size32_t size) = 0;
  237. virtual size32_t write(void const* buf, size32_t size) = 0; // returns amount written normally same as in size (see set_nonblock)
  238. virtual size32_t writetms(void const* buf, size32_t size, unsigned timeoutms=WAIT_FOREVER) = 0;
  239. virtual size32_t get_max_send_size() = 0;
  240. //
  241. // This method is called by server to accept client connection
  242. //
  243. virtual ISocket* accept(bool allowcancel=false, SocketEndpoint *peerEp = nullptr) = 0; // not needed for UDP
  244. //
  245. // log poll() errors
  246. //
  247. virtual int logPollError(unsigned revents, const char *rwstr) = 0;
  248. //
  249. // This method is called to check whether a socket has data ready
  250. //
  251. virtual int wait_read(unsigned timeout) = 0;
  252. //
  253. // This method is called to check whether a socket is ready to write (i.e. some free buffer space)
  254. //
  255. virtual int wait_write(unsigned timeout) = 0;
  256. //
  257. // can be used with write to allow it to return if it would block
  258. // be sure and restore to old state before calling other functions on this socket
  259. //
  260. virtual bool set_nonblock(bool on) = 0; // returns old state
  261. // enable 'nagling' - small packet coalescing (implies delayed transmission)
  262. //
  263. virtual bool set_nagle(bool on) = 0; // returns old state
  264. // set 'linger' time - time close will linger so that outstanding unsent data will be transmitted
  265. //
  266. virtual void set_linger(int lingersecs) = 0;
  267. //
  268. // Cancel accept operation and close socket
  269. //
  270. virtual void cancel_accept() = 0; // not needed for UDP
  271. //
  272. // Shutdown socket: prohibit write and/or read operations on socket
  273. //
  274. virtual void shutdown(unsigned mode=SHUTDOWN_READWRITE) = 0; // not needed for UDP
  275. // Same as shutdown, but never throws an exception (to call from closedown destructors)
  276. virtual void shutdownNoThrow(unsigned mode=SHUTDOWN_READWRITE) = 0; // not needed for UDP
  277. // Get local name of accepted (or connected) socket and returns port
  278. virtual int name(char *name,size32_t namemax)=0;
  279. // Get peer name of socket and returns port - in UDP returns return addr
  280. virtual int peer_name(char *name,size32_t namemax)=0;
  281. // Get peer endpoint of socket - in UDP returns return addr
  282. virtual SocketEndpoint &getPeerEndpoint(SocketEndpoint &ep)=0;
  283. // Get peer ip of socket - in UDP returns return addr
  284. virtual IpAddress &getPeerAddress(IpAddress &addr)=0;
  285. // Get local endpoint of socket
  286. virtual SocketEndpoint &getEndpoint(SocketEndpoint &ep) const = 0;
  287. //
  288. // Close socket
  289. //
  290. virtual bool connectionless()=0; // true if accept need not be called (i.e. UDP)
  291. virtual void set_return_addr(int port,const char *name) = 0; // used for UDP servers only
  292. // Block functions
  293. virtual void set_block_mode ( // must be called before block operations
  294. unsigned flags, // BF_* flags (must match receive_block)
  295. size32_t recsize=0, // record size (required for rec compression)
  296. unsigned timeoutms=0 // timeout in milisecs (0 for no timeout)
  297. )=0;
  298. virtual bool send_block(
  299. const void *blk, // data to send
  300. size32_t sz // size to send (0 for eof)
  301. )=0;
  302. virtual size32_t receive_block_size ()=0; // get size of next block (always must call receive_block after)
  303. virtual size32_t receive_block(
  304. void *blk, // receive pointer
  305. size32_t sz // max size to read (0 for sync eof)
  306. // if less than block size truncates block
  307. )=0;
  308. virtual void close() = 0;
  309. virtual unsigned OShandle() const = 0; // for internal use
  310. virtual size32_t avail_read() = 0; // called after wait_read to see how much data available
  311. virtual size32_t write_multiple(unsigned num,void const**buf, size32_t *size) = 0; // same as write except writes multiple blocks
  312. virtual size32_t get_send_buffer_size() =0; // get OS send buffer
  313. virtual void set_send_buffer_size(size32_t sz) =0; // set OS send buffer size
  314. virtual bool join_multicast_group(SocketEndpoint &ep) = 0; // for udp multicast
  315. virtual bool leave_multicast_group(SocketEndpoint &ep) = 0; // for udp multicast
  316. virtual void set_ttl(unsigned _ttl) = 0; // set TTL
  317. virtual size32_t get_receive_buffer_size() = 0; // get OS receive buffer
  318. virtual void set_receive_buffer_size(size32_t sz) = 0; // set OS receive buffer size
  319. virtual void set_keep_alive(bool set) = 0; // set option SO_KEEPALIVE
  320. virtual size32_t udp_write_to(const SocketEndpoint &ep,void const* buf, size32_t size) = 0;
  321. virtual bool check_connection() = 0;
  322. virtual bool isSecure() const = 0;
  323. virtual bool isValid() const = 0;
  324. /*
  325. Exceptions raised: (when set_raise_exceptions(TRUE))
  326. create
  327. sys:(socket, bind, listen)
  328. udp_create
  329. sys:(socket, bind, listen)
  330. accept
  331. JSOCKERR_not_opened, sys:(accept,setsockopt), JSOCKERR_invalid_access_mode, JSOCKERR_cancel_accept, JSOCKERR_connectionless_socket
  332. name
  333. JSOCKERR_not_opened, sys:(getsockname)
  334. peer_name
  335. JSOCKERR_not_opened, sys:(getpeername)
  336. cancel_accept
  337. {connect}, sys:(gethostname), JSOCKERR_connectionless_socket
  338. connect
  339. JSOCKERR_bad_address, JSOCKERR_connection_failed, sys:(socket, connect, setsockopt)
  340. udp_connect
  341. JSOCKERR_bad_address, sys:(socket, connect, setsockopt)
  342. read (timeout)
  343. JSOCKERR_not_opened, JSOCKERR_broken_pipe, JSOCKERR_timeout_expired ,sys:(select, read), JSOCKERR_graceful_close
  344. read (no timeout)
  345. JSOCKERR_not_opened, JSOCKERR_broken_pipe, sys:(read), JSOCKERR_graceful_close
  346. write
  347. JSOCKERR_not_opened, JSOCKERR_broken_pipe, sys:(write), JSOCKERR_graceful_close
  348. close
  349. sys:(write)
  350. shutdown
  351. sys:(shutdown),JSOCKERR_broken_pipe
  352. */
  353. };
  354. interface jlib_thrown_decl IJSOCK_Exception: extends IException
  355. {
  356. };
  357. extern jlib_decl IJSOCK_Exception *IPv6NotImplementedException(const char *filename,unsigned lineno);
  358. #define IPV6_NOT_IMPLEMENTED() throw IPv6NotImplementedException(sanitizeSourceFile(__FILE__), __LINE__)
  359. #ifdef USERECVSEM
  360. class CSemProtect
  361. {
  362. Semaphore *sem;
  363. bool *owned;
  364. public:
  365. CSemProtect() { clear(); }
  366. ~CSemProtect()
  367. {
  368. if (sem&&*owned) {
  369. *owned = false;
  370. sem->signal();
  371. }
  372. }
  373. void set(Semaphore *_sem,bool *_owned)
  374. {
  375. sem = _sem;
  376. owned = _owned;
  377. }
  378. bool wait(Semaphore *_sem,bool *_owned,unsigned timeout) {
  379. if (!*_owned&&!_sem->wait(timeout))
  380. return false;
  381. *_owned = true;
  382. set(_sem,_owned);
  383. return true;
  384. }
  385. void clear() { sem = NULL; owned = NULL; }
  386. };
  387. #endif
  388. //---------------------------------------------------------------------------
  389. // These classes are useful for compressing a list of ip:ports to pass around.
  390. class jlib_decl SocketListCreator
  391. {
  392. public:
  393. SocketListCreator();
  394. void addSocket(const SocketEndpoint &ep);
  395. void addSocket(const char * ip, unsigned port);
  396. const char * getText();
  397. void addSockets(SocketEndpointArray &array);
  398. protected:
  399. StringBuffer fullText;
  400. StringAttr lastIp;
  401. unsigned lastPort;
  402. };
  403. class jlib_decl SocketListParser
  404. // This class depreciated - new code should use SocketEndpointArray::fromText and getText
  405. {
  406. public:
  407. SocketListParser(const char * text);
  408. void first(unsigned defport=0);
  409. bool get(StringAttr & ip, unsigned & port, unsigned index, unsigned defport=0); // alternative to iterating..
  410. bool next(StringAttr & ip, unsigned & port);
  411. unsigned getSockets(SocketEndpointArray &array,unsigned defport=0);
  412. protected:
  413. StringAttr fullText;
  414. StringAttr lastIp;
  415. const char * cursor;
  416. unsigned lastPort;
  417. };
  418. struct JSocketStatistics
  419. {
  420. unsigned connects; // successful
  421. unsigned connecttime; // all times in microsecs
  422. unsigned failedconnects;
  423. unsigned failedconnecttime;
  424. unsigned reads;
  425. unsigned readtime;
  426. __int64 readsize; // all sizes in bytes
  427. unsigned writes;
  428. unsigned writetime;
  429. __int64 writesize;
  430. unsigned activesockets;
  431. unsigned numblockrecvs;
  432. unsigned numblocksends;
  433. __int64 blockrecvsize;
  434. __int64 blocksendsize;
  435. unsigned blockrecvtime; // not including initial handshake
  436. unsigned blocksendtime;
  437. unsigned longestblocksend;
  438. unsigned longestblocksize;
  439. };
  440. extern jlib_decl JSocketStatistics *getSocketStatPtr();
  441. extern jlib_decl void getSocketStatistics(JSocketStatistics &stats);
  442. extern jlib_decl void resetSocketStatistics();
  443. extern jlib_decl StringBuffer &getSocketStatisticsString(JSocketStatistics &stats,StringBuffer &buf);
  444. // Select Thread
  445. #define SELECTMODE_READ 1
  446. #define SELECTMODE_WRITE 2
  447. #define SELECTMODE_EXCEPT 4
  448. interface ISocketSelectNotify: extends IInterface
  449. {
  450. virtual bool notifySelected(ISocket *sock,unsigned selected)=0; // return false to continue to next selected, true to re-select
  451. };
  452. interface ISocketSelectHandler: extends IInterface
  453. {
  454. public:
  455. virtual void start()=0;
  456. virtual void add(ISocket *sock,unsigned mode,ISocketSelectNotify *nfy)=0;
  457. virtual void remove(ISocket *sock)=0;
  458. virtual void stop(bool wait)=0;
  459. };
  460. extern jlib_decl ISocketSelectHandler *createSocketSelectHandler(const char *trc=NULL, unsigned hdlPerThrd=0);
  461. extern jlib_decl ISocketSelectHandler *createSocketEpollHandler(const char *trc=NULL, unsigned hdlPerThrd=0);
  462. class MemoryBuffer;
  463. // sends/receives length as well as contents.
  464. extern jlib_decl void readBuffer(ISocket * socket, MemoryBuffer & buffer);
  465. extern jlib_decl void readBuffer(ISocket * socket, MemoryBuffer & buffer, unsigned timeoutms);
  466. extern jlib_decl void writeBuffer(ISocket * socket, MemoryBuffer & buffer);
  467. // ditto but catches any exceptions
  468. extern jlib_decl bool catchReadBuffer(ISocket * socket, MemoryBuffer & buffer);
  469. extern jlib_decl bool catchReadBuffer(ISocket * socket, MemoryBuffer & buffer, unsigned timeoutms);
  470. extern jlib_decl bool catchWriteBuffer(ISocket * socket, MemoryBuffer & buffer);
  471. // utility interface for simple conversations
  472. // conversation is always between two ends,
  473. // at any given time one end must be receiving and other sending (though these may swap during the conversation)
  474. interface IConversation: extends IInterface
  475. {
  476. virtual bool accept(unsigned timeoutms)=0; // one side accepts
  477. virtual void set_keep_alive(bool keepalive)=0; // enable keepalive for socket
  478. virtual bool connect(unsigned timeoutms)=0; // other side connects
  479. virtual bool send(MemoryBuffer &mb)=0; // 0 length buffer can be sent
  480. virtual bool recv(MemoryBuffer &mb, unsigned timeoutms)=0; // up to protocol to terminate conversation (e.g. by zero length buffer)
  481. virtual void cancel()=0; // cancels above methods (from separate thread)
  482. virtual unsigned short setRandomPort(unsigned short base, unsigned num)=0; // sets a random unique port for accept use
  483. };
  484. extern jlib_decl IConversation *createSingletonSocketConnection(unsigned short port,SocketEndpoint *ep=NULL);
  485. // the end that listens may omit ep
  486. // this function does not connect so raises no socket exceptions
  487. // interface for reading from multiple sockets using the BF_SYNC_TRANSFER_PUSH protocol
  488. interface ISocketBufferReader: extends IInterface
  489. {
  490. public:
  491. virtual void init(unsigned num,ISocket **sockets,size32_t buffermax=(unsigned)-1)=0;
  492. virtual unsigned get(MemoryBuffer &mb)=0;
  493. virtual void done(bool wait)=0;
  494. };
  495. extern jlib_decl ISocketBufferReader *createSocketBufferReader(const char *trc=NULL);
  496. extern jlib_decl void markNodeCentral(SocketEndpoint &ep); // random delay for linux
  497. interface ISocketConnectNotify
  498. {
  499. public:
  500. virtual void connected(unsigned idx,const SocketEndpoint &ep,ISocket *socket)=0; // must link socket if kept
  501. virtual void failed(unsigned idx,const SocketEndpoint &ep,int err)=0;
  502. };
  503. extern jlib_decl void multiConnect(const SocketEndpointArray &eps,ISocketConnectNotify &inotify,unsigned timeout);
  504. extern jlib_decl void multiConnect(const SocketEndpointArray &eps,IPointerArrayOf<ISocket> &retsockets,unsigned timeout);
  505. interface ISocketConnectWait: extends IInterface
  506. {
  507. public:
  508. virtual ISocket *wait(unsigned waittimems)=0; // return NULL if time expired, throws exception if connect failed
  509. // releasing ISocketConnectWait cancels the connect iff wait has never returned socket
  510. };
  511. extern jlib_decl ISocketConnectWait *nonBlockingConnect(SocketEndpoint &ep,unsigned connectimeoutms=0);
  512. // buffered socket
  513. interface IBufferedSocket : implements IInterface
  514. {
  515. virtual int readline(char* buf, int maxlen, IMultiException *me) = 0;
  516. virtual int read(char* buf, int maxlen) = 0;
  517. virtual int readline(char* buf, int maxlen, bool keepcrlf, IMultiException *me) = 0;
  518. virtual void setReadTimeout(unsigned int timeout) = 0;
  519. };
  520. #define BSOCKET_READ_TIMEOUT 600
  521. #define BSOCKET_CLIENT_READ_TIMEOUT 7200
  522. extern jlib_decl IBufferedSocket* createBufferedSocket(ISocket* socket);
  523. #define MAX_NET_ADDRESS_SIZE (16)
  524. extern jlib_decl IpSubNet &queryPreferredSubnet(); // preferred subnet when resolving multiple NICs
  525. extern jlib_decl bool setPreferredSubnet(const char *ip,const char *mask); // also resets cached host IP
  526. extern jlib_decl StringBuffer &lookupHostName(const IpAddress &ip,StringBuffer &ret);
  527. extern jlib_decl bool isInterfaceIp(const IpAddress &ip, const char *ifname);
  528. extern jlib_decl bool getInterfaceIp(IpAddress &ip, const char *ifname);
  529. extern jlib_decl bool getInterfaceName(StringBuffer &ifname);
  530. //Given a list of server sockets, wait until any one or more are ready to be read/written (wont block)
  531. //return array of ready sockets
  532. extern jlib_decl int wait_read_multiple(UnsignedArray &socks, //IN sockets to be checked for read readiness
  533. unsigned timeoutMS, //IN timeout
  534. UnsignedArray &readySocks);//OUT sockets ready to be read
  535. extern jlib_decl int wait_write_multiple(UnsignedArray &socks, //IN sockets to be checked for write readiness
  536. unsigned timeoutMS, //IN timeout
  537. UnsignedArray &readySocks);//OUT sockets ready to be written
  538. extern jlib_decl void throwJSocketException(int jsockErr);
  539. extern jlib_decl IJSOCK_Exception* createJSocketException(int jsockErr, const char *_msg);
  540. extern jlib_decl bool isIPV4(const char *ip);
  541. extern jlib_decl bool isIPV6(const char *ip);
  542. extern jlib_decl bool isIPAddress(const char *ip);
  543. interface IAllowListHandler : extends IInterface
  544. {
  545. virtual bool isAllowListed(const char *ip, unsigned __int64 role, StringBuffer *responseText=nullptr) const = 0;
  546. virtual StringBuffer &getAllowList(StringBuffer &out) const = 0;
  547. virtual void refresh() = 0;
  548. };
  549. interface IAllowListWriter : extends IInterface
  550. {
  551. virtual void add(const char *ip, unsigned __int64 role) = 0;
  552. virtual void setAllowAnonRoles(bool tf) = 0;
  553. };
  554. typedef std::function<bool(IAllowListWriter &)> AllowListPopulateFunction;
  555. typedef std::function<StringBuffer &(StringBuffer &, unsigned __int64)> AllowListFormatFunction;
  556. extern jlib_decl IAllowListHandler *createAllowListHandler(AllowListPopulateFunction populateFunc, AllowListFormatFunction roleFormatFunc = {}); // format function optional
  557. // utility interface for simple conversations
  558. // conversation is always between two ends,
  559. // at any given time one end must be receiving and other sending (though these may swap during the conversation)
  560. class jlib_decl CSingletonSocketConnection: implements IConversation, public CInterface
  561. {
  562. public:
  563. Owned<ISocket> sock;
  564. Owned<ISocket> listensock;
  565. enum { Snone, Saccept, Sconnect, Srecv, Ssend, Scancelled } state;
  566. bool cancelling = false;
  567. SocketEndpoint ep;
  568. CriticalSection crit;
  569. IMPLEMENT_IINTERFACE;
  570. CSingletonSocketConnection() {}
  571. CSingletonSocketConnection(SocketEndpoint &_ep);
  572. virtual ~CSingletonSocketConnection();
  573. void set_keep_alive(bool keepalive);
  574. virtual bool connect(unsigned timeoutms);
  575. bool send(MemoryBuffer &mb);
  576. unsigned short setRandomPort(unsigned short base, unsigned num);
  577. virtual bool accept(unsigned timeoutms);
  578. bool recv(MemoryBuffer &mb, unsigned timeoutms);
  579. virtual void cancel();
  580. };
  581. extern jlib_decl void shutdownAndCloseNoThrow(ISocket * optSocket); // Safely shutdown and close a socket without throwing an exception.
  582. #endif