<commit_before>/***************************************************************
 *
 * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License.  You may
 * obtain a copy of the License at
 * 
 *    http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ***************************************************************/


#ifndef SOCK_H
#define SOCK_H

#include "condor_common.h"
#include "condor_socket_types.h"
#include "stream.h"
#include "CondorError.h"
#include "condor_perms.h"
#include "condor_sockaddr.h"

// retry failed connects for CONNECT_TIMEOUT seconds
#define CONNECT_TIMEOUT 10

// Some error codes.  These should go to condor_errno.h once it is there.
const int CEDAR_EWOULDBLOCK = 666;
const int CEDAR_ENOCCB = 667;

#if !defined(WIN32)
#  ifndef SOCKET
#    define SOCKET int
#  endif
#  ifndef INVALID_SOCKET
#    define INVALID_SOCKET -1
#  endif
#endif /* not WIN32 */


#ifdef WIN32
class SockInitializer {
	private:
		bool called_from_init;
	public:
		SockInitializer();
		~SockInitializer();
		void init();
};
#endif  /* of WIN32 */

/*
We want to define a callback function to be invoked when certain actions happen upon a stream.  CedarHandler is the type of a callback function.   The following notation is a little strange.  It reads: Define a new type called "CedarHandler" to be "a function returning void with single argument pointer to Stream"
*/

typedef void (CedarHandler) (Stream *s);

/*
**	B A S E    S O C K
*/

/** The Sock class defines an interface for connection establishment.
This interface is implemented with TCP in the ReliSock class and with
UDP in the SafeSock class.  ReliSock and SafeSock are the only Cedar
classes which should be instantiated; however, pointers to the Stream
base class are often used at points in the application where it is not
important if the underlying medium is TCP or UDP (for example, in a
daemon which handles the same commands over both TCP and UDP).
*/
class Sock : public Stream {

//	PUBLIC INTERFACE TO ALL SOCKS
//
public:

	friend class DaemonCore;
	friend class Daemon;
	friend class SecMan;
	friend class SecManStartCommand;
	friend class SharedPortListener;
	friend class SharedPortEndpoint;

	/*
	**	Methods
	*/

	/// Virtual socket services
	virtual int handle_incoming_packet() = 0;

	/** Connect the socket to a remote peer.
		@param host Hostname of peer, either a DNS name or an IP address, or 
		an IP address and port together in the format "&lt;IP:PORT&gt;", such as 
		<p> &lt;172.16.17.32:3354&gt;
		<b>Note:</b> The "&lt;" and "&gt;" are required when giving both the
		IP and Port.
		@param port The port to connect to.  If host is in the form <IP:PORT>,
		then the port parameter is ignored.
		@param do_not_block If false, then the connect call will block until
		completion or until timeout.  If true, then the connect call will
		return immediately with TRUE, FALSE, or CEDAR_EWOULDBLOCK.  If 
		CEDAR_EWOULDBLOCK is returned, the user should call 
		do_connect_finish() when select says this socket is writeable to 
		find out if the CEDAR connection process has really completed.  
		In Condor this is usually accomplished by calling DaemonCore's
		Register_Socket() method.
		@return TRUE if connection succeeded, FALSE on failure, or 
		CEDAR_EWOULDBLOCK if parameter do_not_block is set to true and 
		the call would block.
		@see do_connect_finish
	*/
	virtual int connect(char const *host, int port=0, bool do_not_block = false) = 0;

	/** Connect the socket to a remote peer.
		@param host Hostname of the peer, either a DNS name or IP address.
		@param service The name of a service that represents a port address,
		which can be passed to getportbyserv().
	*/
	inline int connect(char const *host, char *service, bool do_not_block = false) { 
		return connect(host,getportbyserv(service),do_not_block); 
	}


	/** Install this function as the asynchronous handler.  When a handler is installed, it is invoked whenever data arrives on the socket.  Setting the handler to zero disables asynchronous notification.  */

