Page History

Turn Off History

See also:

On-going

Working on Phase 2.

*remember to fix command.cpp, sin_to_hostname() is converted to to_sinful(), not get_hostname() file_transfer_db.cpp, condor_auth_x509.cpp, and schedd.cpp, same --> command.cpp is not. --> done. need double-check. confusing to_sinful() and get_hostname() produces an error that is hard to debug. be sure to check by comparing with git history.

Qmgmt, StdUnivSock and soap all have IPv4 data structure. have a look!

Socket connections that do not use class Sock

StdUnivSock calls do_connect() (condor_util_lib/do_connect.c) to establish connection with the scheduler. Entire code path uses IPv4 specific constant and functions. Should I just convert them or introduce another socket class?

Current Stream and Sock are somewhat bloated. It is not functionally coherent. Diverse functions are included in single class. The concept "Stream" is a feature of socket. It should not be parent of Sock. This is where multiple interface inheritance kicks in. Consider "IStream" for the functionalities. So, class Sock could remain just socket wrapper.

Sinful string construction

There are some places that construct sinful strings without using wrapper functions.

  // shadow_common.cpp
  char sinfulstring[SINFUL_STRING_BUF_SIZE];

  snprintf(sinfulstring, SINFUL_STRING_BUF_SIZE, "<%s:%d>", sock->peer_ip_str(), ports.port1);

The caveat is that sinful grammar is changing due to IPv6 address and these are simply incompatible. If the address is IPv6, it should be form of <[%s]:%s>. We need another abstraction layer.

Where to put NODNS?

Previously, NODNS is implemented over existing DNS query functions such as condor_gethostbyname, condor_gethostname, and condor_gethostbyaddr.

In IPv6, this problem is little bit complicated because when you call getaddrinfo(), it will return a pointer to addrinfo structure. It should be released by the user code. Previously, gethostbyname() returned a pointer to static buffer, thus, the user is not liable to release.

addrinfo structure is a linked list and its allocation method is unknown. Thus, I cannot allocate my own addrinfo structure that is filled with NODNS information.

One possible way is to provide condor_freeaddrinfo() that overrides freeaddrinfo().

But what I really think is that is it really required? I prefer better abstractions.

Test required

Don't forget below lists.

Note for constants

Converting utility functions

struct hostent

I Initially only looked at struct sockaddr_in. I wrote class ipaddr for replacement. However, it is only half of the world. I should devise IPv6 compliant structure for struct hostent and make it obsolete. I think it would make more sense if we have class ipaddr and class MyString instead of sockaddr* and char*. Write here some design possibilities!

// from MSDN
typedef struct hostent {
  char FAR      *h_name;
  char FAR  FAR **h_aliases;
  short         h_addrtype;
  short         h_length;
  char FAR  FAR **h_addr_list;
}

typedef struct addrinfo {
  int             ai_flags;
  int             ai_family;
  int             ai_socktype;
  int             ai_protocol;
  size_t          ai_addrlen;
  char            *ai_canonname;
  struct sockaddr *ai_addr;
  struct addrinfo *ai_next;
}

get_full_hostname *RESOLVED

my_ip_addr, my_hostname, my_full_hostname() and get_full_hostname() are now obsolete. Now, implementing ipv6_hostname.{h/cpp}.

It uses gethostbyname() which has been obsoleted. It should call getaddrinfo() instead. The function has about 150-200 lines of code. At the end of function, it tail-calls get_full_hostname_from_hostent(). struct hostent is also deprecated structure.

It requires overhaul from interface to implementation.

Importance: ?

** I reimplemented get_full_hostname* and my_hostname*. Newer implementation exists at ipv6_hostname.*

IpVerify

[zach] implemented by mostly Todd, and little bit by Zach and Dan.

