jude@orville.nas.nasa.gov (Jude A. George) (12/17/90)
Posting-number: Volume 15, Issue 97 Submitted-by: Jude A. George <jude@orville.nas.nasa.gov> Archive-name: atos/part01 [Hey Phil, when will this show up in NOS? ;-) ++bsa] ATOS -- Application-Level Type-of-Service Routing v0.95 October 5, 1990 ATOS is a small bit of code that provides network applications with a way to choose the best network path to a destination when multiple paths are available. For example, when two hosts share both an Ethernet and an UltraNet, they want to route all of their ftp traffic through their UltraNet interfaces and all of their telnets and rlogins through the Ethernet. The higher-bandwidth network is better suited for ftp's large-packet data transfers than for telnet/rlogin "tinygrams". The proper interface must be chosen by the application. A name server ordinarily returns all of the network addresses for a host, but in no particular order. Thus the calling code cannot normally make an intelligent choice of address. Until true type-of-service routing is handled by IP and the routing hardware, we have to solve this problem at a higher layer. The software does require a resolver that has the capability of returning multiple (all available) network addresses in the hostent data structure. If you use YP or a host table, as opposed to a name server, and can map only one IP address to a hostname, ATOS will not help you. You should have the following files: atos/ README makefile man3/ atos.3n sortaddrbytos.3n tosroutes.3n netinet/ atos.c atos.h test.c tosroutes The makefile requires this directory structure to build the test program. To use ATOS, compile the source into any C code that makes a call to the resolver. After a gethostbyname() or similar call, call sortaddrbytos() with a pointer to the hostent structure and a TOS code. This function will sort the h_addr_list IP addresses in order of descending preference, with the "best" address at the top. The sorting is done under the assumption that the calling code will choose its addresses from the top of the list, moving downwards. An /etc/tosroutes file must also be present, which tells the sorting routine how to compare the available networks against the TOS codes. The codes and the format of this file are explained in the man page. The example file included with this distribution will not work for your network. To get the maximum benefit from ATOS, incorporate it into heavily used network software such as ftp and telnet, on hosts that are homed on multiple networks. Use a tos code of "T" for ftp, and "D" for telnet. This will maximize throughput on the one, and minimize delay on the other. Caveat: ftp uses the same port for its control connection and its data connection. All frequently-used network/tos combinations should be listed in the /etc/tosroutes file. ATOS has been tested on a VAX 11/780 running BSD 4.3 UNIX, a Cray Y-MP running UNICOS 5.1.10, a Sun 3/260 and Sun 4/65 running SunOS 4.0.3, and a Silicon Graphics Iris 4D/320 running IRIX 3.3. The software is provided "as is"; use at your own risk. It is by no means production code, from any organization. Neither I, nor any organization I am affiliated with, assume any resonsibility for its use or misuse. It is very simple in design, but because of its nature (it destructively modifies data structures in the calling code) any usage should be tested extensively. 'Nuff said. ATOS may be freely modified, distributed, and used; all I ask is that it be distributed with its documentation. I would like to hear from anyone who tries it out. If you've come up with improvements for the sorting routine or the format of the tosroutes file, I would be happy to incorporate them, so others may benefit. I didn't spend much time on this. Many thanks go to John Lekashman and David Ianucci of NASA Ames for their input. Jude George NAS Program, M/S 258-6 NASA Ames Research Center Moffett Field, CA 94086 jude@nas.nasa.gov ----------------------------------- #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # atos # This archive created: Mon Oct 22 11:32:04 1990 export PATH; PATH=/bin:/usr/bin:$PATH if test ! -d 'atos' then mkdir 'atos' fi cd 'atos' if test -f 'README' then echo shar: "will not over-write existing file 'README'" else sed 's/^X//' << \SHAR_EOF > 'README' XATOS -- Application-Level Type-of-Service Routing X Xv0.95 October 5, 1990 X XATOS is a small bit of code that provides network applications with a way Xto choose the best network path to a destination when multiple paths are Xavailable. For example, when two hosts share both an Ethernet and an XUltraNet, they want to route all of their ftp traffic through their UltraNet Xinterfaces and all of their telnets and rlogins through the Ethernet. XThe higher-bandwidth network is better suited for ftp's large-packet Xdata transfers than for telnet/rlogin "tinygrams". The proper interface Xmust be chosen by the application. A name server ordinarily returns all of Xthe network addresses for a host, but in no particular order. Thus the Xcalling code cannot normally make an intelligent choice of address. Until Xtrue type-of-service routing is handled by IP and the routing hardware, Xwe have to solve this problem at a higher layer. X XThe software does require a resolver that has the capability of returning Xmultiple (all available) network addresses in the hostent data structure. XIf you use YP or a host table, as opposed to a name server, and can map only Xone IP address to a hostname, ATOS will not help you. X XYou should have the following files: X Xatos/ X README X makefile X man3/ X atos.3n X sortaddrbytos.3n X tosroutes.3n X netinet/ X atos.c X atos.h X test.c X tosroutes X XThe makefile requires this directory structure to build the test program. X XTo use ATOS, compile the source into any C code that makes a call to the Xresolver. After a gethostbyname() or similar call, call sortaddrbytos() Xwith a pointer to the hostent structure and a TOS code. This function will Xsort the h_addr_list IP addresses in order of descending preference, with Xthe "best" address at the top. The sorting is done under the assumption Xthat the calling code will choose its addresses from the top of the list, Xmoving downwards. An /etc/tosroutes file must also be present, which tells Xthe sorting routine how to compare the available networks against the TOS Xcodes. The codes and the format of this file are explained in the man page. XThe example file included with this distribution will not work for your Xnetwork. X XTo get the maximum benefit from ATOS, incorporate it into heavily used Xnetwork software such as ftp and telnet, on hosts that are homed on multiple Xnetworks. Use a tos code of "T" for ftp, and "D" for telnet. This will Xmaximize throughput on the one, and minimize delay on the other. Caveat: Xftp uses the same port for its control connection and its data connection. XAll frequently-used network/tos combinations should be listed in the X/etc/tosroutes file. X XATOS has been tested on a VAX 11/780 running BSD 4.3 UNIX, a Cray Y-MP Xrunning UNICOS 5.1.10, a Sun 3/260 and Sun 4/65 running SunOS 4.0.3, and Xa Silicon Graphics Iris 4D/320 running IRIX 3.3. The software is provided X"as is"; use at your own risk. It is by no means production code, from Xany organization. Neither I, nor any organization I am affiliated with, Xassume any resonsibility for its use or misuse. It is very simple in design, Xbut because of its nature (it destructively modifies data structures in Xthe calling code) any usage should be tested extensively. 'Nuff said. X XATOS may be freely modified, distributed, and used; all I ask is that it Xbe distributed with its documentation. I would like to hear from anyone who Xtries it out. If you've come up with improvements for the sorting routine Xor the format of the tosroutes file, I would be happy to incorporate them, Xso others may benefit. I didn't spend much time on this. X XMany thanks go to John Lekashman and David Ianucci of NASA Ames for their Xinput. X XJude George X XNAS Program, M/S 258-6 XNASA Ames Research Center XMoffett Field, CA 94086 X Xjude@nas.nasa.gov SHAR_EOF fi if test ! -d 'netinet' then mkdir 'netinet' fi cd 'netinet' if test -f 'atos.h' then echo shar: "will not over-write existing file 'atos.h'" else sed 's/^X//' << \SHAR_EOF > 'atos.h' X/*\ X * ATOS -- Application-Level Type-of-Service Routing X * X * FILE: atos.h X * X * v0.95, 5 October 1990 X * X * sortaddrbytos() takes a host entry (struct hostent *) and a tos X * (type of service) code, and rearranges the h_addr_list in the X * host entry in order of preference for that particular tos. X * This is an attempt to solve the problem of routing by tos above X * the ip layer, when multiple physical network paths to the X * destination host are available. X * X * The function relies on the existence of a file /etc/tosroutes X * with each line consisting of three fields: tos, addr, pref. X * The tos field is a single character indicating the network X * requirements of the calling code: "D" for low delay, "T" for X * high throughput, or "R" for high reliability. Multiple X * requirements (low delay AND high throughput) may not be entered. X * The addr field is either a network #, subnet #, or full IP #, X * and specifies a possible destination. Typically, only subnet X * #'s are useful. The pref field is a number from 0 to 9 indicating X * that tos' preference for that network address, 0 being the most X * preferred addr for that tos. X * X * There should be an entry for every local network or subnet, X * as a net/subnet that the function does not recognize will always X * be sorted down to the bottom of the list. X * sortaddrbytos() returns 0, or -1 if there was an error. X * X * Copyright (c) 1990 Jude A. George (jude@nas.nasa.gov) X * This code may be freely distributed. It is believed to be X * useful and bug-free, but comes with no warranty whatsoever, X * from any party. It is not production code. X\*/ X X#define ADDRSIZE 16 X#define STRSIZE 16 X#define TOSFILE "/etc/tosroutes" X#define ALT_TOSFILE "./tosroutes" Xint sortaddrbytos(); SHAR_EOF fi if test -f 'atos.c' then echo shar: "will not over-write existing file 'atos.c'" else sed 's/^X//' << \SHAR_EOF > 'atos.c' X/*\ X * ATOS -- Application-Level Type-of-Service Routing X * X * FILE: atos.c X * X * v0.95, 5 October 1990 X * X * sortaddrbytos() takes a host entry (struct hostent *) and a tos X * (type of service) code, and rearranges the h_addr_list in the X * host entry in order of preference for that particular tos. X * This is an attempt to solve the problem of routing by tos above X * the ip layer, when multiple physical network paths to the X * destination host are available. X * X * The function relies on the existence of a file /etc/tosroutes X * with each line consisting of three fields: tos, addr, pref. X * The tos field is a single character indicating the network X * requirements of the calling code: "D" for low delay, "T" for X * high throughput, or "R" for high reliability. Multiple X * requirements (low delay AND high throughput) may not be entered. X * The addr field is either a network #, subnet #, or full IP #, X * and specifies a possible destination. Typically, only subnet X * #'s are useful. The pref field is a number from 0 to 9 indicating X * that tos' preference for that network address, 0 being the most X * preferred addr for that tos. X * X * There should be an entry for every local network or subnet, X * as a net/subnet that the function does not recognize will always X * be sorted down to the bottom of the list. X * sortaddrbytos() returns 0, or -1 if there was an error. X * X * Copyright (c) 1990 Jude A. George (jude@nas.nasa.gov) X * This code may be freely distributed. It is believed to be X * useful and bug-free, but comes with no warranty whatsoever, X * from any party. It is not production code. X\*/ X X#include <stdio.h> X#include <netdb.h> X X#include <netinet/atos.h> X Xstruct tos_ent { X struct tos_ent *next; X char addr[ADDRSIZE]; X char tos[STRSIZE]; X int pref; X}; X X/*\ X * Insert an entry into the tos list, sorted by pref. Low pref value, X * i.e. more preferred entries, will be placed closer to the head of X * the list. X\*/ Xtos_insert(entry,list_ptr) Xstruct tos_ent *entry; Xstruct tos_ent **list_ptr; X{ X struct tos_ent *cur_ent, *prev_ent; X X if (*list_ptr == NULL) { X *list_ptr = entry; X return; X } X prev_ent = NULL; X cur_ent = *list_ptr; X while(cur_ent != NULL) { X if (entry->pref <= cur_ent->pref) { X entry->next = cur_ent; X if (prev_ent == NULL) X *list_ptr = entry; X else X prev_ent->next = entry; X break; X } X prev_ent = cur_ent; X cur_ent = cur_ent->next; X } X} X X/*\ X * Sort host_entry->h_addr_list based on tos and the tos file. Note that X * a network or subnet entry in the tos file can match a full IP address X * from the h_addr_list. (e.g. 129.99 matches 129.99.23.20). X\*/ Xint sortaddrbytos(host_entry, tos) Xstruct hostent *host_entry; Xchar *tos; X{ X struct tos_ent *tos_list, *cur_ent; X unsigned char **cur_addr, **cur_addr_top; X unsigned char *temp; X char addrbuf[ADDRSIZE]; X int numents = 0; X int rval = 1; X int i; X FILE *fp; X X /* X * If host entry is NULL, return with an error. X */ X if (host_entry == NULL) X return -1; X X /* X * Open the tos file for reading; if file doesn't exist, search for X * an alternate. If still not found, return with an error but don't X * change the addr_list. X */ X fp = fopen(TOSFILE,"r"); X if (fp == NULL) { X fp = fopen(ALT_TOSFILE,"r"); X if (fp == NULL) X return -1; X } X X /* X * Read all tos file entries that have our tos code, and make a list, X * sorting in order of pref. X */ X tos_list = NULL; X while(rval != EOF) { X cur_ent = (struct tos_ent *)malloc(sizeof(struct tos_ent)); X cur_ent->pref = -1; X cur_ent->next = NULL; X bzero(cur_ent->addr, ADDRSIZE); X bzero(cur_ent->tos, STRSIZE); X rval = fscanf(fp, "%s %s %d", cur_ent->tos, cur_ent->addr, X &cur_ent->pref); X if (!strcmp(cur_ent->tos, tos)) X tos_insert(cur_ent, &tos_list); X } X fclose(fp); X X /* X * Sort the h_addr_list in order of "preference", using the sorted X * tos_list as a guide. Go down the tos_list; for each entry, look X * through the h_addr_list from cur_addr_top downwards; if a match X * is found in the h_addr_list, swap that match with the cur_addr_top X * of the h_addr_list and lower the cur_addr_top by one. Keep looking X * down the list in case there are multiple matches. Cur_addr_top is X * initially at the head of the h_addr_list. Note: the string X * comparison is performed only up to the length of the tos file's addr X * entry, to allow a network or subnet id to match a host's ip address. X */ X cur_addr_top = (unsigned char **)host_entry->h_addr_list; X for (cur_ent = tos_list; cur_ent != NULL; cur_ent = cur_ent->next) X for (cur_addr = cur_addr_top; *cur_addr != 0; cur_addr++) { X bzero(addrbuf, ADDRSIZE); X sprintf(addrbuf, "%u.%u.%u.%u", (*cur_addr)[0], (*cur_addr)[1], X (*cur_addr)[2], (*cur_addr)[3]); X if (!strncmp(addrbuf, cur_ent->addr, strlen(cur_ent->addr))) { X temp = *cur_addr_top; X *cur_addr_top++ = *cur_addr; X *cur_addr = temp; X } X } X return 0; X} SHAR_EOF fi cd .. if test -f 'test.c' then echo shar: "will not over-write existing file 'test.c'" else sed 's/^X//' << \SHAR_EOF > 'test.c' X/*\ X * FILE: test.c X * X * Test function for sortaddrbytos(). X\*/ X X#include <stdio.h> X#include <netdb.h> X X#include <netinet/atos.h> X Xmain(argc,argv) Xint argc; Xchar **argv; X{ X struct hostent *test_host; X unsigned char **addr_list, **i, byte1, byte2, byte3, byte4; X int int1, int2, int3, int4; X X if (argc != 3) { X printf("Usage: %s hostname tos\n", argv[0]); X exit(0); X } X X test_host = gethostbyname(argv[1]); X X if (test_host == NULL) { X printf("Bad host name.\n"); X exit(-1); X } X X addr_list = (unsigned char **)test_host->h_addr_list; X X printf("\nOriginal address list for %s:\n\n", test_host->h_name); X for(i = addr_list; *i != 0; i++) X printf("address: %u.%u.%u.%u\n",(*i)[0],(*i)[1],(*i)[2],(*i)[3]); X X sortaddrbytos(test_host, argv[2]); X X printf("\nSorted address list for %s:\n\n", test_host->h_name); X for(i = addr_list; *i != 0; i++) X printf("address: %u.%u.%u.%u\n",(*i)[0],(*i)[1],(*i)[2],(*i)[3]); X} SHAR_EOF fi if test -f 'makefile' then echo shar: "will not over-write existing file 'makefile'" else sed 's/^X//' << \SHAR_EOF > 'makefile' X# X# Makefile for sortaddrbytos() test. If you do not have a system X# similar to BSD 4.3, you may have to modify the CFLAGS to include X# additional libraries, or change the #include paths. This makefile X# should work, unchanged, on the following systems: BSD 4.3, X# IRIX 3.3, SunOS 4.0.3. For UNICOS, add -lbsd -lnet. X# X# The install option will install the ATOS source files and man X# page in the appropriate directories, if you have write-access. X# I will not presume to guess which protection bits you use. X# X XSRCDIR= /usr/include/netinet XINCLDIR= /usr/include/netinet XMANDIR= /usr/man/man3 X XMAN= man3/atos.3n man3/tosroutes.3n man3/sortaddrbytos.3n X XCFLAGS= -O -I. X Xtest: netinet/atos.h netinet/atos.c test.c X cc ${CFLAGS} netinet/atos.c test.c -o test X Xinstall: netinet/atos.h netinet/atos.c ${MAN} X cp netinet/atos.c ${SRCDIR} X cp netinet/atos.h ${INCLDIR} X cp ${MAN} ${MANDIR} X Xclean: X rm -f atos.o test.o X Xspotless: X rm -f atos.o test.o test SHAR_EOF fi if test -f 'tosroutes' then echo shar: "will not over-write existing file 'tosroutes'" else sed 's/^X//' << \SHAR_EOF > 'tosroutes' XT 129.99.23 5 XT 129.99.32 5 XT 129.99.64 5 XT 129.99.48 5 XT 129.99.196 2 XD 129.99.23 3 XD 129.99.196 4 XD 129.99.32 4 XD 129.99.48 4 XD 129.99.64 4 XD 128.102 7 XT 128.102 7 SHAR_EOF fi if test ! -d 'man3' then mkdir 'man3' fi cd 'man3' if test -f 'sortaddrbytos.3n' then echo shar: "will not over-write existing file 'sortaddrbytos.3n'" else sed 's/^X//' << \SHAR_EOF > 'sortaddrbytos.3n' X.\" @(#)sortaddrbytos.3n 0.95 90/10/05; X.TH SORTADDRBYTOS 3N "5 October 1990" X.SH NAME Xsortaddrbytos \- sort host addresses by type of service and preferred Xnetwork X.SH SYNOPSIS X.nf X.ft B X#include <stdio.h> X#include <netdb.h> X#include <tosroute.h> X.LP X.ft B Xint sortaddrbytos(host_entry, tos) Xstruct hostent *host_entry; Xchar *tos; X.ft R X.fi X.IX "tosroutes file" "" "\fLtosroutes\fP \(em network preference codes" X.SH DESCRIPTION X.BR sortaddrbytos() Xtakes a host entry and an internet-standard tos (type of service) code Xand rearranges the h_addr_list in the host entry in order of preference Xfor that particular tos. This is an attempt to solve the problem of routing Xby tos above the ip layer, when multiple phisical network paths to the Xdestination host are available. A name server ordinarily returns all of Xthe network addresses for a host, but in no particular order. Thus Xthe calling code cannot normally make an intelligent choice of address. X.BR sortaddrbytos() Xshould be called immediately after X.BR gethostent(), X.BR gethostbyname(), Xor X.BR gethostbyaddr() Xin the application program. X.LP XThe function relies on the existence of a Xfile /etc/tosroutes with each line consisting of three fields: tos, addr, Xand pref. XThe tos field is a single character indicating the Xnetwork requirements of the calling code: "D" for low delay, X"T" for high throughput, or "R" for high reliability. Multiple Xrequirements (low delay AND high throughput) may not be entered. XThe addr field is either a network id, subnet id, or full IP address, Xand specifies a possible destination. Typically, only subnet ids are Xuseful. The pref field is a number from 0 to 9 indicating that tos' Xpreference for that network address, 0 being the most preferred addr Xfor that tos. Fields may be separated by tabs or spaces. X.LP XThere should be an entry for every local subnet, as a net/subnet that the Xfunction does not recognize will always be sorted to the bottom of the Xlist. Of course, hosts connected to different subnets will have slightly Xdifferent entries in their tosroutes files. X.SH EXAMPLE X.LP XHere is portion of an example /etc/tosroutes file for a host that can reach Xfour networks; 191.255.1 is a low-throughput Ethernet, 191.255.2 is a Xmedium-throughput FDDI ring, 191.255.3 is a high-throughput UltraNet, and X191.255.10 is a low-throughput, high-delay satellite link. In addition, X191.255.5 is another Ethernet that is an extra hop away, and hence may Xexperience slightly higher delay than the first Ethernet. X.LP X T 191.255.1 5 X T 191.255.2 2 X T 191.255.3 0 X T 191.255.10 9 X T 191.255.5 5 X D 191.255.1 2 X D 191.255.2 2 X D 191.255.3 2 X D 191.255.10 9 X D 191.255.5 3 X.LP XA program that wants the best path for high-throughput traffic (e.g. ftp) Xwould call sortaddrbytos() with "T" as the tos code. If the destination Xhost has interfaces 191.255.1.50, 191.255.2, and 191.255.3, the sorting Xalgorithm will return them in the order 191.255.3, 191.255.2, 191.255.1. X.SH FILES X/etc/tosroutes X.LP XIf tosroutes is not found in /etc, the current working directory of the Xcalling code will be searched. X.SH SEE ALSO Xgethostent(3N), services(5) X.SH BUGS XA name server should be used instead of a static file. Ideally, this Xfunction should be integrated into X.BR gethostent() Xand the resolver library. X.LP XThe function is not very forgiving of errors in the tosroutes file. X XThe function uses fscanf() and sprintf(). X X.SH AUTHOR XJude Anand George (jude@nas.nasa.gov) SHAR_EOF fi if test -f 'tosroutes.3n' then echo shar: "will not over-write existing file 'tosroutes.3n'" else sed 's/^X//' << \SHAR_EOF > 'tosroutes.3n' X.so man3/sortaddrbytos.3n X.\" @(#)tosroutes.3n 0.95 90/10/05; SHAR_EOF fi if test -f 'atos.3n' then echo shar: "will not over-write existing file 'atos.3n'" else sed 's/^X//' << \SHAR_EOF > 'atos.3n' X.so man3/sortaddrbytos.3n X.\" @(#)atos.3n 0.95 90/10/05; SHAR_EOF fi cd .. cd .. exit 0 # End of shell archive