	int set_async_handler( CedarHandler *handler );

	
	//	Socket services
	//

PRAGMA_REMIND("adesmet: DEPRECATED")
	int assign(SOCKET =INVALID_SOCKET);

	int assign(condor_protocol proto, SOCKET =INVALID_SOCKET);
#if defined(WIN32) && defined(_WINSOCK2API_)
	int assign(LPWSAPROTOCOL_INFO);		// to inherit sockets from other processes
#endif

PRAGMA_REMIND("adesmet: DEPRECATED")
	int bind(bool outbound, int port=0, bool loopback=false);

	int bind(condor_protocol proto, bool outbound, int port, bool loopback);

	bool bind_to_loopback(bool outbound=false, int port=0);

    int setsockopt(int, int, const void*, int); 

	/**  Set the size of the operating system buffers (in the IP stack) for
		 this socket.
		 @param desired_size The desired size of the buffer in bytes.  If 
		 desired_size is greater than the maximum allowed by the operating system,
		 the size will be set to the maximum allowed.
		 @param set_write_buf if false, then only the size of the receive buffer
		 is changed; if true, then both the send and receive buffers are resized
		 @return the actual/resulting size of the buffer in bytes
	*/
	int set_os_buffers(int desired_size, bool set_write_buf = false);

	/** Enable keepalive options for this socket as dictacted by config knob
		TCP_KEEPALIVE_INTERVAL.  Currently a no-op on anything but relisocks.
		@return false if any system call errors, true otherwise.
	*/
	bool set_keepalive();

PRAGMA_REMIND("adesmet: deprecated")
	inline int bind(bool outbound, char *s) { return bind(outbound, getportbyserv(s)); }

	int close();
	/** if any operation takes more than sec seconds, timeout
        call timeout(0) to set blocking mode (default)
        @param sec the number of seconds to wait before timing out
               Note that (for better or worse) this may be multiplied
               by a global timeout multiplier unless<commit_msg>turn off messages in sock.h about deprecated methods ===VersionHistory:None===<commit_after>/***************************************************************
 *
 * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License.  You may
 * obtain a copy of the License at
 * 
 *    http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ***************************************************************/


#ifndef SOCK_H
#define SOCK_H

#include "condor_common.h"
#include "condor_socket_types.h"
#include "stream.h"
#include "CondorError.h"
#include "condor_perms.h"
#include "condor_sockaddr.h"

// retry failed connects for CONNECT_TIMEOUT seconds
#define CONNECT_TIMEOUT 10

// Some error codes.  These should go to condor_errno.h once it is there.
const int CEDAR_EWOULDBLOCK = 666;
const int CEDAR_ENOCCB = 667;

#if !defined(WIN32)
#  ifndef SOCKET
#    define SOCKET int
#  endif
#  ifndef INVALID_SOCKET
#    define INVALID_SOCKET -1
#  endif
#endif /* not WIN32 */


#ifdef WIN32
class SockInitializer {
	private:
		bool called_from_init;
	public:
		SockInitializer();
		~SockInitializer();
		void init();
};
#endif  /* of WIN32 */

/*
We want to define a callback function to be invoked when certain actions happen upon a stream.  CedarHandler is the type of a callback function.   The following notation is a little strange.  It reads: Define a new type called "CedarHandler" to be "a function returning void with single argument pointer to Stream"
*/

typedef void (CedarHandler) (Stream *s);

/*
**	B A S E    S O C K
*/

/** The Sock class defines an interface for connection establishment.
This interface is implemented with TCP in the ReliSock class and with
UDP in the SafeSock class.  ReliSock and SafeSock are the only Cedar
classes which should be instantiated; however, pointers to the Stream
base class are often used at points in the application where it is not
important if the underlying medium is TCP or UDP (for example, in a
daemon which handles the same commands over both TCP and UDP).
*/
class Sock : public Stream {

//	PUBLIC INTERFACE TO ALL SOCKS
//
public:

	friend class DaemonCore;
	friend class Daemon;
	friend class SecMan;
	friend class SecManStartCommand;
	friend class SharedPortListener;
	friend class SharedPortEndpoint;

