/*
* Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
*
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
/** @file
*
* Name resolution
*
*/
/***************************************************************************
*
* Name resolution interfaces
*
***************************************************************************
*/
/**
* Name resolved
*
* @v intf Object interface
* @v sa Completed socket address (if successful)
*/
resolv_done_TYPE ( void * ) *op =
if ( op ) {
} else {
/* Default is to ignore resolutions */
}
}
/***************************************************************************
*
* Numeric name resolver
*
***************************************************************************
*/
/** A numeric name resolver */
struct numeric_resolv {
/** Reference counter */
/** Name resolution interface */
/** Process */
/** Completed socket address */
/** Overall status code */
int rc;
};
}
/* Allocate and initialise structure */
if ( ! numeric )
return -ENOMEM;
/* Attempt to resolve name */
} else {
}
/* Attach to parent interface, mortalise self, and return */
return 0;
}
.name = "NUMERIC",
.resolv = numeric_resolv,
};
/***************************************************************************
*
* Name resolution multiplexer
*
***************************************************************************
*/
/** A name resolution multiplexer */
struct resolv_mux {
/** Reference counter */
/** Parent name resolution interface */
/** Child name resolution interface */
/** Current child resolver */
/** Socket address to complete */
/** Name to be resolved
*
* Must be at end of structure
*/
char name[0];
};
/**
* Try current child name resolver
*
* @v mux Name resolution multiplexer
* @ret rc Return status code
*/
int rc;
return rc;
}
return 0;
}
/**
* Child resolved name
*
* @v mux Name resolution multiplexer
* @v sa Completed socket address
*/
/* Pass resolution to parent */
}
/**
* Child finished resolution
*
* @v mux Name resolution multiplexer
* @v rc Return status code
*/
/* Restart child interface */
/* If this resolution succeeded, stop now */
if ( rc == 0 ) {
goto finished;
}
/* Attempt next child resolver, if possible */
goto finished;
}
goto finished;
/* Next resolver is now running */
return;
}
/** Name resolution multiplexer child interface operations */
};
/** Name resolution multiplexer child interface descriptor */
/**
* Start name resolution
*
* @v resolv Name resolution interface
* @v name Name to resolve
* @v sa Socket address to complete
* @ret rc Return status code
*/
int rc;
/* Allocate and initialise structure */
if ( ! mux )
return -ENOMEM;
if ( sa )
/* Start first resolver in chain. There will always be at
* least one resolver (the numeric resolver), so no need to
* check for the zero-resolvers-available case.
*/
goto err;
/* Attach parent interface, mortalise self, and return */
return 0;
err:
return rc;
}
/***************************************************************************
*
* Named socket opening
*
***************************************************************************
*/
/** A named socket */
struct named_socket {
/** Reference counter */
/** Data transfer interface */
/** Name resolution interface */
/** Communication semantics (e.g. SOCK_STREAM) */
int semantics;
/** Stored local socket address, if applicable */
/** Stored local socket address exists */
int have_local;
};
/**
* Terminate named socket opener
*
* @v named Named socket
* @v rc Reason for termination
*/
/* Shut down interfaces */
}
/**
* Check flow control window
*
* @v named Named socket
* @ret len Length of window
*/
/* Not ready for data until we have redirected away */
return 0;
}
/** Named socket opener data transfer interface operations */
};
/** Named socket opener data transfer interface descriptor */
/**
* Name resolved
*
* @v named Named socket
* @v sa Completed socket address
*/
int rc;
/* Nullify data transfer interface */
/* Redirect data-xfer interface */
( named->have_local ?
/* Redirection failed - do not unplug data-xfer interface */
} else {
/* Redirection succeeded - unplug data-xfer interface */
}
/* Terminate named socket opener */
}
/** Named socket opener resolver interface operations */
};
/** Named socket opener resolver interface descriptor */
/**
* Open named socket
*
* @v semantics Communication semantics (e.g. SOCK_STREAM)
* @v peer Peer socket address to complete
* @v name Name to resolve
* @v local Local socket address, or NULL
* @ret rc Return status code
*/
int rc;
/* Allocate and initialise structure */
if ( ! named )
return -ENOMEM;
if ( local ) {
}
/* Start name resolution */
goto err;
/* Attach parent interface, mortalise self, and return */
return 0;
err:
return rc;
}