diff --git a/doc/admin-man/configure.tex b/doc/admin-man/configure.tex index ddc8d5f6977..324a9e4aa09 100644 --- a/doc/admin-man/configure.tex +++ b/doc/admin-man/configure.tex @@ -2384,11 +2384,7 @@ \subsection{\label{sec:Network-Related-Config-File-Entries}Network-Related Confi If \MacroNI{BIND\_ALL\_INTERFACES} is \Expr{True} (the default), \MacroNI{NETWORK\_INTERFACE} controls what IP address will be advertised as the public address of the daemon. - If multiple network interfaces match the value and - \MacroNI{ENABLE\_ADDRESS\_REWRITING} is \Expr{True} (the default), - the IP address that is chosen to be advertised will be the one that - is used to communicate with the \Condor{collector}. - If \MacroNI{ENABLE\_ADDRESS\_REWRITING} is \Expr{False}, the IP address + If multiple network interfaces match the value, the IP address that is chosen to be advertised will be the one associated with the first device (in system-defined order) that is in a public address space, or a private address space, or a loopback address, in that @@ -2488,24 +2484,6 @@ \subsection{\label{sec:Network-Related-Config-File-Entries}Network-Related Confi authorization settings that rely on host addresses should be considered accordingly. -\label{param:EnableAddressRewriting} -\item[\Macro{ENABLE\_ADDRESS\_REWRITING}] - A boolean value that defaults to \Expr{True}. When - \MacroNI{NETWORK\_INTERFACE} matches only one IP address or - \MacroNI{TCP\_FORWARDING\_HOST} is defined or - \MacroNI{NET\_REMAP\_ENABLE} is \Expr{True}, this setting has no effect and - the behavior is as though it had been set to \Expr{False}. When \Expr{True}, - IP addresses published by HTCondor daemons are automatically rewritten to - match the IP address of the network interface used to make the - publication. For example, if the \Condor{schedd} advertises itself to - two pools via flocking, and the \Condor{collector} for one pool is reached - by the \Condor{schedd} through a private network interface, while - the \Condor{collector} for the other pool is reached through a different - network interface, the IP address published by the \Condor{schedd} - daemon will match the address of the respective network interfaces - used in the two cases. The intention is to make it easier for - HTCondor daemons to operate in a multi-homed environment. - \label{param:HighPort} \item[\Macro{HIGHPORT}] Specifies an upper limit of given port numbers for HTCondor to use, diff --git a/doc/admin-man/install.tex b/doc/admin-man/install.tex index 1a6ec3d4878..b9979b04d15 100644 --- a/doc/admin-man/install.tex +++ b/doc/admin-man/install.tex @@ -511,10 +511,10 @@ \subsubsection{\label{sec:install-rpms} development releases and by Red Hat version number. The 4 repositories are: \begin{itemize} - \item \File{condor-stable-rhel6.repo} - \item \File{condor-stable-rhel7.repo} - \item \File{condor-development-rhel6.repo} - \item \File{condor-development-rhel7.repo} + \item \File{htcondor-stable-rhel6.repo} + \item \File{htcondor-stable-rhel7.repo} + \item \File{htcondor-development-rhel6.repo} + \item \File{htcondor-development-rhel7.repo} \end{itemize} Here is an ordered set of steps that get HTCondor running using the RPM. @@ -530,7 +530,7 @@ \subsubsection{\label{sec:install-rpms} \footnotesize \begin{verbatim} cd /etc/yum.repos.d - wget http://htcondor.org/yum/repo.d/condor-stable-rhel7.repo + wget http://htcondor.org/yum/repo.d/htcondor-stable-rhel7.repo \end{verbatim} \normalsize Note that this step need be done only once; diff --git a/doc/admin-man/multiple-interfaces.tex b/doc/admin-man/multiple-interfaces.tex index 7d15681ffb0..3f0fa1a0e5f 100644 --- a/doc/admin-man/multiple-interfaces.tex +++ b/doc/admin-man/multiple-interfaces.tex @@ -112,10 +112,8 @@ \subsubsection{\label{sec:Using-BindAllInterfaces}Using each with a separate IP, the daemon must choose which two IP addresses to advertise so that other daemons and tools can connect to it. - By default, HTCondor advertises the IP address of the network interface - used to contact the \Condor{collector} as its public address, - since this is the most likely to be - accessible to other processes that query the same \Condor{collector}. + By default, HTCondor advertises the most public IP address available + on the machine. The \Macro{NETWORK\_INTERFACE} configuration variable can be used to specify the public IP address HTCondor should advertise, and \Macro{PRIVATE\_NETWORK\_INTERFACE}, along with diff --git a/doc/version-history/8-7.history.tex b/doc/version-history/8-7.history.tex index acd2654586e..82c5693cd8e 100644 --- a/doc/version-history/8-7.history.tex +++ b/doc/version-history/8-7.history.tex @@ -29,7 +29,23 @@ \subsection*{\label{sec:New-8-7-7}Version 8.7.7} \begin{itemize} -\item None. +\item Removed configuration parameters \MacroNI{ENABLE\_ADDRESS\_REWRITING} +and \MacroNI{SHARED\_PORT\_ADDRESS\_REWRITING}. +\Ticket{6525} + +\item An IPv6 address can now be specified in the configuration file +either with or without square brackets in most cases. +If specifying a port number in the same value, the square brackets are +required. +If using a wildcard to specify a range of possible addresses, square +brackets are not allowed. +\Ticket{5697} + +\item Improved support for IPv6 link-local addresses, in particular +using the correct scope id. +Using a wildcard or device name in \MacroNI{NETWORK\_INTERFACE} now +works properly when \MacroNI{NO\_DNS} is set to \Expr{True}. +\Ticket{6518} \end{itemize} @@ -37,7 +53,9 @@ \subsection*{\label{sec:New-8-7-7}Version 8.7.7} \begin{itemize} -\item None. +\item IPv4 addresses are now ignored when resolving a hostname and +\MacroNI{ENABLE\_IPV4} is set to \Expr{False}. +\Ticket{4881} \end{itemize} diff --git a/src/ccb/ccb_server.cpp b/src/ccb/ccb_server.cpp index 95e61f8edc8..42e42fb2764 100644 --- a/src/ccb/ccb_server.cpp +++ b/src/ccb/ccb_server.cpp @@ -469,19 +469,7 @@ CCBServer::HandleRegistration(int cmd,Stream *stream) // potential flexibility on the CCB server side to do things like // assign different targets to different CCB server sub-processes, // each with their own command port. - - // - // We need to reply with a contact string of the proper protocol. At - // some point, we'll just send /all/ of our command sockets, but for - // now, just use the rewriter (and lie to make sure it happens). - // - std::string exprString; - formatstr( exprString, "%s = \"<%s>\"", ATTR_MY_ADDRESS, m_address.Value() ); - ConvertDefaultIPToSocketIP( ATTR_MY_ADDRESS, exprString, * stream ); - std::string rewrittenAddress = exprString.substr( strlen( ATTR_MY_ADDRESS ) + 5 ); - rewrittenAddress.resize( rewrittenAddress.size() - 2 ); - dprintf( D_NETWORK | D_VERBOSE, "Will send %s instead of %s to CCB client %s.\n", rewrittenAddress.c_str(), m_address.Value(), sock->my_ip_str() ); - CCBIDToContactString( rewrittenAddress.c_str(), target->getCCBID(), ccb_contact ); + CCBIDToContactString( m_address.Value(), target->getCCBID(), ccb_contact ); CCBIDToString( reconnect_info->getReconnectCookie(),reconnect_cookie_str ); diff --git a/src/classad/classad/lexer.h b/src/classad/classad/lexer.h index 04c1ed2e77b..9659e28caff 100644 --- a/src/classad/classad/lexer.h +++ b/src/classad/classad/lexer.h @@ -79,9 +79,7 @@ class Lexer LEX_CLOSE_PAREN, LEX_OPEN_BRACE, LEX_CLOSE_BRACE, - LEX_BACKSLASH, - LEX_ABSOLUTE_TIME_VALUE, - LEX_RELATIVE_TIME_VALUE + LEX_BACKSLASH }; class TokenValue @@ -94,9 +92,6 @@ class Lexer realValue = 0.0; boolValue = false; quotedExpr = false; - relative_secs = 0; - absolute_secs.secs = 0; - absolute_secs.offset = 0; } ~TokenValue( ) { @@ -127,14 +122,6 @@ class Lexer quotedExpr = quoted; } - void SetAbsTimeValue( abstime_t asecs ) { - absolute_secs = asecs; - } - - void SetRelTimeValue( double rsecs ) { - relative_secs = rsecs; - } - TokenType GetTokenType( ) { return tt; } @@ -160,14 +147,6 @@ class Lexer quoted = quotedExpr; } - void GetAbsTimeValue( abstime_t& asecs ) { - asecs = absolute_secs; - } - - void GetRelTimeValue( double& rsecs ) { - rsecs = relative_secs; - } - void CopyFrom( TokenValue &tv ) { tt = tv.tt; factor = tv.factor; @@ -175,8 +154,6 @@ class Lexer realValue = tv.realValue; boolValue = tv.boolValue; quotedExpr = tv.quotedExpr; - relative_secs = tv.relative_secs; - absolute_secs = tv.absolute_secs; strValue = tv.strValue; } @@ -188,8 +165,6 @@ class Lexer bool boolValue; bool quotedExpr; std::string strValue; - double relative_secs; - abstime_t absolute_secs; }; // ctor/dtor diff --git a/src/classad/lexer.cpp b/src/classad/lexer.cpp index 1e5854b47a7..388dcebbb77 100644 --- a/src/classad/lexer.cpp +++ b/src/classad/lexer.cpp @@ -258,8 +258,6 @@ PeekToken (TokenValue *lvalp) case LEX_CLOSE_PAREN: case LEX_CLOSE_BRACE: case LEX_BACKSLASH: - case LEX_ABSOLUTE_TIME_VALUE: - case LEX_RELATIVE_TIME_VALUE: tokenizePunctOperator(); break; default: @@ -971,8 +969,6 @@ strLexToken (int tokenValue) case LEX_OPEN_BRACE: return "LEX_OPEN_BRACE"; case LEX_CLOSE_BRACE: return "LEX_CLOSE_BRACE"; case LEX_BACKSLASH: return "LEX_BACKSLASH"; - case LEX_ABSOLUTE_TIME_VALUE: return "LEX_ABSOLUTE_TIME_VALUE"; - case LEX_RELATIVE_TIME_VALUE: return "LEX_RELATIVE_TIME_VALUE"; default: return "** Unknown **"; diff --git a/src/classad/source.cpp b/src/classad/source.cpp index 002d4a5d876..de197a86559 100644 --- a/src/classad/source.cpp +++ b/src/classad/source.cpp @@ -1091,29 +1091,6 @@ parsePrimaryExpression(ExprTree *&tree) val.SetStringValue( s ); return( (tree=Literal::MakeLiteral(val)) != NULL ); } - - case Lexer::LEX_ABSOLUTE_TIME_VALUE: - { - Value val; - abstime_t asecs; - - tv.GetAbsTimeValue( asecs ); - lexer.ConsumeToken( ); - val.SetAbsoluteTimeValue( asecs ); - return( (tree=Literal::MakeLiteral(val)) != NULL ); - } - - case Lexer::LEX_RELATIVE_TIME_VALUE: - { - Value val; - double secs; - - tv.GetRelTimeValue( secs ); - lexer.ConsumeToken( ); - val.SetRelativeTimeValue( secs ); - return( (tree=Literal::MakeLiteral(val)) != NULL ); - } - default: tree = NULL; return false; diff --git a/src/condor_ckpt_server/network2.cpp b/src/condor_ckpt_server/network2.cpp index fe879956dfc..7d706c6ad41 100644 --- a/src/condor_ckpt_server/network2.cpp +++ b/src/condor_ckpt_server/network2.cpp @@ -57,6 +57,7 @@ #include "network2.h" #include "internet.h" +#include "internet_obsolete.h" #include #include @@ -68,18 +69,6 @@ /* P R O T O T Y P E S */ char *param(void); -//char* GetIPName(struct in_addr machine_IP) -//{ -// char* temp_name; -// -// temp_name = inet_ntoa(machine_IP); -// if (temp_name == NULL) -// return ""; -// else -// return temp_name; -//} - - /****************************************************************************** * * * Function: I_bind(int socket_desc, * @@ -125,9 +114,15 @@ int I_bind(int socket_desc, condor_sockaddr& addr, int is_well_known) priv_state old_priv = PRIV_UNKNOWN; //temp = sizeof(struct sockaddr_in); - setsockopt(socket_desc, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)); - setsockopt(socket_desc, SOL_SOCKET, SO_LINGER, + int ret = setsockopt(socket_desc, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)); + if (ret < 0) { + fprintf(stderr, "\nWARNING: Cannot set SO_REUSEADDR on socket %d\n", socket_desc); + } + ret = setsockopt(socket_desc, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(linger)); + if (ret < 0) { + fprintf(stderr, "\nWARNING: Cannot set SO_LINGER on socket %d\n", socket_desc); + } // remember we did this transformation before calling this function... // so undo it here. @@ -190,52 +185,6 @@ int I_bind(int socket_desc, condor_sockaddr& addr, int is_well_known) -/****************************************************************************** -* * -* Function: gethostnamebyaddr(struct in_addr* addr) * -* * -******************************************************************************* -* * -* This function, by using the gethostbyaddr() function, returns a pointer * -* to the name (i.e., string) of a machine. The machine is specified by * -* the parameter which is an IP address. * -* * -* Note: this function may fail if the name server cannot find the name of * -* a machine. In this case, this function will terminate the program. * -* * -******************************************************************************* -* * -* Parameters: * -* struct in_addr* addr - a pointer to an IP address * -* * -******************************************************************************* -* * -* Return Type: * -* char* - a pointer to a static area where a machine's (string) name * -* is held * -* * -******************************************************************************/ - - -//char* gethostnamebyaddr(struct in_addr* addr) -//{ -// struct hostent* h; -// -// h = condor_gethostbyaddr((char*)addr, sizeof(struct in_addr), AF_INET); -// if (h == NULL) -// { -// fprintf(stderr, "\nERROR:\n"); -// fprintf(stderr, "ERROR:\n"); -// fprintf(stderr, "ERROR: cannot get host information (pid=%d)\n", -// (int) getpid()); -// fprintf(stderr, "ERROR:\n"); -// fprintf(stderr, "ERROR:\n\n"); -// return NULL; -// } -// return(h->h_name); -//} - - /****************************************************************************** * * * Function: I_socket(int exit_status) * diff --git a/src/condor_ckpt_server/network2.h b/src/condor_ckpt_server/network2.h index 600029d264f..ac9cbe76f6b 100644 --- a/src/condor_ckpt_server/network2.h +++ b/src/condor_ckpt_server/network2.h @@ -64,15 +64,11 @@ #include "condor_sockaddr.h" /* Function Prototypes*/ -//extern "C" { -//char* GetIPName(struct in_addr machine_IP); // I_bind binds to given addr and stores the address obtained by // getsockname() on socket_desc to addr. int I_bind(int socket_desc, condor_sockaddr& addr, int is_well_known); -//char* gethostnamebyaddr(struct in_addr* addr); - int I_socket(void); int I_listen(int socket_desc, int queue_len); @@ -81,7 +77,6 @@ int I_accept(int socket_desc, condor_sockaddr& addr); int net_write(int socket_desc, char* buffer, int size); -//} #endif diff --git a/src/condor_ckpt_server/server2.cpp b/src/condor_ckpt_server/server2.cpp index 55153cc2cdd..d8b46ed73cb 100644 --- a/src/condor_ckpt_server/server2.cpp +++ b/src/condor_ckpt_server/server2.cpp @@ -925,6 +925,7 @@ void Server::ProcessServiceReq(int req_id, service_reply.server_addr.s_addr = ntohl(server_addr.s_addr); service_reply.port = server_sa.get_port(); close(data_conn_sd); + data_conn_sd = -1; } else { service_reply.server_addr.s_addr = 0; service_reply.port = 0; diff --git a/src/condor_ckpt_server/server_interface.cpp b/src/condor_ckpt_server/server_interface.cpp index ed516702097..18e3d525d02 100644 --- a/src/condor_ckpt_server/server_interface.cpp +++ b/src/condor_ckpt_server/server_interface.cpp @@ -24,6 +24,7 @@ #include "constants2.h" #include "network2.h" #include "internet.h" +#include "internet_obsolete.h" #include "condor_netdb.h" #include "condor_sockaddr.h" #include "ipv6_hostname.h" diff --git a/src/condor_daemon_client/dc_startd.cpp b/src/condor_daemon_client/dc_startd.cpp index 9bedf62447e..bee22091ec7 100644 --- a/src/condor_daemon_client/dc_startd.cpp +++ b/src/condor_daemon_client/dc_startd.cpp @@ -118,9 +118,6 @@ ClaimStartdMsg::writeMsg( DCMessenger * /*messenger*/, Sock *sock ) { m_startd_fqu = sock->getFullyQualifiedUser(); m_startd_ip_addr = sock->peer_ip_str(); - std::string scheduler_addr_to_send = m_scheduler_addr; - ConvertDefaultIPToSocketIP(ATTR_SCHEDD_IP_ADDR,scheduler_addr_to_send,*sock); - // Insert an attribute in the request ad to inform the // startd that this schedd is capable of understanding // the newer protocol where the claim response may send @@ -137,7 +134,7 @@ ClaimStartdMsg::writeMsg( DCMessenger * /*messenger*/, Sock *sock ) { if( !sock->put_secret( m_claim_id.c_str() ) || !putClassAd( sock, m_job_ad ) || - !sock->put( scheduler_addr_to_send.c_str() ) || + !sock->put( m_scheduler_addr.c_str() ) || !sock->put( m_alive_interval ) || !this->putExtraClaims(sock)) { diff --git a/src/condor_daemon_core.V6/condor_daemon_core.h b/src/condor_daemon_core.V6/condor_daemon_core.h index d7f27ab5a1f..19a69c52b3c 100644 --- a/src/condor_daemon_core.V6/condor_daemon_core.h +++ b/src/condor_daemon_core.V6/condor_daemon_core.h @@ -1634,24 +1634,6 @@ class DaemonCore : public Service } dc_stats; - // Do not use this function for anything. It's a temporary hack to get - // ConvertDefaultIPToSocketIP working in mixed-mode IPv4/IPv6. The - // real goal is to eliminate ConvertDefaultIPToSocketIP, and eliminate - // the need for this. - // - // All that said: given a condor_sockaddr, this will look for the interface - // that best matches and will return its port. - int find_interface_command_port_do_not_use(const condor_sockaddr & addr); - - // Do not use this function for anything. It's a temporary hack to get - // ConvertDefaultIPToSocketIP working in mixed-mode IPv4/IPv6. The - // real goal is to eliminate ConvertDefaultIPToSocketIP, and eliminate - // the need for this. - // - // All that said: given a condor_sockaddr, determine if it describes - // one of our command ports. - bool is_command_port_do_not_use(const condor_sockaddr & addr); - bool wants_dc_udp_self() const { return m_wants_dc_udp_self;} private: diff --git a/src/condor_daemon_core.V6/daemon_core.cpp b/src/condor_daemon_core.V6/daemon_core.cpp index 12644ed9a4e..e94638bce79 100644 --- a/src/condor_daemon_core.V6/daemon_core.cpp +++ b/src/condor_daemon_core.V6/daemon_core.cpp @@ -1233,6 +1233,11 @@ DaemonCore::InfoCommandSinfulStringMyself(bool usePrivateAddress) // Sinful in the address file will have TCP_FORWARDING_HOST as its // primary address, and older versions of HTCondor don't ignore // the primary address). + // + // NOTE: For the primary address in our sinful string, prefer an + // IPv4 address, if available. The primary address is only used by + // older clients (pre-8.3.x) that don't understand the addrs field + // and probably don't have good IPv6 support. char const * addr = sock->get_sinful_public(); if(! sa.is_ipv4()) { for( int i = initialCommandSock; i < nSock; ++i ) { @@ -11048,33 +11053,3 @@ bool DaemonCore::SockPair::has_safesock(bool b) { } return true; } - -int DaemonCore::find_interface_command_port_do_not_use(const condor_sockaddr & addr) { - - // Boldly assuming all entries in dc_socks have relisocks and - // that all listen sockets for a given protocol use the same port - // As of Sept 2014, I believe these are true. This function should - // go away long before these are violated. - for(SockPairVec::iterator it = dc_socks.begin(); it != dc_socks.end(); it++) { - ASSERT(it->has_relisock()); - condor_sockaddr listen_addr = it->rsock()->my_addr(); - if(addr.get_protocol() == listen_addr.get_protocol()) { - return listen_addr.get_port(); - } - } - // No matching listen socket. - return 0; -} - -bool DaemonCore::is_command_port_do_not_use(const condor_sockaddr & addr) { - // Boldly assuming all entries in dc_socks have relisocks and - // that all listen sockets for a given protocol use the same port - // As of Sept 2014, I believe these are true. This function should - // go away long before these are violated. - for(SockPairVec::iterator it = dc_socks.begin(); it != dc_socks.end(); it++) { - ASSERT(it->has_relisock()); - condor_sockaddr listen_addr = it->rsock()->my_addr(); - if(listen_addr == addr) { return true; } - } - return false; -} diff --git a/src/condor_includes/condor_constants.h b/src/condor_includes/condor_constants.h index f66b497b366..b384ccdc547 100644 --- a/src/condor_includes/condor_constants.h +++ b/src/condor_includes/condor_constants.h @@ -119,7 +119,7 @@ static const char NiceUserName[] = "nice-user"; static const size_t IP_STRING_BUF_SIZE = 48; /* Max space needed to hold a sinful string, as - * returned by sin_to_string() + * returned by condor_sockaddr::to_sinful() */ // TODO: [IPV6] Should be increased #define SINFUL_STRING_BUF_SIZE 64 diff --git a/src/condor_includes/condor_error.h b/src/condor_includes/condor_error.h index 18293d1bfbc..9bb114027c7 100644 --- a/src/condor_includes/condor_error.h +++ b/src/condor_includes/condor_error.h @@ -31,8 +31,8 @@ _retry causes an exit allowing a rollback to the last checkpoint, while _fatal causes a permanent termination. */ -void _condor_error_retry( const char *format, ... ) CHECK_PRINTF_FORMAT(1,2); -void _condor_error_fatal( const char *format, ... ) CHECK_PRINTF_FORMAT(1,2); +void _condor_error_retry( const char *format, ... ) CHECK_PRINTF_FORMAT(1,2) GCC_NORETURN; +void _condor_error_fatal( const char *format, ... ) CHECK_PRINTF_FORMAT(1,2) GCC_NORETURN; typedef enum { CONDOR_WARNING_KIND_ALL, diff --git a/src/condor_includes/condor_netaddr.h b/src/condor_includes/condor_netaddr.h index ff1fadb4f62..9ccc85c7d48 100644 --- a/src/condor_includes/condor_netaddr.h +++ b/src/condor_includes/condor_netaddr.h @@ -27,8 +27,6 @@ // // the purpose of the class is to have all the relevant functions in // single place. -// -// Also, this is replacement for is_valid_network() in internet.cpp class condor_netaddr { @@ -51,7 +49,9 @@ class condor_netaddr // mask bits. An IPv6 network may be specified as an IPv6 literal // followed by a slash followed by an integer specifying the number of // mask bits; or as an IPv6 literal with the second of its trailing - // colons replaced by a star. Examples: + // colons replaced by a star. When a full IPv6 literal is used (with + // or without a slash and mask bits), the use of square brackets is + // allowed but optional. Examples: // // 128.104.100.22 // @@ -60,7 +60,9 @@ class condor_netaddr // 128.104.0.0/16 // // 2607:f388:107c:501:1b:21ff:feca:51f0 + // [2607:f388:107c:501:1b:21ff:feca:51f0] // 2607:f388:107c:501::/60 + // [2607:f388:107c:501::]/60 // 2607:f388:107c:501:* // bool from_net_string(const char* net); diff --git a/src/condor_includes/condor_netdb.h b/src/condor_includes/condor_netdb.h index 6ab12ef82c8..a5deaac5d9c 100644 --- a/src/condor_includes/condor_netdb.h +++ b/src/condor_includes/condor_netdb.h @@ -29,15 +29,6 @@ extern "C" { #endif -// do not use gethostbyname and gethostbyaddr -// use resolve_hsotname, get_hostname instead - -//struct hostent * -//condor_gethostbyname(const char *name); -// -//struct hostent * -//condor_gethostbyaddr(const char *addr, SOCKET_LENGTH_TYPE len, int type); - int condor_gethostname(char *name, size_t namelen); diff --git a/src/condor_includes/condor_sockaddr.h b/src/condor_includes/condor_sockaddr.h index 587823a83eb..dfc183ccc83 100644 --- a/src/condor_includes/condor_sockaddr.h +++ b/src/condor_includes/condor_sockaddr.h @@ -110,6 +110,8 @@ class condor_sockaddr // from_sinful() calls gethostbyname to resolve DNS name to IP addr. bool from_sinful(const MyString& ip_string); bool from_sinful(const char* sinful); + // The sinful string will fit in a buffer whose size is at least + // SINFUL_STRING_BUF_SIZE. MyString to_sinful() const; const char* to_sinful(char* buf, int len) const; MyString to_sinful_wildcard_okay() const; @@ -127,7 +129,9 @@ class condor_sockaddr MyString to_ip_and_port_string() const; // Have I mentioned recently how much I hate life? MyString to_ccb_safe_string(); - // it it fails on inet_ntop(), returns NULL and given buf + // The string will fit in a buffer whose size is as least + // IP_STRING_BUF_SIZE. + // if it fails on inet_ntop(), returns NULL and given buf // will not be modified. // decorate==true - Add additional decorations appropriate // for the protocol. As of 2014 only puts diff --git a/src/condor_includes/internet.h b/src/condor_includes/internet.h index 8de3a270204..189e581965f 100644 --- a/src/condor_includes/internet.h +++ b/src/condor_includes/internet.h @@ -41,48 +41,14 @@ extern "C" { #endif -/* Convert "" to a sockaddr_in TCP */ -//int string_to_sin(const char *addr, struct sockaddr_in *s_in); - -/* Split "" into parts: host, port, and params. If - the port or params are not in the string, the result is set to - NULL. Any of the result char** values may be NULL, in which case - they are parsed but not set. The caller is responsible for freeing - all result strings. -*/ -int split_sin( const char *addr, char **host, char **port, char **params ); - - -//char *sin_to_string(const struct sockaddr_in *s_in); - /* Extract the port from a string of the form "" */ int string_to_port( const char* addr ); -/* Extract the ip_addr from a string of the form "" - and convert it to the unsigned int version from the ASCII version */ -//unsigned int string_to_ip( const char* addr ); - /* Convert a hostname[:port] to sinful string */ char * hostname_to_string (const char * hostname, const int default_port ); const char *sock_to_string(SOCKET sockd); -/* - Puts socket peer's sinful address in buf. Returns this value or the - specified unknown value if address could not be determined. - Buffer should be at least SINFUL_STRING_BUF_SIZE, - but if it is less, the value will be truncated if necessary. -*/ -char const * -sock_peer_to_string( SOCKET fd, char *buf, size_t buflen, char const *unknown); - -/* Return the real hostname of a machine given a sin; return NULL if it cannot - * be found or error. Also return aliases. */ -//char *sin_to_hostname(const struct sockaddr_in *s_in, char ***aliases); - -//void -//display_from( struct sockaddr_in *from ); - /* Returns 1 if h1 and h2 are both hostnames which refer to the same host, 0 if they don't, and -1 on error. */ int same_host(const char *h1, const char *h2); @@ -114,11 +80,6 @@ char* getHostFromAddr( const char* addr ); */ char* getAddrFromClaimId( const char* id ); -/* Binds the given fd to any port on the correct local interface for - this machine. is_outgoing tells it how to param. Returns 1 if - successful, 0 on error. */ -int _condor_local_bind( int is_outgoing, int fd ); - // generates sinful string. // it detects whether given ip address is IPv4 or IPv6. int generate_sinful(char* buf, int len, const char* ip, int port); diff --git a/src/condor_includes/internet_obsolete.h b/src/condor_includes/internet_obsolete.h index 6a96b6ca7e8..ec4a6d8e128 100644 --- a/src/condor_includes/internet_obsolete.h +++ b/src/condor_includes/internet_obsolete.h @@ -1,4 +1,4 @@ -/*******char * ipport_to_string(const unsigned int ip, const unsigned short port)******************************************************** +/*************************************************************** * * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department, * University of Wisconsin-Madison, WI. @@ -18,7 +18,7 @@ ***************************************************************/ /* This file defines some of the obsolete functions from internet.h - * Except check point server, it should not be included! + * Except for standard universe code, it should not be included! */ #ifndef INTERNET_OBSOLETE_H @@ -28,7 +28,11 @@ extern "C" { #endif -char * ipport_to_string(const unsigned int ip, const unsigned short port); +/* Binds the given fd to any port on the correct local interface for + this machine. is_outgoing tells it how to param. Returns 1 if + successful, 0 on error. */ +int _condor_local_bind( int is_outgoing, int fd ); + struct sockaddr_in * getSockAddr(int sockfd); #if defined(__cplusplus) diff --git a/src/condor_includes/ipv6_addrinfo.h b/src/condor_includes/ipv6_addrinfo.h index dd3558fd5be..645b6c44337 100644 --- a/src/condor_includes/ipv6_addrinfo.h +++ b/src/condor_includes/ipv6_addrinfo.h @@ -38,7 +38,6 @@ class addrinfo_iterator protected: shared_context* cxt_; addrinfo* current_; - bool ipv6; }; // return with AI_ADDRCONFIG diff --git a/src/condor_includes/ipv6_hostname.h b/src/condor_includes/ipv6_hostname.h index 174a77b8abb..053f84963c1 100644 --- a/src/condor_includes/ipv6_hostname.h +++ b/src/condor_includes/ipv6_hostname.h @@ -76,9 +76,9 @@ std::vector resolve_hostname_raw(const MyString& hostname); // NODNS functions // -// IPv6-compliant version of convert_ip_to_hostname and -// convert_hostname_to_ip. -MyString convert_ipaddr_to_hostname(const condor_sockaddr& addr); -condor_sockaddr convert_hostname_to_ipaddr(const MyString& fullname); +// Construct fake hostnames based on an underlying IP address, +// avoiding any use of DNS. +MyString convert_ipaddr_to_fake_hostname(const condor_sockaddr& addr); +condor_sockaddr convert_fake_hostname_to_ipaddr(const MyString& fullname); #endif // IPV6_HOSTNAME_H diff --git a/src/condor_io/condor_auth_ssl.cpp b/src/condor_io/condor_auth_ssl.cpp index 8abe371b2c1..e9f12d0511d 100644 --- a/src/condor_io/condor_auth_ssl.cpp +++ b/src/condor_io/condor_auth_ssl.cpp @@ -220,20 +220,6 @@ int Condor_Auth_SSL::authenticate(const char * /* remoteHost */, CondorError* /* SSL_CTX *ctx = NULL; unsigned char session_key[AUTH_SSL_SESSION_KEY_LEN]; - /* This next bit is just to get the fqdn of the host we're communicating - with. One would think that remoteHost would have this, but it doesn't - seem to. -Ian - */ - /* After some discussion with Zach, we don't actually do any checking - that involves the host name, so whatever... - const char *peerHostAddr = getRemoteHost(); - struct hostent *he = condor_gethostbyname(peerHostAddr); - dprintf(D_SECURITY,"Peer addr: '%s'\n", peerHostAddr); - const char *peerHostName = get_full_hostname_from_hostent( - condor_gethostbyaddr(he->h_addr, sizeof he->h_addr, AF_INET), NULL); - dprintf(D_SECURITY,"Got hostname for peer: '%s'\n", peerHostName); - */ - // allocate a large buffer for comminications buffer = (char*) malloc( AUTH_SSL_BUF_SIZE ); diff --git a/src/condor_io/condor_ipverify.cpp b/src/condor_io/condor_ipverify.cpp index 8015a9b077e..cfd643deab2 100644 --- a/src/condor_io/condor_ipverify.cpp +++ b/src/condor_io/condor_ipverify.cpp @@ -697,7 +697,6 @@ void IpVerify :: split_entry(const char * perm_entry, char ** host, char** user) } else { condor_netaddr netaddr; if (netaddr.from_net_string(permbuf)) { - //if (is_valid_network(permbuf, NULL, NULL)) { *user = strdup("*"); *host = strdup(permbuf); } else { @@ -1221,71 +1220,3 @@ IpVerify::PermTypeEntry::~PermTypeEntry() { } } - -#ifdef WANT_STANDALONE_TESTING -#include "condor_io.h" -#ifdef WIN32 -# include - _CrtMemState s1, s2, s3; -#endif -int -main() -{ - char buf[50]; - char buf1[50]; - struct sockaddr_in sin; - SafeSock ssock; - IpVerify* userverify; - - set_mySubSystem( "COLLECTOR", SUBSYSTEM_TYPE_COLLECTOR ); - - config(); - -#ifdef WIN32 - _CrtMemCheckpoint( &s1 ); -#endif - - userverify = new IpVerify(); - - userverify->Init(); - - buf[0] = '\0'; - - while( 1 ) { - printf("Enter test:\n"); - scanf("%s",buf); - if ( strncmp(buf,"exit",4) == 0 ) - break; - if ( strncmp(buf,"reinit",6) == 0 ) { - config(); - userverify->Init(); - continue; - } - printf("Verifying %s ... ",buf); - sprintf(buf1,"<%s:1970>",buf); - string_to_sin(buf1,&sin); - if ( userverify->Verify(WRITE,&sin) == TRUE ) - printf("ALLOW\n"); - else - printf("DENY\n"); - } - - delete userverify; - -#ifdef WIN32 - _CrtMemCheckpoint( &s2 ); - // _CrtMemDumpAllObjectsSince( &s1 ); - _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); - _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT); - _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE); - _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDOUT); - _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE); - _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT); - if ( _CrtMemDifference( &s3, &s1, &s2 ) ) - _CrtMemDumpStatistics( &s3 ); - // _CrtDumpMemoryLeaks(); // report any memory leaks on Win32 -#endif - - return TRUE; -} -#endif // of WANT_STANDALONE_TESTING diff --git a/src/condor_io/condor_rw.cpp b/src/condor_io/condor_rw.cpp index 22f7847b48b..0127f63f075 100644 --- a/src/condor_io/condor_rw.cpp +++ b/src/condor_io/condor_rw.cpp @@ -27,6 +27,7 @@ #include "internet.h" #include "selector.h" #include "condor_threads.h" +#include "condor_sockfunc.h" /* * Returns true if the given error number indicates @@ -55,7 +56,14 @@ static char const *not_null_peer_description(char const *peer_description,SOCKET if( peer_description ) { return peer_description; } - return sock_peer_to_string(fd,sinbuf,SINFUL_STRING_BUF_SIZE,"disconnected socket"); + + condor_sockaddr addr; + if (condor_getpeername(fd, addr) < 0) { + return "disconnected socket"; + } + + addr.to_sinful(sinbuf, SINFUL_STRING_BUF_SIZE); + return sinbuf; } /* Generic read/write wrappers for condor. These function emulate-ish the diff --git a/src/condor_io/condor_secman.cpp b/src/condor_io/condor_secman.cpp index 98762be69a9..d8ab91c3ae8 100644 --- a/src/condor_io/condor_secman.cpp +++ b/src/condor_io/condor_secman.cpp @@ -2826,44 +2826,6 @@ SecMan::invalidateExpiredCache() } } -/* - - // a failure here signals that the cache may be invalid. - // delete this entry from table and force normal auth. - KeyCacheEntry * ek = NULL; - if (session_cache->lookup(keybuf, ek) == 0) { - delete ek; - } else { - dprintf (D_SECURITY, "SECMAN: unable to delete KeyCacheEntry.\n"); - } - session_cache->remove(keybuf); - m_have_session = false; - - // close this connection and start a new one - if (!sock->close()) { - dprintf ( D_ALWAYS, "SECMAN: could not close socket to %s\n", - sin_to_string(sock->peer_addr())); - return false; - } - - KeyInfo* nullp = 0; - if (!sock->set_crypto_key(false, nullp)) { - dprintf ( D_ALWAYS, "SECMAN: could not re-init crypto!\n"); - return false; - } - if (!sock->set_MD_mode(MD_OFF, nullp)) { - dprintf ( D_ALWAYS, "SECMAN: could not re-init MD5!\n"); - return false; - } - if (!sock->connect(sock->get_connect_addr(), 0)) { - dprintf ( D_ALWAYS, "SECMAN: could not reconnect to %s.\n", - sin_to_string(sock->peer_addr())); - return false; - } - - goto choose_action; -*/ - MyString SecMan::getDefaultAuthenticationMethods() { MyString methods; diff --git a/src/condor_schedd.V6/schedd_td.cpp b/src/condor_schedd.V6/schedd_td.cpp index a2fa6cd270c..20f137110b0 100644 --- a/src/condor_schedd.V6/schedd_td.cpp +++ b/src/condor_schedd.V6/schedd_td.cpp @@ -119,7 +119,11 @@ Scheduler::requestSandboxLocation(int mode, Stream* s) // ATTR_TREQ_HAS_CONSTRAINT // ATTR_TREQ_CONSTRAINT // ATTR_TREQ_XFP - getClassAd(rsock, reqad); + + if (!getClassAd(rsock, reqad)) { + rsock->end_of_message(); + return CLOSE_STREAM; + } rsock->end_of_message(); if (reqad.LookupBool(ATTR_TREQ_HAS_CONSTRAINT, has_constraint) == 0) { diff --git a/src/condor_shadow.std/shadow_common.cpp b/src/condor_shadow.std/shadow_common.cpp index 9d092f7acb2..902a5fbb982 100644 --- a/src/condor_shadow.std/shadow_common.cpp +++ b/src/condor_shadow.std/shadow_common.cpp @@ -31,6 +31,7 @@ #include "spooled_job_files.h" #include "condor_debug.h" #include "internet.h" +#include "internet_obsolete.h" #include "condor_uid.h" #include "condor_adtypes.h" #include "condor_attributes.h" diff --git a/src/condor_starter.V6.1/docker_proc.cpp b/src/condor_starter.V6.1/docker_proc.cpp index cac74ef2acb..8e0e8ddee61 100644 --- a/src/condor_starter.V6.1/docker_proc.cpp +++ b/src/condor_starter.V6.1/docker_proc.cpp @@ -353,8 +353,8 @@ bool DockerProc::JobReaper( int pid, int status ) { dprintf( D_ALWAYS | D_FAILURE, "Inspection of container '%s' failed to reveal its exit code.\n", containerName.c_str() ); return VanillaProc::JobReaper( pid, status ); } - dprintf( D_FULLDEBUG, "Setting status of Docker job to %d.\n", dockerStatus ); - status = dockerStatus; + status = dockerStatus > 128 ? (dockerStatus - 128) : (dockerStatus << 8); + dprintf( D_FULLDEBUG, "Setting status of Docker job to %d.\n", status ); // TODO: Record final job usage. diff --git a/src/condor_syscall_lib/special_stubs.cpp b/src/condor_syscall_lib/special_stubs.cpp index 09e902a6488..b8e822f987c 100644 --- a/src/condor_syscall_lib/special_stubs.cpp +++ b/src/condor_syscall_lib/special_stubs.cpp @@ -167,19 +167,6 @@ _condor_bind_all_interfaces( void ) } -struct hostent * -condor_gethostbyname( const char *name ) -{ - return gethostbyname( name ); -} - -struct hostent * -condor_gethostbyaddr( const char *addr, SOCKET_LENGTH_TYPE len, int type ) - -{ - return gethostbyaddr( addr, len, type ); -} - int condor_gethostname( char *name, size_t namelen ) { diff --git a/src/condor_transferd/td_read_files.cpp b/src/condor_transferd/td_read_files.cpp index 38c73991111..e31b662620d 100644 --- a/src/condor_transferd/td_read_files.cpp +++ b/src/condor_transferd/td_read_files.cpp @@ -96,7 +96,11 @@ TransferD::read_files_handler(int /* cmd */, Stream *sock) rsock->decode(); // soak the request ad from the client about what it wants to transfer - getClassAd(rsock, reqad); + if (!getClassAd(rsock, reqad)) { + rsock->end_of_message(); + return CLOSE_STREAM; + } + rsock->end_of_message(); reqad.LookupString(ATTR_TREQ_CAPABILITY, capability); diff --git a/src/condor_transferd/td_write_files.cpp b/src/condor_transferd/td_write_files.cpp index c46567a9181..4832a9d339b 100644 --- a/src/condor_transferd/td_write_files.cpp +++ b/src/condor_transferd/td_write_files.cpp @@ -97,7 +97,10 @@ TransferD::write_files_handler(int /* cmd */, Stream *sock) rsock->decode(); // soak the request ad from the client about what it wants to transfer - getClassAd(rsock, reqad); + if (!getClassAd(rsock, reqad)) { + return CLOSE_STREAM; + } + rsock->end_of_message(); reqad.LookupString(ATTR_TREQ_CAPABILITY, capability); diff --git a/src/condor_unit_tests/FTEST_getPortFromAddr.cpp b/src/condor_unit_tests/FTEST_getPortFromAddr.cpp index 6e144196772..11ccd3ee6fb 100644 --- a/src/condor_unit_tests/FTEST_getPortFromAddr.cpp +++ b/src/condor_unit_tests/FTEST_getPortFromAddr.cpp @@ -18,7 +18,7 @@ ***************************************************************/ /* - This code tests the sin_to_string() function implementation. + This code tests the getPortFromAddr() function implementation. */ #include "condor_common.h" diff --git a/src/condor_unit_tests/FTEST_host_in_domain.cpp b/src/condor_unit_tests/FTEST_host_in_domain.cpp index 21511e1b621..a6bc9bdbad2 100644 --- a/src/condor_unit_tests/FTEST_host_in_domain.cpp +++ b/src/condor_unit_tests/FTEST_host_in_domain.cpp @@ -18,7 +18,7 @@ ***************************************************************/ /* - This code tests the sin_to_string() function implementation. + This code tests the host_in_domain() function implementation. */ #include "condor_common.h" diff --git a/src/condor_unit_tests/FTEST_is_valid_sinful.cpp b/src/condor_unit_tests/FTEST_is_valid_sinful.cpp index 0df2bf5fd4e..43c83c4e01c 100644 --- a/src/condor_unit_tests/FTEST_is_valid_sinful.cpp +++ b/src/condor_unit_tests/FTEST_is_valid_sinful.cpp @@ -18,7 +18,7 @@ ***************************************************************/ /* - This code tests the sin_to_string() function implementation. + This code tests the is_valid_sinful() function implementation. */ #include "condor_common.h" diff --git a/src/condor_unit_tests/FTEST_sin_to_hostname.cpp b/src/condor_unit_tests/FTEST_sin_to_hostname.cpp deleted file mode 100644 index da0396f2b38..00000000000 --- a/src/condor_unit_tests/FTEST_sin_to_hostname.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/*************************************************************** - * - * 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. - * - ***************************************************************/ - -/* - This code tests the sin_to_string() function implementation. - */ - -#include "condor_common.h" -#include "condor_debug.h" -#include "condor_config.h" -#include "internet.h" -#include "function_test_driver.h" -#include "unit_test_utils.h" -#include "emit.h" - -static bool test_normal_case(void); - -bool FTEST_sin_to_hostname(void) { - // beginning junk for getPortFromAddr(() { - emit_function("sin_to_hostname(const char*, char*** aliases)"); - emit_comment("Converts a sinful string to a hostname."); - emit_problem("None"); - - // driver to run the tests and all required setup - FunctionDriver driver; - driver.register_function(test_normal_case); - - // run the tests - return driver.do_all_functions(); -} - -static bool test_normal_case() { - /* - emit_test("Is normal input converted correctly?"); - struct sockaddr_in ip; - char* host_to_test = strdup( "www.google.com" ); - // it's okay that host_to_test will be freed when we use aliases, - // because it just matters that this isn't null - char** aliases = &host_to_test; - struct hostent *h; - h = gethostbyname(host_to_test); - ip.sin_addr = *((in_addr*) h->h_addr); - emit_input_header(); - emit_param("IP", inet_ntoa(ip.sin_addr)); - emit_output_expected_header(); - char expected[30]; - sprintf(expected, h->h_name); - free(host_to_test); - emit_retval(expected); - emit_output_actual_header(); - char* hostname = sin_to_hostname(&ip, &aliases); - emit_retval(hostname); - if(*aliases == NULL) { - dprintf(D_ALWAYS, "I am a fish!\n"); - } - if(strcmp(&expected[0], hostname) != 0) { - FAIL; - } - */ - PASS; -} diff --git a/src/condor_unit_tests/FTEST_sin_to_string.cpp b/src/condor_unit_tests/FTEST_sin_to_string.cpp deleted file mode 100644 index bd4f13918d5..00000000000 --- a/src/condor_unit_tests/FTEST_sin_to_string.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/*************************************************************** - * - * 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. - * - ***************************************************************/ - -/* - This code tests the sin_to_string() function implementation. - */ - -#include "condor_common.h" -#include "condor_debug.h" -#include "condor_config.h" -#include "internet.h" -#include "function_test_driver.h" -#include "unit_test_utils.h" -#include "emit.h" - -#include "condor_sockaddr.h" - -// IPV6_REMOVED - IPv6 changes obsoleted these interfaces. However, -// these tests probably should be updated to the new interfaces, -// so they are being kept here for nwo. -#ifdef IPV6_REMOVED -static bool test_normal_case(void); -#endif - -bool FTEST_sin_to_string(void) { - const char* h = "<[fe80::862b:2bff:fe98:65f2]:9618>"; - condor_sockaddr addr; - addr.from_sinful(h); - - - // beginning junk for getPortFromAddr(() { - emit_function("sin_to_string(sockaddr_in)"); - emit_comment("Converts a sockaddr_in to a sinful string."); - emit_problem("None"); - - // driver to run the tests and all required setup - FunctionDriver driver; -#ifdef IPV6_REMOVED - driver.register_function(test_normal_case); -#endif - - // run the tests - return driver.do_all_functions(); -} - -#ifdef IPV6_REMOVED -static bool test_normal_case() { - emit_test("Is normal input converted correctly?"); -#ifdef WIN32 - unsigned long address = inet_addr("192.168.0.2"); - if(address == INADDR_NONE || address == INADDR_ANY) { -#else - in_addr ip; - if(inet_aton("192.168.0.2", &ip) == 0) { -#endif - emit_alert("inet_aton() returned failure."); - ABORT; - } - unsigned int port = 47; - emit_input_header(); - emit_param("IP", "192.168.0.2"); - emit_param("PORT", "47"); - emit_output_expected_header(); - char* expected = strdup("<192.168.0.2:47>"); - emit_retval(expected); - emit_output_actual_header(); - sockaddr_in sa_in; -#ifdef WIN32 - sa_in.sin_addr.s_addr = address; -#else - sa_in.sin_addr.s_addr = ip.s_addr; -#endif - sa_in.sin_port = htons(port); - char* sinstring = sin_to_string(&sa_in); - emit_retval(sinstring); - if(strcmp(expected, sinstring) != 0) { - free(expected); - free(sinstring); - FAIL; - } - free(expected); - PASS; -} -#endif diff --git a/src/condor_unit_tests/FTEST_stl_string_utils.cpp b/src/condor_unit_tests/FTEST_stl_string_utils.cpp index a3bced80e72..a4eda2f6aad 100644 --- a/src/condor_unit_tests/FTEST_stl_string_utils.cpp +++ b/src/condor_unit_tests/FTEST_stl_string_utils.cpp @@ -18,7 +18,7 @@ ***************************************************************/ /* - This code tests the sin_to_string() function implementation. + This code tests some of our string manipulation utility functions. */ #include "condor_common.h" @@ -59,7 +59,6 @@ static bool tokenize_empty(void); static bool tokenize_empty_delimiter(void); bool FTEST_stl_string_utils(void) { - // beginning junk for getPortFromAddr(() { emit_function("STL string utils"); emit_comment("Package of functions/operators to facilitate adoption of std::string"); diff --git a/src/condor_unit_tests/FTEST_string_to_port.cpp b/src/condor_unit_tests/FTEST_string_to_port.cpp index 4639917cc89..5bc15805ca6 100644 --- a/src/condor_unit_tests/FTEST_string_to_port.cpp +++ b/src/condor_unit_tests/FTEST_string_to_port.cpp @@ -18,7 +18,7 @@ ***************************************************************/ /* - This code tests the sin_to_string() function implementation. + This code tests the string_to_port() function implementation. */ #include "condor_common.h" diff --git a/src/condor_unit_tests/unit_tests.cpp b/src/condor_unit_tests/unit_tests.cpp index 5f9a6ddf05b..f36ff74e548 100644 --- a/src/condor_unit_tests/unit_tests.cpp +++ b/src/condor_unit_tests/unit_tests.cpp @@ -39,7 +39,6 @@ bool FTEST_host_in_domain(void); bool FTEST_getHostFromAddr(void); bool FTEST_getPortFromAddr(void); bool FTEST_is_valid_sinful(void); -bool FTEST_sin_to_string(void); bool FTEST_string_to_port(void); bool FTEST_strupr(void); bool FTEST_strlwr(void); @@ -73,7 +72,6 @@ const static struct { map(FTEST_getHostFromAddr), map(FTEST_getPortFromAddr), map(FTEST_is_valid_sinful), - map(FTEST_sin_to_string), map(FTEST_string_to_port), map(FTEST_strupr), map(FTEST_strlwr), diff --git a/src/condor_utils/ClassAdLogProber.cpp b/src/condor_utils/ClassAdLogProber.cpp index cfaacc36baf..d986bd61dbc 100644 --- a/src/condor_utils/ClassAdLogProber.cpp +++ b/src/condor_utils/ClassAdLogProber.cpp @@ -61,7 +61,8 @@ void ClassAdLogProber::setJobQueueName(const char* jqn) { assert(jqn); - strcpy(job_queue_name, jqn); + strncpy(job_queue_name, jqn, PATH_MAX); + job_queue_name[PATH_MAX - 1] = '\0'; } char* diff --git a/src/condor_utils/classad_oldnew.cpp b/src/condor_utils/classad_oldnew.cpp index 425059720df..87eb9faad24 100644 --- a/src/condor_utils/classad_oldnew.cpp +++ b/src/condor_utils/classad_oldnew.cpp @@ -700,8 +700,6 @@ int _putClassAd_v0( Stream *sock, classad::ClassAd& ad, bool excludeTypes, bool buf += " = "; unp.Unparse( buf, expr ); - ConvertDefaultIPToSocketIP(attr.c_str(),buf,*sock); - if( ! sock->prepare_crypto_for_secret_is_noop() && compat_classad::ClassAdAttributeIsPrivate(attr.c_str())) { @@ -800,7 +798,6 @@ int _putClassAd_v0( Stream *sock, classad::ClassAd& ad, bool excludeTypes, bool else { unp.Unparse( buf, expr ); } - ConvertDefaultIPToSocketIP(attr,buf,*sock); if( ! sock->prepare_crypto_for_secret_is_noop() && compat_classad::ClassAdAttributeIsPrivate(attr) ) @@ -1047,8 +1044,6 @@ int _putClassAd( Stream *sock, classad::ClassAd& ad, int options) buf += " = "; unp.Unparse( buf, expr ); - ConvertDefaultIPToSocketIP(attr.c_str(),buf,*sock); - if( ! sock->prepare_crypto_for_secret_is_noop() && compat_classad::ClassAdAttributeIsPrivate(attr.c_str())) { @@ -1112,13 +1107,16 @@ int _putClassAd( Stream *sock, classad::ClassAd& ad, int options, const classad: buf = *attr; buf += " = "; unp.Unparse( buf, expr ); - ConvertDefaultIPToSocketIP(attr->c_str(),buf,*sock); if ( ! sock->prepare_crypto_for_secret_is_noop() && compat_classad::ClassAdAttributeIsPrivate(attr->c_str()) ) { - sock->put(SECRET_MARKER); - sock->put_secret(buf.c_str()); + if (!sock->put(SECRET_MARKER)) { + return false; + } + if (!sock->put_secret(buf.c_str())) { + return false; + } } else if ( ! sock->put(buf.c_str()) ){ return false; diff --git a/src/condor_utils/condor_config.cpp b/src/condor_utils/condor_config.cpp index c5abaf5c539..95d464fac58 100644 --- a/src/condor_utils/condor_config.cpp +++ b/src/condor_utils/condor_config.cpp @@ -1072,15 +1072,18 @@ real_config(const char* host, int wantsQuiet, int config_options) // Now, insert any macros defined in the environment. char **my_environ = GetEnviron(); - for( int i = 0; my_environ[i]; i++ ) { - char magic_prefix[MAX_DISTRIBUTION_NAME + 3]; // case-insensitive - strcpy( magic_prefix, "_" ); - strcat( magic_prefix, myDistro->Get() ); - strcat( magic_prefix, "_" ); - int prefix_len = (int)strlen( magic_prefix ); + // Build "magic_prefix" with _condor_, or w/e distro we are + + std::string magic_prefix; + magic_prefix += "_"; + magic_prefix += myDistro->Get(); + magic_prefix += "_"; + int prefix_len = magic_prefix.size(); + + for( int i = 0; my_environ[i]; i++ ) { // proceed only if we see the magic prefix - if( strncasecmp( my_environ[i], magic_prefix, prefix_len ) != 0 ) { + if( strncasecmp( my_environ[i], magic_prefix.c_str(), prefix_len ) != 0 ) { continue; } @@ -1128,7 +1131,6 @@ real_config(const char* host, int wantsQuiet, int config_options) free( config_source ); } - // init_ipaddr and init_full_hostname is now obsolete CondorError errorStack; if(! init_network_interfaces( & errorStack )) { const char * subsysName = get_mySubSystem()->getName(); @@ -1146,11 +1148,6 @@ real_config(const char* host, int wantsQuiet, int config_options) reset_local_hostname(); } - // Also, we should be safe to process the NETWORK_INTERFACE - // parameter at this point, if it's set. - //init_ipaddr( TRUE ); - - // The IPv6 code currently caches some results that depend // on configuration settings such as NETWORK_INTERFACE. // Therefore, force the cache to be reset, now that the @@ -1182,8 +1179,6 @@ real_config(const char* host, int wantsQuiet, int config_options) // and non-daemons to do. condor_auth_config( false ); - ConfigConvertDefaultIPToSocketIP(); - //Configure condor_fsync condor_fsync_on = param_boolean("CONDOR_FSYNC", true); if(!condor_fsync_on) diff --git a/src/condor_utils/condor_netaddr.cpp b/src/condor_utils/condor_netaddr.cpp index 156d4f4cd69..753b29056c5 100644 --- a/src/condor_utils/condor_netaddr.cpp +++ b/src/condor_utils/condor_netaddr.cpp @@ -116,6 +116,8 @@ bool condor_netaddr::from_net_string(const char* net) { if (maskbit_ == (unsigned int)-1) { return false; } + } else { + return false; } } } else { @@ -138,9 +140,7 @@ bool condor_netaddr::from_net_string(const char* net) { // IPv6 literal or asterisk. const char * asterisk = strchr( net, '*' ); if( asterisk == NULL ) { - struct in6_addr in6a; - if( inet_pton( AF_INET6, net, & in6a ) == 1 ) { - base_ = condor_sockaddr( in6a ); + if ( base_.from_ip_string( net ) ) { maskbit_ = 128; return true; } else { diff --git a/src/condor_utils/condor_netdb.cpp b/src/condor_utils/condor_netdb.cpp index e5dbd458c55..6bbe593c397 100644 --- a/src/condor_utils/condor_netdb.cpp +++ b/src/condor_utils/condor_netdb.cpp @@ -26,20 +26,7 @@ #include "condor_netdb.h" #include "ipv6_hostname.h" #include "condor_sockfunc.h" - -#ifndef NI_MAXHOST -#define NI_MAXHOST 1025 -#endif - -typedef union sockaddr_storage_ptr_u { - struct sockaddr *raw; - struct sockaddr_in *in; -} sockaddr_storage_ptr; - -typedef union in_addr_ptr_u { - const char *as_char; - struct in_addr *in; -} in_addr_ptr; +#include "my_hostname.h" /* SPECIAL NAMES: * @@ -50,107 +37,12 @@ typedef union in_addr_ptr_u { * XXX.XXX.XXX.XXX. */ -/* param_boolean() and param_boolean_int() are C++-only functions, so - * we roll our own version for checking NO_DNS. :-( - */ -static int -nodns_enabled( void ) -{ - return param_boolean_crufty("NO_DNS", false) ? 1 : 0; -} - /* WARNING: None of these functions properly set h_error, or errno */ -int -convert_ip_to_hostname(const char *addr, - char *h_name, - int maxlen); - -int -convert_hostname_to_ip(const char *name, - char **h_addr_list, - int maxaddrs); - -struct hostent * get_nodns_hostent(const char* name) -{ - // We simulate at most 1 addr - #define MAXSIMULATEDADDRS 2 - - static struct hostent hostent; - static char *h_aliases[1] = {NULL}; - static char *h_addr_list[MAXSIMULATEDADDRS]; - static char h_name[NI_MAXHOST]; - - if (convert_hostname_to_ip(name, h_addr_list, MAXSIMULATEDADDRS)) { - // We've failed - return NULL; - } else { - memset(h_name, 0, MAXSIMULATEDADDRS); - strncpy(h_name, name, NI_MAXHOST - 1); - hostent.h_name = h_name; - hostent.h_aliases = h_aliases; - hostent.h_addrtype = AF_INET; - hostent.h_length = sizeof(struct in_addr); - hostent.h_addr_list = h_addr_list; - - return &hostent; - } -} - -struct hostent * -condor_gethostbyname_ipv4(const char *name) { - if (nodns_enabled()) { - return get_nodns_hostent(name); - } else { - return gethostbyname(name); - } -} - -struct hostent * -condor_gethostbyname(const char *name) -{ - // condor_gethostbyname_ipv6 is obsolete - return condor_gethostbyname_ipv4(name); -} - -struct hostent* get_nodns_addr(const char* addr) { - static struct hostent hostent; - static char *h_aliases[1] = {NULL}; - static char h_name[NI_MAXHOST]; // from /usr/include/sys/param.h - - if (convert_ip_to_hostname(addr, h_name, MAXHOSTNAMELEN)) { - // We've failed - return NULL; - } else { - hostent.h_name = h_name; - hostent.h_aliases = h_aliases; - hostent.h_addrtype = AF_INET; - hostent.h_length = 0; - hostent.h_addr_list = NULL; - - return &hostent; - } -} - -struct hostent * -condor_gethostbyaddr_ipv4(const char *addr, SOCKET_LENGTH_TYPE len, int type) { - if (nodns_enabled()) { - return get_nodns_addr(addr); - } else { - return gethostbyaddr(addr, len, type); - } -} - -struct hostent * -condor_gethostbyaddr(const char *addr, SOCKET_LENGTH_TYPE len, int type) { - // condor_gethostbyaddr_ipv6 is obsolete - return condor_gethostbyaddr_ipv4(addr, len, type); -} - int condor_gethostname(char *name, size_t namelen) { - if (nodns_enabled()) { + if (param_boolean("NO_DNS", false)) { char tmp[MAXHOSTNAMELEN]; char *param_buf; @@ -165,7 +57,15 @@ condor_gethostname(char *name, size_t namelen) { dprintf( D_HOSTNAME, "NO_DNS: Using NETWORK_INTERFACE='%s' " "to determine hostname\n", param_buf ); - snprintf( ip_str, MAXHOSTNAMELEN, "%s", param_buf ); + std::string ipv4; + std::string ipv6; + std::string ipbest; + if ( !network_interface_to_ip("NETWORK_INTERFACE", param_buf, ipv4, ipv6, ipbest) ) { + dprintf(D_HOSTNAME, "NO_DNS: network_interface_to_ip() failed\n"); + free( param_buf ); + return -1; + } + snprintf( ip_str, MAXHOSTNAMELEN, "%s", ipbest.c_str() ); free( param_buf ); if (!addr.from_ip_string(ip_str)) { @@ -175,7 +75,7 @@ condor_gethostname(char *name, size_t namelen) { return -1; } - MyString hostname = convert_ipaddr_to_hostname(addr); + MyString hostname = convert_ipaddr_to_fake_hostname(addr); if (hostname.Length() >= (int) namelen) { return -1; } @@ -253,7 +153,7 @@ condor_gethostname(char *name, size_t namelen) { } close(s); - MyString hostname = convert_ipaddr_to_hostname(addr); + MyString hostname = convert_ipaddr_to_fake_hostname(addr); if (hostname.Length() >= (int) namelen) { return -1; } @@ -277,7 +177,7 @@ condor_gethostname(char *name, size_t namelen) { return -1; } - MyString hostname = convert_ipaddr_to_hostname(addrs.front()); + MyString hostname = convert_ipaddr_to_fake_hostname(addrs.front()); if (hostname.Length() >= (int) namelen) { return -1; } @@ -294,128 +194,3 @@ condor_gethostname(char *name, size_t namelen) { } } -int -convert_ip_to_hostname(const char *addr, - char *h_name, - int maxlen) { - char *default_domain_name; - - if (NULL != (default_domain_name = param("DEFAULT_DOMAIN_NAME"))) { - int h_name_len; - int i; - in_addr_ptr in_address_ptr; - in_address_ptr.as_char = addr; - strncpy(h_name, inet_ntoa(*(in_address_ptr.in)), maxlen - 1); - for (i = 0; h_name[i]; i++) { - if ('.' == h_name[i]) { - h_name[i] = '-'; - } - } - h_name[maxlen-1] = 0; // make sure of null term - h_name_len = strlen(h_name); - snprintf(&(h_name[h_name_len]), maxlen - h_name_len, ".%s", - default_domain_name); - - free(default_domain_name); - return 0; - } else { - dprintf(D_HOSTNAME, - "NO_DNS: DEFAULT_DOMAIN_NAME must be defined in your " - "top-level config file\n"); - return -1; - } -} - -int -convert_hostname_to_ip(const char *name, - char **h_addr_list, - int maxaddrs) { - static struct in_addr addr; - char tmp_name[MAXHOSTNAMELEN]; // could get away with 16 for IPv4 - char *default_domain_name; - int ret; - - // We need at least one place for an address - if (2 > maxaddrs) { - return -1; - } - - // We do at most one address - h_addr_list[1] = NULL; - - if (NULL != (default_domain_name = param("DEFAULT_DOMAIN_NAME"))) { - int i; - const char *idx; - // XXX: What I really want to do here is to not try to - // parse names that do not contain the DEFAULT_DOMAIN_NAME - // suffix, but for some reason line 517 of condor_config.C - // tries to reconfigure the full_hostname and subsequently - // calls this function with a hostname that is of the form - // XXX-XXX-XXX-XXX except without a suffix. Argh, so - // instead of failing when there is no suffix I must try - // to parse anyway! -// This is the code I want, but it's not what I get to use (below) -// if (NULL != (idx = strstr(name, default_domain_name))) { -// int i; -// memset(tmp_name, 0, MAXHOSTNAMELEN); -// strncpy(tmp_name, name, idx - name); -// for (i = 0; tmp_name[i]; i++) { -// if ('-' == tmp_name[i]) { -// tmp_name[i] = '.'; -// } -// } -// -// addr.s_addr = inet_addr(tmp_name); -// if (addr.s_addr == (unsigned long)(-1L)) { -// // Parsing failed, so we will too -// h_addr_list[0] = NULL; -// -// return -1; -// } else { -// h_addr_list[0] = (char *) &addr; -// -// return 0; -// } -// } else { -// dprintf(D_HOSTNAME, -// "All hostnames must end with '%s' " -// "(DEFAULT_DOMAIN_NAME) in NODNS operation\n", -// default_domain_name); -// -// return -1; -// } - - memset(tmp_name, 0, MAXHOSTNAMELEN); - idx = strstr(name, default_domain_name); - if (NULL != idx) { - strncpy(tmp_name, name, idx - name - 1); - } else { - strncpy(tmp_name, name, MAXHOSTNAMELEN - 1); - } - - free( default_domain_name ); - - for (i = 0; tmp_name[i]; i++) { - if ('-' == tmp_name[i]) { - tmp_name[i] = '.'; - } - } - - ret = inet_pton( AF_INET, tmp_name, &addr.s_addr); - if (ret<=0) { - // Parsing failed, so we will too - h_addr_list[0] = NULL; - - return -1; - } else { - h_addr_list[0] = (char *) &addr; - - return 0; - } - } else { - dprintf(D_HOSTNAME, - "NO_DNS: DEFAULT_DOMAIN_NAME must be defined in your " - "top-level config file\n"); - return -1; - } -} diff --git a/src/condor_utils/condor_perms.cpp b/src/condor_utils/condor_perms.cpp index 8aabb0f61ac..0a8a8332a14 100644 --- a/src/condor_utils/condor_perms.cpp +++ b/src/condor_utils/condor_perms.cpp @@ -55,7 +55,6 @@ PermString( DCpermission perm ) default: return "Unknown"; } - return "Unknown"; }; diff --git a/src/condor_utils/condor_sinful.cpp b/src/condor_utils/condor_sinful.cpp index d71ba6921ca..b636b47a363 100644 --- a/src/condor_utils/condor_sinful.cpp +++ b/src/condor_utils/condor_sinful.cpp @@ -26,6 +26,99 @@ #include +/* Split "" into parts: host, port, and params. If + the port or params are not in the string, the result is set to + NULL. Any of the result char** values may be NULL, in which case + they are parsed but not set. The caller is responsible for freeing + all result strings. +*/ +static int +split_sin( const char *addr, char **host, char **port, char **params ) +{ + int len; + + if( host ) *host = NULL; + if( port ) *port = NULL; + if( params ) *params = NULL; + + if( !addr || *addr != '<' ) { + return 0; + } + addr++; + + if (*addr == '[') { + addr++; + // ipv6 address + const char* pos = strchr(addr, ']'); + if (!pos) { + // mis-match bracket + return 0; + } + if ( host ) { + *host = (char*)malloc(pos - addr + 1); + ASSERT( *host ); + memcpy(*host, addr, pos - addr); + (*host)[pos - addr] = '\0'; + } + addr = pos + 1; + } else { + // everything else + len = strcspn(addr,":?>"); + if( host ) { + *host = (char *)malloc(len+1); + ASSERT( *host ); + memcpy(*host,addr,len); + (*host)[len] = '\0'; + } + addr += len; + } + + if( *addr == ':' ) { + addr++; + // len = strspn(addr,"0123456789"); + // Reimplemented without strspn because strspn causes valgrind + // errors on RHEL6. + const char * addr_ptr = addr; + len = 0; + while (*addr_ptr && isdigit(*addr_ptr++)) len++; + + if( port ) { + *port = (char *)malloc(len+1); + memcpy(*port,addr,len); + (*port)[len] = '\0'; + } + addr += len; + } + + if( *addr == '?' ) { + addr++; + len = strcspn(addr,">"); + if( params ) { + *params = (char *)malloc(len+1); + memcpy(*params,addr,len); + (*params)[len] = '\0'; + } + addr += len; + } + + if( addr[0] != '>' || addr[1] != '\0' ) { + if( host ) { + free( *host ); + *host = NULL; + } + if( port ) { + free( *port ); + *port = NULL; + } + if( params ) { + free( *params ); + *params = NULL; + } + return 0; + } + return 1; +} + static bool urlDecode(char const *str,size_t max,std::string &result) { @@ -495,17 +588,15 @@ Sinful::Sinful( char const * sinful ) { } break; default: { - // If this is a naked IPv6 address, reject, since we can't - // reliably tell where the address ends and the port begins. - if( hasTwoColonsInHost( sinful ) ) { - m_valid = false; - return; - } - // Otherwise, it may be an unbracketed original Sinful from // an old implementation of CCB... or from the command line, // or from a config setting. - formatstr( m_sinfulString, "<%s>", sinful ); + // If it's a naked IPv6 address, add square brackets. + if ( hasTwoColonsInHost( sinful ) ) { + formatstr( m_sinfulString, "<[%s]>", sinful ); + } else { + formatstr( m_sinfulString, "<%s>", sinful ); + } parseSinfulString(); } break; } diff --git a/src/condor_utils/condor_sockaddr.cpp b/src/condor_utils/condor_sockaddr.cpp index 0fa2ca23f7d..bf08ef0d002 100644 --- a/src/condor_utils/condor_sockaddr.cpp +++ b/src/condor_utils/condor_sockaddr.cpp @@ -614,7 +614,14 @@ bool condor_sockaddr::is_private_network() const return p10.match(*this) || p172_16.match(*this) || p192_168.match(*this); } else if (is_ipv6()) { - return IN6_IS_ADDR_LINKLOCAL(&v6.sin6_addr); + static bool initialized = false; + static condor_netaddr pfc00; + if(!initialized) { + pfc00.from_net_string("fc00::/7"); + initialized = true; + } + + return pfc00.match(*this); } else { @@ -738,18 +745,17 @@ bool condor_sockaddr::operator==(const condor_sockaddr& rhs) const bool condor_sockaddr::is_link_local() const { if (is_ipv4()) { - static struct in_addr link_mask; static bool initialized = false; + static condor_netaddr p169_254; if(!initialized) { - int converted = inet_pton(AF_INET, "169.254.0.0", &link_mask); - ASSERT(converted); + p169_254.from_net_string("169.254.0.0/16"); initialized = true; } - return ((uint32_t)v4.sin_addr.s_addr & link_mask.s_addr) == link_mask.s_addr; + + return p169_254.match(*this); } else if (is_ipv6()) { - // it begins with fe80 - return v6.sin6_addr.s6_addr[0] == 0xfe && - v6.sin6_addr.s6_addr[1] == 0x80; + // fe80::/10 + return IN6_IS_ADDR_LINKLOCAL(&v6.sin6_addr); } return false; } diff --git a/src/condor_utils/config.cpp b/src/condor_utils/config.cpp index e121ea01082..a905f33ebc9 100644 --- a/src/condor_utils/config.cpp +++ b/src/condor_utils/config.cpp @@ -3575,6 +3575,7 @@ static const char * evaluate_macro_func ( case SPECIAL_MACRO_ID_FILENAME: { const char * mval = lookup_macro(name, macro_set, ctx); + if ( ! mval) mval = body; tvalue = NULL; auto_free_ptr tmp2; diff --git a/src/condor_utils/globus_utils.cpp b/src/condor_utils/globus_utils.cpp index 0386f68e7cd..9d03fb4dd27 100644 --- a/src/condor_utils/globus_utils.cpp +++ b/src/condor_utils/globus_utils.cpp @@ -1645,7 +1645,7 @@ x509_receive_delegation( const char *destination_file, (*globus_gsi_proxy_handle_attrs_destroy_ptr)( handle_attrs ); } // Error! Cleanup memory immediately and return. - if ( rc && st ) { + if ( rc ) { if ( st->m_request_handle ) { (*globus_gsi_proxy_handle_destroy_ptr)( st->m_request_handle ); } diff --git a/src/condor_utils/internet.cpp b/src/condor_utils/internet.cpp index 6aee77c5540..e8a5ae8d78b 100644 --- a/src/condor_utils/internet.cpp +++ b/src/condor_utils/internet.cpp @@ -46,150 +46,10 @@ extern "C" { #endif +static int bindWithin(const int fd, const int low_port, const int high_port); -/* Split "" into parts: host, port, and params. If - the port or params are not in the string, the result is set to - NULL. Any of the result char** values may be NULL, in which case - they are parsed but not set. The caller is responsible for freeing - all result strings. -*/ -int -split_sin( const char *addr, char **host, char **port, char **params ) -{ - int len; - - if( host ) *host = NULL; - if( port ) *port = NULL; - if( params ) *params = NULL; - - if( !addr || *addr != '<' ) { - return 0; - } - addr++; - - if (*addr == '[') { - addr++; - // ipv6 address - const char* pos = strchr(addr, ']'); - if (!pos) { - // mis-match bracket - return 0; - } - if ( host ) { - *host = (char*)malloc(pos - addr + 1); - ASSERT( *host ); - memcpy(*host, addr, pos - addr); - (*host)[pos - addr] = '\0'; - } - addr = pos + 1; - } else { - // everything else - len = strcspn(addr,":?>"); - if( host ) { - *host = (char *)malloc(len+1); - ASSERT( *host ); - memcpy(*host,addr,len); - (*host)[len] = '\0'; - } - addr += len; - } - - if( *addr == ':' ) { - addr++; - // len = strspn(addr,"0123456789"); - // Reimplemented without strspn because strspn causes valgrind - // errors on RHEL6. - const char * addr_ptr = addr; - len = 0; - while (*addr_ptr && isdigit(*addr_ptr++)) len++; - - if( port ) { - *port = (char *)malloc(len+1); - memcpy(*port,addr,len); - (*port)[len] = '\0'; - } - addr += len; - } - - if( *addr == '?' ) { - addr++; - len = strcspn(addr,">"); - if( params ) { - *params = (char *)malloc(len+1); - memcpy(*params,addr,len); - (*params)[len] = '\0'; - } - addr += len; - } - - if( addr[0] != '>' || addr[1] != '\0' ) { - if( host ) { - free( *host ); - *host = NULL; - } - if( port ) { - free( *port ); - *port = NULL; - } - if( params ) { - free( *params ); - *params = NULL; - } - return 0; - } - return 1; -} - - -/* Convert a string of the form "" to a - sockaddr_in TCP (Also allow strings of the form "") - The ?params part is optional. Use string_to_sin_params() to get the value - of params. - - This function has a unit test. -*/ - -//int -//string_to_sin( const char *addr, struct sockaddr_in *sa_in ) -//{ -// char *host=NULL; -// char *port=NULL; -// int result; -// -// result = split_sin(addr,&host,&port,NULL); -// -// if( result ) { -// result = address_to_sin(host,port,sa_in); -// } -// -// free( host ); -// free( port ); -// -// return result; -//} - -/* This function has a unit test. */ -//char * -//sin_to_string(const struct sockaddr_in *sa_in) -//{ -// static char buf[SINFUL_STRING_BUF_SIZE]; -// -// buf[0] = '\0'; -// if (!sa_in) return buf; -// buf[0] = '<'; -// buf[1] = '\0'; -// if (sa_in->sin_addr.s_addr == INADDR_ANY) { -// strcat(buf, my_ip_string()); -// } else { -// strcat(buf, inet_ntoa(sa_in->sin_addr)); -// } -// sprintf(&buf[strlen(buf)], ":%d>", ntohs(sa_in->sin_port)); -// return buf; -//} - - const char * sock_to_string(SOCKET sockd) { @@ -203,20 +63,6 @@ sock_to_string(SOCKET sockd) return sinful; } -char const * -sock_peer_to_string( SOCKET fd, char *buf, size_t buflen, char const *unknown ) -{ - condor_sockaddr addr; - if (condor_getpeername(fd, addr) <0) - return unknown; - - addr.to_sinful(buf, buflen); - return buf; -} - - - - int same_host(const char *h1, const char *h2) @@ -370,109 +216,6 @@ is_ipv4_addr_implementation(const char *inbuf, struct in_addr *sin_addr, } -/* - is_ipaddr() returns TRUE if buf is an ascii IP address (like - "144.11.11.11") and false if not (like "cs.wisc.edu"). Allow - wildcard "*". If we return TRUE, and we were passed in a non-NULL - sin_addr, it's filled in with the integer version of the ip address. -NOTE: it looks like sin_addr may be modified even if the return - value is FALSE. -zmiller -*/ -/* XXX: Known problems: This function succeeds even if something with less - * than four octets is passed in without a wildcard. Also, strings with - * multiple wildcards (such as 192.168.*.*) are not allowed, perhaps those - * should be considered the same as 192.168.* ~tristan 8/16/07 - */ -/* This function has a unit test. */ -//int -//is_ipaddr(const char *inbuf, struct in_addr *sin_addr) -//{ -// // In keeping with the historical definition of this function, -// // we allow wildcards, even though the caller did not explicitly -// // ask for them. This usage needs to be reviewed. -// return is_ipaddr_implementation(inbuf,sin_addr,NULL,1); -//} -// -//int -//is_ipaddr_no_wildcard(const char *inbuf, struct in_addr *sin_addr) -//{ -// return is_ipaddr_implementation(inbuf,sin_addr,NULL,0); -//} -// -//int -//is_ipaddr_wildcard(const char *inbuf, struct in_addr *sin_addr, struct in_addr *mask_addr) -//{ -// return is_ipaddr_implementation(inbuf,sin_addr,mask_addr,1); -//} - - -// checks to see if 'network' is a valid ip/netmask. if given pointers to -// ip_addr structs, they will be filled in. -/* XXX: Known Problems: The netmask doesn't have to be a valid - netmask, as long as it looks something like an IP address. ~tristan 8/16/07 - */ -/* This function has a unit test. */ -//int -//is_valid_network( const char *network, struct in_addr *ip, struct in_addr *mask) -//{ -// // copy the string, only 32 is necessary since the lonest -// // legitimate one is 123.567.901.345/789.123.567.901 -// // 1 2 3 -// // 31 characters. -// // -// // we make a copy because we then find the slash and -// // overwrite it with a null to create two separate strings. -// // those are then validated and parsed into the structures -// // that were optionally passed in. -// char nmcopy[32]; -// char *tmp; -// int numbits; -// strncpy( nmcopy, network, 31 ); -// nmcopy[31] = '\0'; -// -// // find a slash and make sure both sides are valid -// tmp = strchr(nmcopy, '/'); -// if( !tmp ) { -// if( is_ipaddr_wildcard(nmcopy,ip,mask) ) { -// // this is just a plain IP or IP.* -// return TRUE; -// } -// } -// else { -// // separate by overwriting the slash with a null, and moving tmp -// // to point to the begining of the second string. -// *tmp++ = 0; -// -// // now validate -// if (is_ipaddr_no_wildcard(nmcopy, ip)) { -// // first part is a valid ip, now validate the netmask. two -// // different formats are valid, we check for both. -// if (is_ipaddr_no_wildcard(tmp, mask)) { -// // format is a.b.c.d/m.a.s.k -// // is_ipaddr fills in the value for both ip and mask, -// // so we are done! -// return TRUE; -// } else { -// // try format a.b.c.d/num -// char *end = NULL; -// numbits = strtol(tmp,&end,10); -// if (end && *end == '\0') { -// if (mask) { -// // fill in the structure -// mask->s_addr = 0; -// mask->s_addr = htonl(~(~(mask->s_addr) >> numbits)); -// } -// return TRUE; -// } else { -// dprintf (D_SECURITY, "ISVALIDNETWORK: malformed netmask: %s\n", network); -// } -// } -// } -// } -// -// return FALSE; -//} - /* XXX: known problems: This function allows anything after the :, it doesn't have to be a port number. ~tristan 8/20/07 @@ -582,63 +325,6 @@ string_to_port( const char* addr ) return port; } -/* XXX: known problems: string_to_ip() uses is_ipaddr(), and so has the same - * flaws. Mainly, input like 66.199 is assumed to be followed by ".*" even - * though that's a badly formed IP address. ~tristan 8/22/07 - */ -/* This function has a unit test. */ -//unsigned int -//string_to_ip( const char* addr ) -//{ -// char *sinful, *tmp; -// unsigned int ip = 0; -// struct in_addr sin_addr; -// -// if( ! (addr && is_valid_sinful(addr)) ) { -// return 0; -// } -// -// sinful = strdup( addr ); -// if( (tmp = strchr(sinful, ':')) ) { -// *tmp = '\0'; -// if( is_ipaddr(&sinful[1], &sin_addr) ) { -// ip = sin_addr.s_addr; -// } -// } else { -// EXCEPT( "is_valid_sinful(\"%s\") is true, but can't find ':'", addr ); -// } -// free( sinful ); -// return ip; -//} - -#if 0 -char* -string_to_ipstr( const char* addr ) -{ -// char *tmp; -// static char result[MAXHOSTNAMELEN]; -// char sinful[MAXHOSTNAMELEN]; -// -// if( ! (addr && is_valid_sinful(addr)) ) { -// return NULL; -// } -// -// strncpy( sinful, addr, MAXHOSTNAMELEN-1 ); -// tmp = strchr( sinful, ':' ); -// if( tmp ) { -// *tmp = '\0'; -// } else { -// return NULL; -// } -// if( is_ipaddr(&sinful[1], NULL) ) { -// strncpy( result, &sinful[1], MAXHOSTNAMELEN-1 ); -// return result; -// } -// return NULL; -} - -#endif - // This union allow us to avoid casts, which cause // gcc to warn about type punning pointers, which // may or may not cause it to generate invalid code @@ -718,6 +404,7 @@ _condor_local_bind( int is_outgoing, int fd ) return TRUE; } +static int bindWithin( const int fd, const int lowPort, const int highPort ) { int pid = (int)getpid(); int range = highPort - lowPort + 1; @@ -766,25 +453,6 @@ int bindWithin( const int fd, const int lowPort, const int highPort ) { return FALSE; } -// ip: network-byte order -// port: network-byte order -char * ipport_to_string(const unsigned int ip, const unsigned short port) -{ - static char buf[24]; - struct in_addr inaddr; - - buf[0] = '<'; - buf[1] = '\0'; - if (ip == INADDR_ANY) { - strcat(buf, my_ip_string()); - } else { - inaddr.s_addr = ip; - strcat(buf, inet_ntoa(inaddr)); - } - sprintf(&buf[strlen(buf)], ":%d>", ntohs(port)); - return buf; -} - /* This function has a unit test. */ int getPortFromAddr( const char* addr ) diff --git a/src/condor_utils/ipv6_addrinfo.cpp b/src/condor_utils/ipv6_addrinfo.cpp index fcb948e9191..cd45529bc60 100644 --- a/src/condor_utils/ipv6_addrinfo.cpp +++ b/src/condor_utils/ipv6_addrinfo.cpp @@ -36,7 +36,13 @@ addrinfo get_default_hint() // ret.ai_flags = AI_ADDRCONFIG; #endif ret.ai_flags |= AI_CANONNAME; - ret.ai_family = AF_UNSPEC; + if ( param_false( "ENABLE_IPV6" ) ) { + ret.ai_family = AF_INET; + } else if ( param_false( "ENABLE_IPV4" ) ) { + ret.ai_family = AF_INET6; + } else { + ret.ai_family = AF_UNSPEC; + } ret.ai_socktype = SOCK_STREAM; ret.ai_protocol = IPPROTO_TCP; return ret; @@ -81,11 +87,10 @@ struct shared_context addrinfo_iterator::addrinfo_iterator() : cxt_(NULL), current_(NULL) { - ipv6 = ! param_false( "ENABLE_IPV6" ); } addrinfo_iterator::addrinfo_iterator(const addrinfo_iterator& rhs) : - cxt_(rhs.cxt_), current_(NULL), ipv6(rhs.ipv6) + cxt_(rhs.cxt_), current_(NULL) { if (cxt_) cxt_->add_ref(); } @@ -163,7 +168,6 @@ addrinfo * deepCopyAndSort( addrinfo * res, bool preferIPv4 ) { addrinfo_iterator::addrinfo_iterator(addrinfo* res) : cxt_(new shared_context), current_(NULL) { - ipv6 = ! param_false( "ENABLE_IPV6" ); cxt_->add_ref(); cxt_->head = res; @@ -205,7 +209,6 @@ addrinfo_iterator& addrinfo_iterator::operator= (const addrinfo_iterator& rhs) if (cxt_) cxt_->release(); cxt_ = rhs.cxt_; cxt_->add_ref(); - ipv6 = rhs.ipv6; current_ = NULL; return *this; @@ -234,8 +237,7 @@ addrinfo* addrinfo_iterator::next() case AF_INET: return current_; case AF_INET6: - if( ipv6 ) { return current_; } - // This fall-through is deliberate. + return current_; default: // // ai_canonname is only ever non-NULL in the first struct addrinfo @@ -245,6 +247,10 @@ addrinfo* addrinfo_iterator::next() // more broken for host with IPv6 addresses.) We can't just // copy the pointer because then it will be double-free()d. // + // TODO: Since we no longer filter out IPv6 entries in the + // results of getaddrinfo() (we now do so via the hints + // parameter), this juggling of ai_canonname is probably no + // longer necessary. if( current_ == cxt_->head && cxt_->head->ai_canonname ) { addrinfo * hack = next(); if( hack ) { diff --git a/src/condor_utils/ipv6_hostname.cpp b/src/condor_utils/ipv6_hostname.cpp index e2ebf9044a4..29b0c308230 100644 --- a/src/condor_utils/ipv6_hostname.cpp +++ b/src/condor_utils/ipv6_hostname.cpp @@ -21,24 +21,6 @@ static bool nodns_enabled() return param_boolean("NO_DNS", false); } -#ifdef TEST_DNS_TODO -static void replace_higher_scoring_addr(const char * reason, condor_sockaddr & current, int & current_score, - const condor_sockaddr & potential, int potential_score) { - const char * result = "skipped for low score"; - if(current_score < potential_score) { - current = potential; - current_score = potential_score; - result = "new winner"; - } - - dprintf(D_HOSTNAME, "%s: %s (score %d) %s\n", - reason, - potential.to_ip_string().Value(), - potential_score, - result); -} -#endif - bool init_local_hostname_impl() { bool local_hostname_initialized = false; @@ -62,8 +44,6 @@ bool init_local_hostname_impl() MyString test_hostname = local_hostname; bool local_ipaddr_initialized = false; - bool local_ipv4addr_initialized = false; - bool local_ipv6addr_initialized = false; MyString network_interface; if (param(network_interface, "NETWORK_INTERFACE")) { @@ -72,11 +52,9 @@ bool init_local_hostname_impl() local_ipaddr_initialized = true; if(local_ipaddr.is_ipv4()) { local_ipv4addr = local_ipaddr; - local_ipv4addr_initialized = true; } if(local_ipaddr.is_ipv6()) { local_ipv6addr = local_ipaddr; - local_ipv6addr_initialized = true; } } } @@ -91,23 +69,19 @@ bool init_local_hostname_impl() dprintf(D_ALWAYS, "Unable to identify IP address from interfaces. None match NETWORK_INTERFACE=%s. Problems are likely.\n", network_interface.Value()); } if((!ipv4.empty()) && local_ipv4addr.from_ip_string(ipv4)) { - local_ipv4addr_initialized = true; ASSERT(local_ipv4addr.is_ipv4()); } if((!ipv6.empty()) && local_ipv6addr.from_ip_string(ipv6)) { - local_ipv6addr_initialized = true; ASSERT(local_ipv6addr.is_ipv6()); } } - bool local_fqdn_initialized = false; if (nodns_enabled()) { // condor_gethostname() returns a hostname with // DEFAULT_DOMAIN_NAME. Thus, it is always fqdn local_fqdn = local_hostname; - local_fqdn_initialized = true; if (!local_ipaddr_initialized) { - local_ipaddr = convert_hostname_to_ipaddr(local_hostname); + local_ipaddr = convert_fake_hostname_to_ipaddr(local_hostname); if (local_ipaddr != condor_sockaddr::null) { local_ipaddr_initialized = true; } @@ -121,9 +95,7 @@ bool init_local_hostname_impl() const int SLEEP_DUR = 3; bool gai_success = false; for(int try_count = 1; true; try_count++) { - addrinfo hint = get_default_hint(); - hint.ai_family = AF_UNSPEC; - int ret = ipv6_getaddrinfo(test_hostname.Value(), NULL, ai, hint); + int ret = ipv6_getaddrinfo(test_hostname.Value(), NULL, ai); if(ret == 0) { gai_success = true; break; } if(ret != EAI_AGAIN ) { dprintf(D_ALWAYS, "init_local_hostname_impl: ipv6_getaddrinfo() could not look up '%s': %s (%d). Error is not recoverable; giving up. Problems are likely.\n", test_hostname.Value(), gai_strerror(ret), ret ); @@ -140,74 +112,26 @@ bool init_local_hostname_impl() } if(gai_success) { - int local_hostname_desireability = 0; -#ifdef TEST_DNS_TODO - int local_ipaddr_desireability = 0; - int local_ipv4addr_desireability = 0; - int local_ipv6addr_desireability = 0; -#endif - while (addrinfo* info = ai.next()) { - // TODO: the only time ai_canonname should be set is the first - // record. Why are we testing its desirability? + addrinfo* info = ai.next(); + if (info->ai_canonname) { const char* name = info->ai_canonname; - if (!name) - continue; - condor_sockaddr addr(info->ai_addr); - - int desireability = addr.desirability(); - - const char * result = "skipped for low score"; - if(desireability > local_hostname_desireability) { - result = "new winner"; - dprintf(D_HOSTNAME, " I like it.\n"); - local_hostname_desireability = desireability; - - const char* dotpos = strchr(name, '.'); - if (dotpos) { // consider it as a FQDN - local_fqdn = name; - local_hostname = local_fqdn.substr(0, dotpos-name); - } else { - local_hostname = name; - local_fqdn = local_hostname; - MyString default_domain; - if (param(default_domain, "DEFAULT_DOMAIN_NAME")) { - if (default_domain[0] != '.') - local_fqdn += "."; - local_fqdn += default_domain; - } - } - } - dprintf(D_HOSTNAME, "hostname: %s (score %d) %s\n", name, desireability, result); - -#ifdef TEST_DNS_TODO - // Resist urge to set local_ip*addr_initialized=true, - // We want to repeatedly retest this looking for - // better results. - if (!local_ipaddr_initialized) { - replace_higher_scoring_addr("IP", - local_ipaddr, local_ipaddr_desireability, - addr, desireability); - } - if (addr.is_ipv4() && !local_ipv4addr_initialized) { - replace_higher_scoring_addr("IPv4", - local_ipv4addr, local_ipv4addr_desireability, - addr, desireability); + const char* dotpos = strchr(name, '.'); + if (dotpos) { // consider it as a FQDN + local_fqdn = name; + local_hostname = local_fqdn.substr(0, dotpos-name); + } else { + local_hostname = name; + local_fqdn = local_hostname; + MyString default_domain; + if (param(default_domain, "DEFAULT_DOMAIN_NAME")) { + if (default_domain[0] != '.') + local_fqdn += "."; + local_fqdn += default_domain; + } } + dprintf(D_HOSTNAME, "hostname: %s\n", name); - if (addr.is_ipv6() && !local_ipv6addr_initialized) { - replace_higher_scoring_addr("IPv6", - local_ipv6addr, local_ipv6addr_desireability, - addr, desireability); - } -#else - // Make Fedora quit complaining. - if( local_ipv4addr_initialized && local_ipv6addr_initialized && local_fqdn_initialized ) { - local_ipv4addr_initialized = false; - local_ipv6addr_initialized = false; - local_fqdn_initialized = false; - } -#endif } } @@ -266,10 +190,10 @@ MyString get_fqdn_from_hostname(const MyString& hostname) { return ret; } - while (addrinfo* info = ai.next()) { - if (info->ai_canonname) { - if (strchr(info->ai_canonname, '.')) - return info->ai_canonname; + addrinfo *info = ai.next(); + if (info != NULL && info->ai_canonname != NULL) { + if (strchr(info->ai_canonname, '.')) { + return info->ai_canonname; } } @@ -309,9 +233,9 @@ int get_fqdn_and_ip_from_hostname(const MyString& hostname, if (nodns_enabled()) { // if nodns is enabled, convert hostname to ip address directly - ret_addr = convert_hostname_to_ipaddr(hostname); + ret_addr = convert_fake_hostname_to_ipaddr(hostname); - // note that convert_hostname_to_ipaddr() could fail; if so, + // note that convert_fake_hostname_to_ipaddr() could fail; if so, // leave found_ip = false and fall through to the block below // where we try to use the resolver. if (ret_addr != condor_sockaddr::null) { @@ -331,12 +255,11 @@ int get_fqdn_and_ip_from_hostname(const MyString& hostname, return 0; } - while (addrinfo* info = ai.next()) { - if (info->ai_canonname) { - fqdn = info->ai_canonname; - addr = condor_sockaddr(info->ai_addr); - return 1; - } + addrinfo *info = ai.next(); + if (info != NULL && info->ai_canonname != NULL) { + fqdn = info->ai_canonname; + addr = condor_sockaddr(info->ai_addr); + return 1; } hostent* h = gethostbyname(hostname.Value()); @@ -377,11 +300,11 @@ int get_fqdn_and_ip_from_hostname(const MyString& hostname, MyString get_hostname(const condor_sockaddr& addr) { MyString ret; if (nodns_enabled()) - return convert_ipaddr_to_hostname(addr); + return convert_ipaddr_to_fake_hostname(addr); condor_sockaddr targ_addr; - // just like sin_to_string(), if given address is 0.0.0.0 or equivalent, + // if given address is 0.0.0.0 or equivalent, // it changes to local IP address. if (addr.is_addr_any()) targ_addr = get_local_ipaddr(addr.get_protocol()); @@ -530,7 +453,7 @@ std::vector resolve_hostname(const MyString& hostname) { std::vector ret; if (nodns_enabled()) { - condor_sockaddr addr = convert_hostname_to_ipaddr(hostname); + condor_sockaddr addr = convert_fake_hostname_to_ipaddr(hostname); if (addr == condor_sockaddr::null) return ret; ret.push_back(addr); @@ -578,7 +501,7 @@ std::vector resolve_hostname_raw(const MyString& hostname) { return ret; } -MyString convert_ipaddr_to_hostname(const condor_sockaddr& addr) +MyString convert_ipaddr_to_fake_hostname(const condor_sockaddr& addr) { MyString ret; MyString default_domain; @@ -607,7 +530,7 @@ MyString convert_ipaddr_to_hostname(const condor_sockaddr& addr) } // Upon failure, return condor_sockaddr::null -condor_sockaddr convert_hostname_to_ipaddr(const MyString& fullname) +condor_sockaddr convert_fake_hostname_to_ipaddr(const MyString& fullname) { MyString hostname; MyString default_domain; diff --git a/src/condor_utils/ipv6_interface.cpp b/src/condor_utils/ipv6_interface.cpp index 656cad76d50..8dcf20cc87e 100644 --- a/src/condor_utils/ipv6_interface.cpp +++ b/src/condor_utils/ipv6_interface.cpp @@ -2,6 +2,7 @@ #include "ipv6_interface.h" #include "condor_config.h" #include "condor_sockaddr.h" +#include "my_hostname.h" #if HAVE_GETIFADDRS #include @@ -43,13 +44,27 @@ uint32_t find_scope_id(const condor_sockaddr& addr) { uint32_t ipv6_get_scope_id() { if (!scope_id_inited) { - MyString network_interface; - if (param(network_interface, "NETWORK_INTERFACE")) { - condor_sockaddr addr; - if (addr.from_ip_string(network_interface)) { - scope_id = find_scope_id(addr); - } + std::string network_interface; + std::string ipv4_str; + std::string ipv6_str; + std::string ipbest_str; + condor_sockaddr addr; + if (param(network_interface, "NETWORK_INTERFACE") && + network_interface_to_ip("NETWORK_INTERFACE", + network_interface.c_str(), + ipv4_str, ipv6_str, ipbest_str) && + addr.from_ip_string(ipv6_str.c_str()) && addr.is_link_local()) + { + scope_id = find_scope_id(addr); + } + else if (network_interface_to_ip("Ipv6LinkLocal", "fe80:*", + ipv4_str, ipv6_str, ipbest_str) && + addr.from_ip_string(ipv6_str.c_str()) && + addr.is_link_local()) + { + scope_id = find_scope_id(addr); } + scope_id_inited = true; } return scope_id; diff --git a/src/condor_utils/ipv6_interface.h b/src/condor_utils/ipv6_interface.h index f6209b09dac..90afe1ff411 100644 --- a/src/condor_utils/ipv6_interface.h +++ b/src/condor_utils/ipv6_interface.h @@ -20,8 +20,15 @@ #ifndef _IPV6_INTERFACE_H #define _IPV6_INTERFACE_H -// returns scope id for the link-local address -// if NETWORK_INTERFACE was not set, it returns 0 (no scope) +// Returns scope id for the link-local address of the local machine. +// If there are multiple link-local addresses and NETWORK_INTERFACE +// doesn't select one as the preferred address, then a random one +// is selected. +// The scope id should only be used if the destination of a network +// connection is an IPv6 link-local address. +// If a machine has multiple link-local addresses and the admin wants +// to use one with Condor, they should set NETWORK_INTERFACE to indicate +// which one to use. // // scope_id is only valid for IPv6 address uint32_t ipv6_get_scope_id(); diff --git a/src/condor_utils/libcondorapi_stubs.cpp b/src/condor_utils/libcondorapi_stubs.cpp index 9d353c7bc34..bdaa144afcb 100644 --- a/src/condor_utils/libcondorapi_stubs.cpp +++ b/src/condor_utils/libcondorapi_stubs.cpp @@ -355,18 +355,6 @@ CondorQuery::~CondorQuery() {} const char* my_ip_string() {not_impl(); return 0;} -void ConvertDefaultIPToSocketIP(char const *,char const *,char **,Stream& ) { - not_impl(); -} - -void ConvertDefaultIPToSocketIP(char const *,char **,Stream& ) { - not_impl(); -} - -void ConvertDefaultIPToSocketIP(char const *,std::string &,Stream&) { - not_impl(); -} - #include "Regex.h" Regex::Regex() {not_impl();} diff --git a/src/condor_utils/my_hostname.cpp b/src/condor_utils/my_hostname.cpp index df0492924fb..b5a9127416e 100644 --- a/src/condor_utils/my_hostname.cpp +++ b/src/condor_utils/my_hostname.cpp @@ -29,42 +29,13 @@ #include "condor_sinful.h" #include "CondorError.h" -static bool enable_convert_default_IP_to_socket_IP = false; -static bool shared_port_address_rewriting = false; -static bool network_interface_matches_all; - - const char* my_ip_string() { static MyString __my_ip_string; - // TODO: Picking IPv4 arbitrarily. WARNING: This function - // gets called while the configuration file is being loaded, - // before we know if IPV4 and/or IPv6 is enabled. It needs to - // return a stable answer, because having it change midway - // through parsing the file is a recipe for failure. + // TODO: Picking IPv4 arbitrarily. __my_ip_string = get_local_ipaddr(CP_IPV4).to_ip_string(); return __my_ip_string.Value(); } -//void -//init_full_hostname() -//{ -// char *tmp; -// -// tmp = get_full_hostname( hostname ); -// -// if( full_hostname ) { -// free( full_hostname ); -// } -// if( tmp ) { -// // Found it, use it. -// full_hostname = strdup( tmp ); -// delete [] tmp; -// } else { -// // Couldn't find it, just use what we've already got. -// full_hostname = strdup( hostname ); -// } -//} - bool network_interface_to_ip(char const *interface_param_name,char const *interface_pattern,std::string & ipv4, std::string & ipv6, std::string & ipbest) { @@ -214,11 +185,6 @@ network_interface_to_ip(char const *interface_param_name,char const *interface_p } } - if( interfaceCount <= 1 ) { - enable_convert_default_IP_to_socket_IP = false; - dprintf(D_FULLDEBUG,"Disabling ConvertDefaultIPToSocketIP() because NETWORK_INTERFACE does not match multiple IPs.\n"); - } - dprintf(D_HOSTNAME,"%s=%s matches %s, choosing IP %s\n", interface_param_name, interface_pattern, @@ -255,8 +221,6 @@ init_network_interfaces( CondorError * errorStack ) std::string network_interface; param( network_interface, "NETWORK_INTERFACE" ); - network_interface_matches_all = (network_interface == "*"); - if( enable_ipv4_false && enable_ipv6_false ) { errorStack->pushf( "init_network_interfaces", 1, "ENABLE_IPV4 and ENABLE_IPV6 are both false." ); return false; @@ -319,235 +283,3 @@ init_network_interfaces( CondorError * errorStack ) return true; } - -static bool is_sender_ip_attr(char const *attr_name) -{ - if(strcasecmp(attr_name,ATTR_MY_ADDRESS) == 0) return true; - if(strcasecmp(attr_name,ATTR_TRANSFER_SOCKET) == 0) return true; - size_t attr_name_len = strlen(attr_name); - if(attr_name_len >= 6 && strcasecmp(attr_name+attr_name_len-6,"IpAddr") == 0) - { - return true; - } - return false; -} - - -void ConfigConvertDefaultIPToSocketIP() -{ - // do not need to call init_ipaddr() since init_ipaddr() has no effect - // on this function. -// if( ! ipaddr_initialized ) { -// init_ipaddr(0); -// } - - - enable_convert_default_IP_to_socket_IP = true; - - /* - When using TCP_FORWARDING_HOST, if we rewrite addresses, we will - insert the IP address of the local IP address in place of - the forwarding IP address. - */ - char *str = param("TCP_FORWARDING_HOST"); - if( str && *str ) { - enable_convert_default_IP_to_socket_IP = false; - dprintf(D_FULLDEBUG,"Disabling ConvertDefaultIPToSocketIP() because TCP_FORWARDING_HOST is defined.\n"); - } - free( str ); - - if( !param_boolean("ENABLE_ADDRESS_REWRITING",true) ) { - enable_convert_default_IP_to_socket_IP = false; - dprintf(D_FULLDEBUG,"Disabling ConvertDefaultIPToSocketIP() because ENABLE_ADDRESS_REWRITING is false.\n"); - } - shared_port_address_rewriting = param_boolean("SHARED_PORT_ADDRESS_REWRITING", false); -} - -// Only needed for these next two functions; -// #include should be deleted when ConvertDefaultIPToSocketIP is. -#include "condor_daemon_core.h" - -void ConvertDefaultIPToSocketIP(char const * attr_name, std::string & expr_string, Stream & s ) -{ - static bool loggedNullDCMessage = false; - static bool loggedConfigMessage = false; - - // We can't practically do a conversion if daemonCore isn't present; this - // happens in standard universe. We can't move this test into - // ConfigConvertDefaultIPToSocketIP because it gets called before - // daemonCore is created. - if( daemonCore == NULL ) { - if( ! loggedNullDCMessage ) { - dprintf( D_NETWORK | D_VERBOSE, "Address rewriting: disabled: no daemon core.\n" ); - loggedNullDCMessage = true; - } - return; - } - - if( ! enable_convert_default_IP_to_socket_IP ) { - if( ! loggedConfigMessage ) { - dprintf( D_NETWORK | D_VERBOSE, "Address rewriting: disabled: by configuration.\n" ); - loggedConfigMessage = true; - } - return; - } - - if( ! is_sender_ip_attr( attr_name ) ) { - // Reduce log spam. Since all of our subsequent messages include the - // attribute name, we don't have to print a message noting that we - // tried to rewrite it. - // dprintf( D_NETWORK | D_VERBOSE, "Address rewriting: '%s' is not an attribute which might contain the sender's IP address.\n", attr_name ); - return; - } - - // Skip if Stream doesn't have address associated with it - condor_sockaddr connectionSA; - if( !s.my_ip_str() || !connectionSA.from_ip_string( s.my_ip_str() ) ) { - dprintf( D_NETWORK | D_VERBOSE, "Address rewriting: failed for attribute '%s' (%s): failed to generate socket address from stream's IP string (%s).\n", attr_name, expr_string.c_str(), s.my_ip_str() ); - return; - } - - // Skip if it's not a string literal. - if( * ( expr_string.rbegin() ) != '"' ) { - dprintf( D_NETWORK | D_VERBOSE, "Address rewriting: failed for attribute '%s' (%s): failed to parse. Missing closing double quotation mark.\n", attr_name, expr_string.c_str() ); - return; - } - - const char * delimiter = " = \""; - size_t delimpos = expr_string.find( delimiter ); - // Skip if doesn't look like a string - if( delimpos == std::string::npos ) { - dprintf( D_NETWORK | D_VERBOSE, "Address rewriting: failed for attribute '%s' (%s): failed to parse. Missing assignment.\n", attr_name, expr_string.c_str() ); - return; - } - - size_t string_start_pos = delimpos + strlen( delimiter ); - // string_end_pos is one beyond last character of String literal. - size_t string_end_pos = expr_string.length() - 1; - size_t string_len = string_end_pos - string_start_pos; - - // Skip if it doesn't look like a Sinful - if( expr_string[string_start_pos] != '<' ) { - dprintf( D_NETWORK | D_VERBOSE, "Address rewriting: failed for attribute '%s' (%s): failed to parse. Missing opening <.\n", attr_name, expr_string.c_str() ); - return; - } - if( expr_string[string_end_pos - 1] != '>' ) { - dprintf( D_NETWORK | D_VERBOSE, "Address rewriting: failed for attribute '%s' (%s): failed to parse. Missing closing >.\n", attr_name, expr_string.c_str() ); - return; - } - - std::string adSinfulString = expr_string.substr( string_start_pos, string_len); - const char *cmd_sinful = daemonCore->InfoCommandSinfulString(); - if ( cmd_sinful == NULL ) { - dprintf( D_NETWORK | D_VERBOSE, "Address rewriting: disabled: no command port sinful string.\n" ); - return; - } - std::string commandPortSinfulString = cmd_sinful; - - Sinful adSinful( adSinfulString.c_str() ); - condor_sockaddr adSA; - adSA.from_sinful( adSinful.getSinful() ); - - bool rewrite_port = true; - if (commandPortSinfulString == adSinfulString) - { - dprintf( D_NETWORK | D_VERBOSE, "Address rewriting: refused for attribute %s (%s): clients now choose addresses.\n", attr_name, expr_string.c_str() ); - return; - } - else if (shared_port_address_rewriting) - { - // - // Wait a minute -- isn't this only supposed to happen in the collector? - // - const std::vector &commandSinfuls = daemonCore->InfoCommandSinfulStringsMyself(); - dprintf(D_NETWORK|D_VERBOSE, "Address rewriting: considering %ld command socket sinfuls.\n", commandSinfuls.size()); - - bool acceptableMatch = false; - std::vector::const_iterator it; - for (it = commandSinfuls.begin(); it!=commandSinfuls.end(); it++) - { - commandPortSinfulString = it->getSinful(); - const Sinful &commandPortSinful = *it; - // We assume that any sinful on the same shared port server - // can also be rewritten. - if ((adSinful.getSharedPortID() != NULL) && (strcmp(commandPortSinful.getHost(), adSinful.getHost()) == 0) && (commandPortSinful.getPortNum() == adSinful.getPortNum())) - { - acceptableMatch = true; - break; - } - dprintf( D_NETWORK | D_VERBOSE, "Address rewriting: refused for attribute %s (%s): the address isn't my default address. (Command socket considered: %s, found in ad: %s)\n", attr_name, expr_string.c_str(), commandPortSinfulString.c_str(), adSinfulString.c_str()); - } - - if (!acceptableMatch) - { - return; - } - } - else - { - dprintf( D_NETWORK | D_VERBOSE, "Address rewriting: refused for attribute %s (%s): the address isn't my default address. (Default: %s, found in ad: %s)\n", attr_name, expr_string.c_str(), commandPortSinfulString.c_str(), adSinfulString.c_str()); - return; - } - - // - // Although it's never useful to rewrite from a non-loopback to a loop- - // back address, if there's more than one loopback address on a machine, - // (generally but not always because the machine supports more than one - // protocol), it's OK to rewrite from one to the other. - // - // Doing this is any other situation breaks, among other things, - // ssh-to-job. (In a design hack, the starter sends its external - // address to the startd over the job-update socket, as part of every - // job update ClassAd. This causes rewriting to happen, but as the - // the startd explicity binds the job-update socket to the loopback - // address -- presumambly to ensure that it always works -- we need - // to make sure we don't rewrite ATTR_STARTER_IP_ADDR when sending - // job updates. *sigh*) - // - if( (! adSA.is_loopback()) && connectionSA.is_loopback() ) { - dprintf( D_NETWORK | D_VERBOSE, "Address rewriting: refused for attribute '%s' (%s): outbound interface is loopback but default interface is not.\n", attr_name, expr_string.c_str() ); - return; - } - - if( adSinful.getSharedPortID() != NULL ) { - // We're using shared port, so "our" port is actually the - // shared port daemon's. We shouldn't be messing with that. - // We'll rewrite the host on the bold assumption that shared - // port daemon and I both use the same IP addresses. - rewrite_port = false; - } - - MyString my_sock_ip = connectionSA.to_ip_string( true ); - adSinful.setHost( my_sock_ip.Value() ); - if( rewrite_port ) { - // connectionSA's port is whatever we happen to be using at the moment; - // that will be meaningless if we established the connection. What we - // want is the port someone could contact us on. Go rummage for one. - int port = daemonCore->find_interface_command_port_do_not_use( connectionSA ); - - // If port is 0, there is no matching listen socket. There is nothing - // useful we can rewrite it do, so just give up and hope the default - // is useful to someone. - if( port == 0 ) { - dprintf( D_NETWORK | D_VERBOSE, "Address rewriting: failed for attribute '%s' (%s): unable to find command port for outbound interface '%s'.\n", attr_name, expr_string.c_str(), s.my_ip_str() ); - return; - } - - adSinful.setPort( port ); - } - - if( adSinful.getSinful() == adSinfulString ) { - dprintf( D_NETWORK | D_VERBOSE, "Address rewriting: refused for attribute '%s' (%s): socket is using same address as the default one; rewrite would do nothing.\n", attr_name, expr_string.c_str() ); - return; - } - - std::string new_expr = expr_string.substr( 0, string_start_pos ); - new_expr.append( adSinful.getSinful() ); - new_expr.append( expr_string.substr( string_end_pos ) ); - - expr_string = new_expr; - - dprintf( D_NETWORK, "Address rewriting: Replaced default IP %s with " - "connection IP %s in outgoing ClassAd attribute %s.\n", - adSinfulString.c_str(), adSinful.getSinful(), attr_name ); -} diff --git a/src/condor_utils/my_hostname.h b/src/condor_utils/my_hostname.h index e07e2e2a45f..18386bceb2d 100644 --- a/src/condor_utils/my_hostname.h +++ b/src/condor_utils/my_hostname.h @@ -30,24 +30,6 @@ extern const char* my_ip_string( void ); class CondorError; bool init_network_interfaces( CondorError * errorStack ); -// If the specified attribute name is recognized as an attribute used -// to publish a daemon IP address, this function replaces any -// reference to the default host IP with the actual connection IP in -// the attribute's expression string. - -// You might consider this a dirty hack (and it is), but of the -// methods that were considered, this was the one with the lowest -// maintainance, least overhead, and least likelihood to have -// unintended side-effects. - -void ConvertDefaultIPToSocketIP(char const *attr_name,std::string &expr_string,Stream& s); - - -void ConfigConvertDefaultIPToSocketIP(); - -// This interface to ConvertDefaultIPToSocketIP() takes a std::string -// and modifies its contents. - /* Find local addresses that match a given NETWORK_INTERFACE * * Prefers public addresses. Strongly prefers "up" addresses. diff --git a/src/condor_utils/param_info.in b/src/condor_utils/param_info.in index 166a0ece7cf..1a75b4b447c 100644 --- a/src/condor_utils/param_info.in +++ b/src/condor_utils/param_info.in @@ -3812,19 +3812,6 @@ default=1000000 description=Max Procd Log (size rotation only, no scale suffix) tags=procd -[ENABLE_ADDRESS_REWRITING] -default=true -version=7.4.3 -type=bool -tags=daemons - -# This was an option "born deprecated"; it allows a single-host HTCondor instance (particularly, the HTCondor-CE) to provide a better dual-stack service by rewriting all ads in the collector. -[SHARED_PORT_ADDRESS_REWRITING] -default=false -version=8.3.4 -type=bool -customization=devel - [SHADOW_WORKLIFE] default=3600 version=7.5.3 diff --git a/src/condor_utils/submit_utils.cpp b/src/condor_utils/submit_utils.cpp index 9c231352e1b..6e44505de1a 100644 --- a/src/condor_utils/submit_utils.cpp +++ b/src/condor_utils/submit_utils.cpp @@ -75,6 +75,7 @@ #include "condor_url.h" #include "condor_version.h" #include "NegotiationUtils.h" +#include "param_info.h" // for BinaryLookup #include "submit_utils.h" //#include "submit_internal.h" #define PLUS_ATTRIBS_IN_CLUSTER_AD 1 @@ -712,7 +713,7 @@ const char * SubmitHash::full_path(const char *name, bool use_iwd /*=true*/) } else if (clusterAd) { // if there is a cluster ad, we NEVER want to use the current working directory // instead we want to treat the saved working directory of submit as the cwd. - realcwd = submit_param_mystring("FACTORY.Iwd", "FACTORY.Iwd"); + realcwd = submit_param_mystring("FACTORY.Iwd", NULL); p_iwd = realcwd.Value(); } else { condor_getcwd(realcwd); @@ -2633,9 +2634,13 @@ int SubmitHash::ComputeIWD(bool check_access /*=true*/) #endif { iwd = shortname; - } + } else { - condor_getcwd( cwd ); + if (clusterAd) { + cwd = submit_param_mystring("FACTORY.Iwd",NULL); + } else { + condor_getcwd( cwd ); + } iwd.formatstr( "%s%c%s", cwd.Value(), DIR_DELIM_CHAR, shortname ); } } @@ -8252,6 +8257,56 @@ const char* SubmitHash::to_string(std::string & out, int flags) return out.c_str(); } +enum FixupKeyId { + idKeyNone=0, + idKeyExecutable, + idKeyInitialDir, +}; + +// struct for a table mapping attribute names to a flag indicating that the attribute +// must only be in cluster ad or only in proc ad, or can be either. +// +typedef struct digest_fixup_key { + const char * key; + FixupKeyId id; // + // a LessThan operator suitable for inserting into a sorted map or set + bool operator<(const struct digest_fixup_key& rhs) const { + return strcasecmp(this->key, rhs.key) < 0; + } +} DIGEST_FIXUP_KEY; + +// table if submit keywords that require special processing when building a submit digest +// NOTE: this table MUST be sorted by case-insensitive value of the first field. +static const DIGEST_FIXUP_KEY aDigestFixupAttrs[] = { + // these should end up sorted case-insenstively + { ATTR_JOB_CMD, idKeyExecutable }, // "Cmd" + { SUBMIT_KEY_Executable, idKeyExecutable }, // "executable" + { "initial_dir", idKeyInitialDir }, // "initial_dir" <- special case legacy hack (sigh) note '_' sorts before 'd' OR 'D' + { SUBMIT_KEY_InitialDir, idKeyInitialDir }, // "initialdir" + { ATTR_JOB_IWD, idKeyInitialDir }, // "Iwd" + { "job_iwd", idKeyInitialDir }, // "job_iwd" <- special case legacy hack (sigh) +}; + +// while building a submit digest, fixup right hand side for certain key=rhs pairs +// for now this is mostly used to promote some paths to fully qualified paths. +void SubmitHash::fixup_rhs_for_digest(const char * key, std::string & rhs) +{ + const DIGEST_FIXUP_KEY* found = NULL; + found = BinaryLookup(aDigestFixupAttrs, COUNTOF(aDigestFixupAttrs), key, strcasecmp); + if ( ! found) + return; + + // the Executable and InitialDir should be expanded to a fully qualified path here. + if (found->id == idKeyExecutable || found->id == idKeyInitialDir) { + if (rhs.empty()) return; + const char * path = rhs.c_str(); + if (strstr(path, "$$(")) return; // don't fixup if there is a pending $$() expansion. + if (IsUrl(path)) return; // don't fixup URL paths + // Convert to a full path it not already a full path + rhs = full_path(path, false); + } +} + const char* SubmitHash::make_digest(std::string & out, int cluster_id, StringList & vars, int /*options*/) { int flags = HASHITER_NO_DEFAULTS; @@ -8288,6 +8343,7 @@ const char* SubmitHash::make_digest(std::string & out, int cluster_id, StringLis if (val) { rhs = val; selective_expand_macro(rhs, skip_knobs, SubmitMacroSet, mctx); + fixup_rhs_for_digest(key, rhs); out += rhs; } out += "\n"; diff --git a/src/condor_utils/submit_utils.h b/src/condor_utils/submit_utils.h index f707c180498..da3b292782c 100644 --- a/src/condor_utils/submit_utils.h +++ b/src/condor_utils/submit_utils.h @@ -682,6 +682,7 @@ class SubmitHash { // private helper functions + void fixup_rhs_for_digest(const char * key, std::string & rhs); void push_error(FILE * fh, const char* format, ... ) CHECK_PRINTF_FORMAT(3,4); void push_warning(FILE * fh, const char* format, ... ) CHECK_PRINTF_FORMAT(3,4); private: diff --git a/src/condor_utils/test_classad_put.cpp b/src/condor_utils/test_classad_put.cpp index 00512465021..7d3a51619b5 100644 --- a/src/condor_utils/test_classad_put.cpp +++ b/src/condor_utils/test_classad_put.cpp @@ -256,7 +256,6 @@ bool putOldClassAd ( DummyStream *sock, classad::ClassAd& ad, bool excludeTypes //get buf's c_str in an editable format exprString = (char*)malloc(buf.size() + 1); strncpy(exprString, buf.c_str(),buf.size() + 1 ); - //ConvertDefaultIPToSocketIP(tmpAttrName.c_str(),&exprString,*sock); /* if( ! sock->prepare_crypto_for_secret_is_noop() && compat_classad::ClassAdAttributeIsPrivate(tmpAttrName.c_str())) {