From 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d Mon Sep 17 00:00:00 2001 From: Jef Date: Tue, 24 Sep 2024 14:54:57 +0200 Subject: Initial community commit --- Src/replicant/jnetlib/udpconnection.h | 151 ++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 Src/replicant/jnetlib/udpconnection.h (limited to 'Src/replicant/jnetlib/udpconnection.h') diff --git a/Src/replicant/jnetlib/udpconnection.h b/Src/replicant/jnetlib/udpconnection.h new file mode 100644 index 00000000..c91d8422 --- /dev/null +++ b/Src/replicant/jnetlib/udpconnection.h @@ -0,0 +1,151 @@ +/* +** JNetLib +** Copyright (C) 2000-2001 Nullsoft, Inc. +** Author: Justin Frankel +** File: udpconnection.h - JNL UDP connection interface +** License: see jnetlib.h +** +** Usage: +** 1. Create a JNL_Connection object, optionally specifying a JNL_AsyncDNS +** object to use (or NULL for none, or WAC_NETWORK_CONNECTION_AUTODNS for auto), +** and the send and receive buffer sizes. +** 2. Call connect() to have it connect to a host/port (the hostname will be +** resolved if possible). +** 3. call run() with the maximum send/recv amounts, and optionally parameters +** so you can tell how much has been send/received. You want to do this a lot, while: +** 4. check get_state() to check the state of the connection. The states are: +** JNL_Connection::STATE_ERROR +** - an error has occured on the connection. the connection has closed, +** and you can no longer write to the socket (there still might be +** data in the receive buffer - use recv_bytes_available()). +** JNL_Connection::STATE_NOCONNECTION +** - no connection has been made yet. call connect() already! :) +** JNL_Connection::STATE_RESOLVING +** - the connection is still waiting for a JNL_AsycnDNS to resolve the +** host. +** JNL_Connection::STATE_CONNECTING +** - the asynchronous call to connect() is still running. +** JNL_Connection::STATE_CONNECTED +** - the connection has connected, all is well. +** JNL_Connection::STATE_CLOSING +** - the connection is closing. This happens after a call to close, +** without the quick parameter set. This means that the connection +** will close once the data in the send buffer is sent (data could +** still be being received when it would be closed). After it is +** closed, the state will transition to: +** JNL_Connection::STATE_CLOSED +** - the connection has closed, generally without error. There still +** might be data in the receieve buffer, use recv_bytes_available(). +** 5. Use send() and send_string() to send data. You can use +** send_bytes_in_queue() to see how much has yet to go out, or +** send_bytes_available() to see how much you can write. If you use send() +** or send_string() and not enough room is available, both functions will +** return error ( < 0) +** 6. Use recv() and recv_line() to get data. If you want to see how much data +** there is, use recv_bytes_available() and recv_lines_available(). If you +** call recv() and not enough data is available, recv() will return how much +** data was actually read. See comments at the function defs. +** +** 7. To close, call close(1) for a quick close, or close() for a close that will +** make the socket close after sending all the data sent. +** +** 8. delete ye' ol' object. +*/ + +#ifndef _UDPCONNECTION_H_ +#define _UDPCONNECTION_H_ + +#include "asyncdns.h" +#include "nu/RingBuffer.h" +#include "jnetlib_defines.h" + +#define JNL_DEFAULT_BUFFER_SIZE 8192 + +class JNL_UDPConnection : private Drainer, private Filler +{ +public: + typedef enum + { + STATE_ERROR = JNL_CONNECTION_STATE_ERROR, + STATE_NOCONNECTION = JNL_CONNECTION_STATE_NOCONNECTION, + STATE_RESOLVING = JNL_CONNECTION_STATE_RESOLVING, + STATE_CONNECTING = JNL_CONNECTION_STATE_CONNECTING, + STATE_CONNECTED = JNL_CONNECTION_STATE_CONNECTED, + STATE_CLOSING = JNL_CONNECTION_STATE_CLOSING, + STATE_CLOSED = JNL_CONNECTION_STATE_CLOSED, + STATE_RESOLVED = JNL_CONNECTION_STATE_RESOLVED, + } state; + + JNL_UDPConnection(); + JNL_UDPConnection( unsigned short port, JNL_AsyncDNS *dns, int sendbufsize = JNL_DEFAULT_BUFFER_SIZE, int recvbufsize = JNL_DEFAULT_BUFFER_SIZE ); + ~JNL_UDPConnection(); + + void open( JNL_AsyncDNS *dns = JNL_AUTODNS, size_t sendbufsize = JNL_DEFAULT_BUFFER_SIZE, size_t recvbufsize = JNL_DEFAULT_BUFFER_SIZE ); + void open( int incoming_socket, JNL_AsyncDNS *dns = JNL_AUTODNS, size_t sendbufsize = JNL_DEFAULT_BUFFER_SIZE, size_t recvbufsize = JNL_DEFAULT_BUFFER_SIZE ); + + void setpeer( const char *hostname, int port ); + void setpeer( sockaddr *addr, socklen_t length /* of addr */ ); + + void run( size_t max_send_bytes = -1, size_t max_recv_bytes = -1, size_t *bytes_sent = NULL, size_t *bytes_rcvd = NULL ); + + int get_state() { return m_state; } + const char *get_errstr() { return m_errorstr; } + + void close( int quick = 0 ); + void flush_send( void ) { send_buffer.clear(); } + + size_t send_bytes_in_queue( void ); + size_t send_bytes_available( void ); + int send( const void *data, size_t length ); // returns -1 if not enough room + int send_string( const char *line ); // returns -1 if not enough room + + + size_t recv_bytes_available( void ); + size_t recv_bytes( void *data, size_t maxlength ); // returns actual bytes read + unsigned int recv_int( void ); + int recv_lines_available( void ); + int recv_line( char *line, size_t maxlength ); // returns 0 if the line was terminated with a \r or \n, 1 if not. + // (i.e. if you specify maxlength=10, and the line is 12 bytes long + // it will return 1. or if there is no \r or \n and that's all the data + // the connection has.) + size_t peek_bytes( void *data, size_t maxlength ); // returns bytes peeked + + int get_interface( sockaddr *sin, socklen_t *sin_length ); // this returns the interface the connection is on + short get_remote_port( void ) { return m_remote_port; } // this returns the remote port of connection + + void get_last_recv_msg_addr( sockaddr **addr, socklen_t *len ) { *addr = (sockaddr *)&m_last_addr; *len = m_last_addr_len; } + + void set_ttl( uint8_t new_ttl ); + +protected: + uint8_t ttl; + SOCKET m_socket; + unsigned short m_remote_port; + RingBuffer recv_buffer; + RingBuffer send_buffer; + + sockaddr *address; + socklen_t address_len; + + sockaddr_storage m_last_addr; + socklen_t m_last_addr_len; + addrinfo *saddr; + + char *m_host; + + JNL_AsyncDNS *m_dns; + int m_dns_owned; + + state m_state; + const char *m_errorstr; + +private: + void init(); // constructor helper function + + // functions for RingBuffer + size_t Read( void *dest, size_t len ); + size_t Write( const void *dest, size_t len ); + +}; + +#endif // _UDPConnection_H_ -- cgit