IpVerify verifies the remote process's ip from the configuration file. IpVerify heavily uses in_addr structure internally. I would simply change it to in6_addr and map IPv4 address into IPv6. (so called V4MAPPED). It would make Condor slightly slower and use more memory. However, having two different code path for IPv4 and IPv6 does not seem nice. 4byte->16byte would not be much overhead and will make everything cleaner and easier. Also, I guess future IP address system will surely be super-set of current IPv6 as IPv6 is super-set of IPv4.

V4MAPPED address works fine. One caveat is that the log will have IPv6-formatted IP address, e.g. ::ffff:127.0.0.1. If somebody do mind, it is possible to remove "::ffff".

Ulrich Mystery

Ulrich's Userlevel IPv6 Programming Introductionn - http://people.redhat.com/drepper/userapi-ipv6.html

He denotes gethostbyaddr() as an obsolete. However, gethostbyaddr() accepts a socket type as a parameter. (AF_INET, AF_INET6) That means it should work well with IPv6. Why it is obsolete??

We should continue to use gethostbyaddr() because there is no other way to get DNS aliases using newer socket functions.

Try getaddrinfo() on www.yahoo.com. You only get 'any-fp.wa1.b.yahoo.com'. But if you call gethostbyname() on www.yahoo.com, you will get additional hostnames (aliases), which are www.yahoo.com and fp.wg1.b.yahoo.com.

Converting Sock

Sock is not only used by TCP/UDP connection but also used by Unix domain socket (AF_UNIX). Basically, Sock can only create TCP or UDP socket internally but SharedEndPoint and SharedPortClient creates Unix domain socket and calls Sock::assign() to pass the descriptor.

I guess this is broken abstraction since Sock has IP related functions such as peer_addr() or peer_port() which are not available to Unix domain socket.

It seems assign() is only used by these Shared* thing. So maybe we could end up with refactoring it.

List of Condor IP addr functions

// from condor_c++_util/get_full_hostname.cpp

extern char* get_full_hostname( const char*,
                                struct in_addr *sin_addrp = NULL );

extern char* get_full_hostname_from_hostent( struct hostent* host_ptr,
                                             const char* host );

// from condor_util_lib/condor_netdb.c

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);

// from condor_util_lib/internet.c
// internet.c is a total failure...... tons of old-style codings

int is_ipaddr(const char *inbuf, struct in_addr *sin_addr);

int is_ipaddr_no_wildcard(const char *inbuf, struct in_addr *sin_addr);

int is_ipaddr_wildcard(const char *inbuf, struct in_addr *sin_addr, struct in_addr *mask_addr);

int is_valid_network( const char *network, struct in_addr *ip, struct in_addr *mask);

int is_valid_sinful( const char *sinful );

// there are many more from internet.c. omitted at this time.

Condor NetDB

Condor defines its own netdb-related functions (proxy functions) for its own DNS system called NO_DNS.

What is it?

TCP_FORWARDING_HOST ?

solved

KeyCache

KeyCache, uses sockaddr_in for storing ip addr. before modify, be sure to look at the overall picture. only used in condor_secman and daemon core.

KeyCacheEntry stores sockaddr_in. KeyCache converts sockaddr_in into sinful string and use the string as a key.

Sock::my_addr() can fail? *RESOLVED

One of asymmetry in Sock class is that peer_addr() does not fail and always return a value but my_addr() can fail. ( peer_addr tells you the address of peer, my_addr() tells you the address of local socket)

The possible case for a failure of my_addr() is that when Sock class did not assign a socket descriptor.

In this case, peer_addr() can also fail.

Returning a pointer of a static buffer inside a function

It is quite common practice in Condor source code that returning a pointer of a static buffer in a function. It was perfectly fine in a world that pthread is rare and multi-core is unknown. It is obviously non-re-entrant and non-thread-safe. Well, I could do as it was. But, I am slightly uncomfortable of writing such a function. So, I decided to use MyString instead of returning a pointer of a static buffer.

changes

should i change?

Sock::get_port() -> Sock::my_addr().get_port() *for consistency. <- Well, I guess it should be in the future but not now.