	/*
	**	Methods
	*/

	/// Virtual socket services
	virtual int handle_incoming_packet() = 0;

	/** Connect the socket to a remote peer.
		@param host Hostname of peer, either a DNS name or an IP address, or 
		an IP address and port together in the format "&lt;IP:PORT&gt;", such as 
		<p> &lt;172.16.17.32:3354&gt;
		<b>Note:</b> The "&lt;" and "&gt;" are required when giving both the
		IP and Port.
		@param port The port to connect to.  If host is in the form <IP:PORT>,
		then the port parameter is ignored.
		@param do_not_block If false, then the connect call will block until
		completion or until timeout.  If true, then the connect call will
		return immediately with TRUE, FALSE, or CEDAR_EWOULDBLOCK.  If 
		CEDAR_EWOULDBLOCK is returned, the user should call 
		do_connect_finish() when select says this socket is writeable to 
		find out if the CEDAR connection process has really completed.  
		In Condor this is usually accomplished by calling DaemonCore's
		Register_Socket() method.
		@return TRUE if connection succeeded, FALSE on failure, or 
		CEDAR_EWOULDBLOCK if parameter do_not_block is set to true and 
		the call would block.
		@see do_connect_finish
	*/
	virtual int connect(char const *host, int port=0, bool do_not_block = false) = 0;

	/** Connect the socket to a remote peer.
		@param host Hostname of the peer, either a DNS name or IP address.
		@param service The name of a service that represents a port address,
		which can be passed to getportbyserv().
	*/
	inline int connect(char const *host, char *service, bool do_not_block = false) { 
		return connect(host,getportbyserv(service),do_not_block); 
	}


	/** Install this function as the asynchronous handler.  When a handler is installed, it is invoked whenever data arrives on the socket.  Setting the handler to zero disables asynchronous notification.  */

	int set_async_handler( CedarHandler *handler );

	
	//	Socket services
	//

//PRAGMA_REMIND("adesmet: DEPRECATED")
	int assign(SOCKET =INVALID_SOCKET);

	int assign(condor_protocol proto, SOCKET =INVALID_SOCKET);
#if defined(WIN32) && defined(_WINSOCK2API_)
	int assign(LPWSAPROTOCOL_INFO);		// to inherit sockets from other processes
#endif

//PRAGMA_REMIND("adesmet: DEPRECATED")
	int bind(bool outbound, int port=0, bool loopback=false);

	int bind(condor_protocol proto, bool outbound, int port, bool loopback);

	bool bind_to_loopback(bool outbound=false, int port=0);

    int setsockopt(int, int, const void*, int); 

	/**  Set the size of the operating system buffers (in the IP stack) for
		 this socket.
		 @param desired_size The desired size of the buffer in bytes.  If 
		 desired_size is greater than the maximum allowed by the operating system,
		 the size will be set to the maximum allowed.
		 @param set_write_buf if false, then only the size of the receive buffer
		 is changed; if true, then both the send and receive buffers are resized
		 @return the actual/resulting size of the buffer in bytes
	*/
	int set_os_buffers(int desired_size, bool set_write_buf = false);

	/** Enable keepalive options for this socket as dictacted by config knob
		TCP_KEEPALIVE_INTERVAL.  Currently a no-op on anything but relisocks.
		@return false if any system call errors, true otherwise.
	*/
	bool set_keepalive();

//PRAGMA_REMIND("adesmet: deprecated")
	inline int bind(bool outbound, char *s) { return bind(outbound, getportbyserv(s)); }

	int close();
	/** if any operation takes more than sec seconds, timeout
        call timeout(0) to set blocking mode (default)
        @param sec the number of seconds to wait before timing out
               Note that (for better or worse) this may be multiplied
               by a global timeout multiplier unless
{'fraction_non_alphanumeric': 0.08950593345226092, 'fraction_numerical': 0.007911269681222369, 'mean_word_length': 4.044600938967136, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1974719', 'n_tokens_mistral': 3952, 'n_tokens_neox': 3640, 'n_words': 1665}