IPv6 Design Review
IPv4 -> IPv6 Patterns
In our AC code, as it stands, much of the time an IP address is represented as a
four-byte value (which I will henceforth refer to as the 4-byte
format). This is typically represented as either an
unsigned long, or array of four chars.
However,
we now need a
standardized address format, which would replace all instances of the
4 byte format. According to the IPv6/IPv4 agnostic code specifications,
that new structure is struct sockaddr_storage *. This would
require replacing all functions that return, or use, the 4-byte IPv4
address format, with sockaddr_storage *.
With the above being the case, the following utility functions are required to implement the AC functionality currently in use.
-
We need a function that converts standardized address -> hostname
code, which will take the address in either form and return a name (See convertAddrToHostname(...) )
-
We need a function that converts standardized address -> text ip
address code, which will take the address in either form and return
dots or colons and numbers. (See convertAddrToIpString(...) )
- We need a function that gets
the standarized address from a socket, either from the source or
destination (peer) of that socket. (See getSelfAddrOfSocket(...) and getPeerAddrOfSocket(...) )
-
We need a function that gets the standarized address(es) for any
given hostname/ip address. (See convertHostnameToAddrs(...))
- We need a function that gets the standardized address(es) for a local host. (See getLocalHostAddresses(...))
- We need a function that determines whether a standardized address is a local host address (See isAddrLocal(...) ).
- We need a function that compares (binary comparison) standardizes addresses with each other (See compareAddresses(...) )
- We need a function that converts the standardized address into its 4 (IPv4) or 16 (IPv6) byte representation, and vice versa. (See getByteFormatFromSockAddr() and getSockAddrFromByteFormat() )
I've
implemented the above functions, plus more, in the TptpNewSocket.c of
the
updated socket code, which is partially based on the Client/Server
IPv4/IPv6
code that I've previously posted. The code isn't complete (e.g. for
instance, there
is no logging, and it hasn't been heavily tested), but it serves as an
excellent base for delivery into
the agent controller. I'd expect as part of stage 2, Intel would handle
moving this code into the AC code as they port
TransportSupport/socketTL.
Central Guidelines
I
highly recommend reading through this section and making sure
everything is clear, before moving past this section. The following
sections rely greatly on this section.
-
One problem is that the functions that we are NOT porting in
stage 2 (e.g. stage 4 functions: request peer monitoring and
access list/check host) use functions that we ARE porting in stage 2.
This will cause the functions that we are NOT porting in stage 2 to
fail to compile. This is a problem, because we still need those
unchanged stage 4 functions to compile.
-
My
solution:
Rewrite the IPv4 functions as per the notes below... BUT, for any
IPv4-only functions that these stage 4 functions use, create a copy of
the old IPv4
method AS IS, but give it a new name: for example, getSocketIPString
is called by the peer monitoring method getPeerConnectionInfo. Create a
new method called getSocketIPStringIPv4M(), with the same contents as
the original, and replace any references in getPeerConnectionInfo with
the new IPv4 name. At the end of IPv4 function name should be IPv4M, to allow us to track them.
- Reserve porting the request peer monitoring functionality until stage 4.
-
Disable host checking functionality until stage 4:
Essentially, comment out "if
(!tptp_checkHost(cctlData->network_list, address)) { ..... } "
in serveRequests of CCTLServer.c, and comment out "rc =
parseHostList(pTransportData->configurationData,
&cctlData->network_list);" in createTransportListener of
ClientCTL.c.
- Use the new 'getTheSocket' method which I have provided in the example file.
- Replace all getTheSocket calls (not many) with the new format, and
then rewrite the calling functions to handle multiple potential sockets
that they need to listen on.
-
Fix connectToTCPServer so that it takes the standardized address, as
above (I've written a replacement for this method, either
'connectToHostWithAddr' or 'connectToHostWithHostname', depending on
the context, usually the former)
-
Fix all functions that directly or indirectly pass the 4-byte IP
address into connectToTCPServer with the struct sockaddr_storage *
code equivalent.
- Having changed the method signatures of the above functions, fix any calling methods of these functions, ad infinitium.
-
For all functions that are listed as "not used" below, ignore them for
now, and mark in their comments that they are IPv4 only. I'd recommend
a standard tag so we can track them, e.g /* IPV4-ONLY */
- Lower Priority: May want to comment out, the RAInetAddress java code.
- See function level recommendations below, for remaining functions.
Intel / IBM Dependencies
With
the
way we've divided the IPv6 code in the original planning document,
I've observed that IBM's files have a lot of dependencies on
Intel's files, while Intel's
files only depend on themselves (for the most part). This requires
Intel to complete their stage 2 changes first, before IBM can proceed
with its stage 2 changes.
Stage 2:
-
First, Intel should complete the changes to the projects that are
listed as theirs in the original planning document. These functions
mostly have either no dependencies, or depend only on other Intel
functions.
- Note, there will be lots of build errors in the IBM
side of the code once the Intel side is completed for stage 2. This is
expected.
- Once Intel's stage 2 code is complete, a patch should be sent to IBM that includes the changes.
-
IBM will use this patch and make its stage 2 changes to its side of the
code, and make any touchups that are required in the AC.
- Once
complete, IBM will produce a patch that should be a working,
compileable AC, but with host access and request peer monitoring
functionality disabled.
- From here, we can pass to stage 3.
Stage 3+:
- After Stage 2, we'll manage dependencies differently.
New AC Code Methods where IPv4-only code is used
I've worked through Microsoft scan tool's output code, and noted the method
that the IPv4-only code is contained in. I then noted which functions reference
this function, and for what purposes. In most cases I've included a recommendation as well. In many cases, these functions can merely be replaced with the updated socket code equivalent.
AgentController.c:
unsigned int parsePeerAttachAddress(char* str):
- Takes a dots and numbers IP addresse and returns it in 4 byte format.
Called by:
- parseAndProcessParameters(), which is called by main.
- Stored in
cm->peerInfo.usePeerAttachAddress = TRUE;
cm->peerInfo.peerAttachAddress = parsePeerAttachAddress(arg);
- See also, PeerAttachInfo_t, below.
Recommendation: Leave this for stage 4. As long as the consumer doesn't use the two peer monitoring command line switches, this should be fine.
ConnectionImpl.cpp:
ConnectionImpl::getLocalIPAddress() (not used)
ConnectionImpl::getIPAddress() (used by itself)
- Returns IP address in 4-byte format (unsigned long).
- Used only as the first parameter to connectToTCPServer
-
Recommendation: When connectToTCPServer is fixed, this function should
be fixed to return the appropriate IPv6 struct. Note, I think for
backwards compatibility, a second copy of this function should be
created called getIPAddressIPv4() (that only returns IPv4
addreses in 4-byte format), for any consuming products that
don't wish to make the switch to IPv6 support.
TCPDataServer.cpp:
TCPDataServer::getLocalIPAddress() (used by itself, it would seem)
- Returns IP address in 4-byte format (unsigned long).
- Used only as the first parameter to connectToTCPServer
- Recommendation: When connectToTCPServer is fixed, this function should return the appropriate IPv6 struct.
TPTP_INetAddress.cpp:
TPTP_INetAddress::getAddress (unused, however part of native client api... may be used by consuming product)
- Is merely a host name resolve.
- Input: Hostname (char *)
- Output: char * (dots and numbers IP address, string)
- Recommendation: Is self-contained, we need only to replace this with IPv6-based host name resolution.
TPTPCBE.cpp:
createSourceComponentID (used, called by itself, merely prints the hostname)
- The offending code in this method only gets the local hostname (char *) and sprintfs it into a string.
- Recommendation: Self-contained, easily replaced.
SocketListener.c:
doListening
- Rewrite the function using the new getTheSocket(...) call. bindAndListen call no longer needed.
- Code must now listen on multiple server sockets.
- Recommendation: Rewrite using the new getTheSocket(...) method, and the code must now listen on multiple server sockets.
TransportOSCalls_win.c:
printSocketRequest (not used - may be for debug purposes)
convertIPAddressStringToArray
- input is an IP address in string form, output is 4 unsigned characters
o in CCTLServer.c serveRequests() - Grabs's the peer's IP in string
form, calls this method, then passes it into tptp_checkHost.
o in Connect2AC.c (TPTPClientCompTL) =>
translateAndForwardPeerRequestMonitor - Gets the local ip address of
the socket, converts it to 4-byte, stores it in
command->info.controller_request_monitor_port. Also, is used to
convert the PeerHost (string) to peerAddr (4 byte), to be stored in
command->info.controller_request_monitor_port.peerNode.
o in Connect2AC.c (TPTPClientCompTL) =>
translateAndForwardRequestMonitor - Gets the local ip address of
the socket, converts it to 4-byte, stores it in
command->info.controller_request_monitor_port., Also, is used to
convert the
PeerHost (string) to peerAddr (4 byte), to be stored in
command->info.controller_request_monitor_port.peerNode.
Recommend leaving this one alone for now, until the fourth stage. Disable
the tptp_CheckHost call in CCTLServer.c...serveRequests. Any socket
functions used by the request peer monitoring code should be IPv4M'ed,
as per above.
convertIPAddressUlongToString
- Converts the four byte IP format to a 'dots and numbers' string
o Used only by getPeerConnectionInfo in ClientCTL.c
o
Outputted as 'dots and numbers' to host portion:
<transportType>TPTP_CCTL</transportType><host>%s</host><port>%d</port>
o This call is only made when cctlData->usePeerAttachPort is
called. It is called on cctlData->peerAttachAddress.
Recommendation: Because this is peer monitoring specific, recommend leaving it to stage 4. IPv4M it.
extractAddressFromSockAddr (not used)
TransportOSCalls_linux.c (as above):
printSocketRequest (not used - may be for debug purposes)
convertIPAddressStringToArray
convertIPAddressUlongToString
extractAddressFromSockAddr (not used)
- Same as above.
TransportSupport:
tptp_getLocalIPAddress (not used)
tptp_getLocalIPAddresses
- Stores the local IP addresses in 4 byte form (null terminated char* list format, inside a tptp_IPAddresses_t )
o Used by isLocalHost() and tptp_checkHost(), below.
- Recommendation: Because it's only used by the checkHost functionality, leave as is in stage 2. IPv4M it.
isLocalHost
- Input is host name, output is either true or false.
- Called only by tptp_checkHost
-
Recommendation: Leave as in stage 2 (IPv4M it.). In stage 4, rewrite:
Self contained, rewrite to use IPv6 compliant code.
tptp_checkHost
- Input is network_list_t, and an address in four byte format.
o Used by serverRequests() of CCTLServer.c
- Recommendation: Leave as in stage 2.
Stage 4 Work (skip this section for Stage 2):
The structs related to the code are:
typedef struct {
network_list_node_t *head;
network_list_node_t *tail;
} network_list_t;
Stored in:
{
(...)
BOOL securityEnabled;
tptp_uint32 securedPort;
tptp_string *keystore;
tptp_string *keystorePassword;
network_list_t *network_list;
tptp_string *users;
} cctl_state_data_t;
Unsupported, nothing will generate these entries: TPTP_HW_UNKNOWN, TPTP_HW_KNOWN, TPTP_HW_MAX_VALUE,
TransportSupport.c:
BOOL tptp_checkHost(network_list_t *list, unsigned char *address);
- Called only in THREAD_USER_FUNC_RET_TYPE serveRequests(LPVOID args)
o Gets the string host name of the peer connected to it
o Converts that to 4-byte format
o calls tptp_checkHost on that 4 byte format.
o Note: the tptp_checkHost called can be easily commented out.
- address is address in 4-byte format.
- begins at list->head
- pulls a network_t out of current->entry
- entry->wildcard = TPTP_HW_ALL, TPTP_HW_LOCAL, TPTP_HW_UNKNOWN, TPTP_HW_KNOWN, TPTP_HW_NET, TPTP_HW_NAMED
case TPTP_HW_ALL:
- if allow return true, otherwise return false. Doesn't need to be rewritten.
case TPTP_HW_LOCAL:
- needs to be rewriten
-
calls tptp_getLocalIPAddresses() and compares each of the returned IP
addresses with the 'address' parameter that was passed in. If match,
return either true or false based on allow or deny.
case TPTP_HW_NET:
- needs to be rewritten
-
binary & the address with the mask to see if it matches the net. If
so, return either true or false based on allow or deny.
- resolve the address into string format, and store the alternative names as well
- compare the named ip listed in the file with the one we now have
- compare aliases as well.
The above constants are referenced in the following places:
- TPTP_HW_ALL (parseHostList in TPTPUtil.c)
- TPTP_HW_LOCAL (parseHostList in TPTPUtil.c)
- TPTP_HW_NET (tptp_addNetwork, parseHostList in TPTPUtil.cpp)
- TPTP_HW_NAMED (tptp_addNetwork, parseHostList in TPTPUtil.cpp)
TPTPUtil.cpp:
void tptp_addNetwork(network_list_t *list, int allow, tptp_host_wildcard_t wildcard, char *name, char *mask)
- called by parseHostList(...)
network_t *network;
network->allow=allow; // This handles the allow field.
network->wildcard=wildcard; // This handles TPTP_HW_ALL and TPTP_HW_LOCAL
if wildcard is TPTP_HW_NAMED:
- This needs to be rewritten for IPv6.
- If a number is specified in here, then maskTemp is set to 255.255.255.255, and the type is changed to TPTP_HW_NET.
- ELSE, if a named host is specified here, then store that named host in network->hostname
if wildcard is TPTP_HW_NET:
- This needs to be rewritten for IPv6
- network->net is 4 byte format IP address.
- network->mask is 4 byte format IP address.
- This code converts a text string into IPv4 IP format.
- It converts net and mask to IPv4 4 byte format.
int parseHostList(const char *initString, network_list_t **nList):
- Called by 'createTransportListener' of ClientCTL.c.
No IPv6 changes required.
(network_list_t is malloc here. It's entirely possible for it to be NULL.)
Under
<Hosts configuration="default">....</Hosts>, you will see
either <Allow host=""/> or <Deny host=""/> tags here.
You can specify, 'host', 'net', or 'mask' as the above attributes.
if host = 'ALL' then it calls tptp_addNetwork(*nList, 0, TPTP_HW_ALL, NULL, NULL);
if host = 'LOCAL' then it calls tptp_addNetwork(*nList, 0, TPTP_HW_LOCAL, NULL, NULL);
else host exists, but isn't either of the above, then: tptp_addNetwork(*nList, 0, TPTP_HW_NAMED, host, NULL);
- Adds it to nList, which is a 'network_list_t'. The second value is either allow or deny.
However, if host is not specified, then either net or mask is specified, and it calls:
- tptp_addNetwork(*nList, 0, TPTP_HW_NET, net, mask);
TransportSupportSocket:
getSocketPort (not used)
getHostInfo
Returns the IP address (4 byte format) of the given hostname.
Used by:
- unsigned long ConnectionImpl::getLocalIPAddress()
- unsigned long ConnectionImpl::getIPAddress(char* hostname) {
- unsigned long TCPDataServer::getLocalIPAddress()
- int getSocketIPString( SOCKET sock, char** ipAddrStr )
- Recommendation: Replace with equivalent struct sockaddr_storage * function.
convertIPAddressStringToUlong
- Converts 'dots and numbers' IP address to 4 byte format.
Used by:
-
tptp_int32 createSocketPeerConnection( server_block_t* pServerData,
tptp_string* sourceConnectionInfo, tptp_uint32* connectionID ) of
SocketListener.c
o parses the
<host></host> tag of sourceConnectionInfo, calls
convertIPAddressStringToULong, passes the address to
connectToTCPServer.
-
tptp_int32 createPeerConnection( tptp_object* tlo, tptp_string*
sourceConnectionInfo, tptp_uint32* connectionID ) of ClientCTL.c
o parses the
<host></host> tag of sourceConnectionInfo, calls
convertIPAddressStringToULong, passes the address to
connectToTCPServer.
- int processServerReachCmd(fs_connection_block_t* con) of nativeFileServer.c
o Reads an int from the connection (which it presumes to be the IP address), and calls connectToTCPServer() with that address.
-
Recommendation: Replace with equivalent struct sockaddr_storage *
function. Also, create an IPv4M'ed copy for reference by the peer
monitoring code.
getSocketIPString
Given
a SOCKET, it converts its 4-byte IP format into 'dots and numbers' IP
address. (If SOCKET passed in is NULL, it merely uses local host)
o createSocketPeerConnection in SocketListener.c (used to place IP into an xml tag)
o createPeerConnection in ClientCTL.c. (used to place IP into an xml tag)
o
translateAndForwardPeerRequestMonitor (grabs the local IP in string
form, converts it to 4 byte form, and stores it in
command->info.controller_request_monitor_port.node )
o translateAndForwardRequestMonitor (grabs the local IP in string form, converts it to 4 byte form, and
stores it in command->info.controller_request_monitor_port.node )
-
Recommendation: Replace with equivalent struct sockaddr_storage *
function. Create an IPv4M'ed copy for reference by the peer monitoring
code.
getPeerIPString
- Given a socket, store the dots and numbers format for the person we're connected to.
o
Used only by serveRequests in CCTLServer.c. It uses the 'dots and
numbers' string to convert into a 4 byte format ip, then calls
tptp_checkHost on it.
- Recommendation: Replace with equivalent struct sockaddr_storage * function.
getTargetHostInfo
- Given a host name string, return hostent.
o
Used only by unsigned long ConnectionImpl::getIPAddress(char*
hostname). Here it's used only to convert the string to the 4-byte
format
o When getIPAddress is rewritten, dump this method.
- Recommendaiton: This function is entirely IPv4, and should be removed. Rewrite getIPAddress to use sockaddr_storage *
getPeerName
- Given a socket, store the peer of the socket in 4 byte format.
o Used by int getClientIP(client_connection_block_t* ccb, unsigned char *buffer, int *length) of RACClientSupport.c.
o Called by getClientIP, the socket is read from ccb, and the four-byte address is stored in buffer.
connectToTCPServer
- Given an IP address in 4 byte format, and a portnumber, return a SOCKET to that connection.
-
Recommendation: Rewrite the function to take struct sockaddr_storage *
instead of the four byte format. Then fix the calling functions below
to pass it that format. For the peer monitoring functions, create an
empty function called connectToTCPServerIPv4M(...) and replace all RPM
calls with this method.
Used by:
o int ConnectionImpl::connect(INode* node, int port)
o int ConnectionImpl::connect(class INode* node, ConnectionInfo* connInfo)
o int ConnectionImpl::createDataConnection(int direction, int flags)
o void TCPDataServer::connect()
o
tptp_int32 createSocketPeerConnection( server_block_t* pServerData,
tptp_string* sourceConnectionInfo, tptp_uint32* connectionID ); in
SocketListener.c
o tptp_int32 createPeerConnection( tptp_object*
tlo, tptp_string* sourceConnectionInfo, tptp_uint32* connectionID
) in ClientCTL
o int processServerReachCmd(fs_connection_block_t* con) in nativeFileServer.c
o SOCKET openClientDataSocket(tptp_int32 ip, tptp_int32 port) in RACClientSupport.c
Native Code Structs that reference IP Addresses
TransportSupport.c:
typedef struct {
unsigned short addressLength;
unsigned char *addresses;
} tptp_IPAddresses_t;
- Referenced ONLY in TransportSupport.c, doesn't leave the C file.
- Used by isLocalHost() and tptp_checkHost().
- Data is stored in it by tptp_getLocalIPAddresses(...)
Recommendation: Leave as is for Stage 2.
MsgPipeline.h:
/* Structure used to override peer monitoring defaults */
typedef struct PeerAttachInfo_tag
{
int usePeerAttachPort;
int usePeerAttachAddress; // Not an IP Address
int peerAttachPort;
unsigned int peerAttachAddress; // IP address, 4 byte format.
} PeerAttachInfo_t;
Generated only by parseAndProcessParameters(...), which parses the command line.
Stored in ConnectionManager_t.
-
passed into setPeerAttachInfo (which copies the together the
ConnectionManager_t->peerInfo data structure and the
cctl_state_data_t of CCTL.)
Call stack:
return tl->setPeerAttachInfo( &tl->tlo, &cm->peerInfo );
tptp_int32 connectionManager_initializePeerConnectionTransport( ConnectionManager_t* cm, char* peerConnectionTransport );
tptp_int32 configurationManager_readConfigFile( ConfigurationManager_t* cm );
main(...) in AgentController.
Recommend: Leave PeerAttachInfo_t and parseAndProcessParameters() for stage 4.
TPTPUtils.h:
typedef struct {
int allow;
/* Is this an Allow entry or a
Deny? */
tptp_host_wildcard_t
wildcard; /* Is this a range of
addresses or an exact address? */
unsigned char
net[4]; /* The network address
information in network byte order. Note that this is IPV4
specific */
unsigned char
mask[4]; /* the subnet mask
information in network byte order. Note that this is IPV4
specific */
char *hostname;
} network_t;
net/mask are used by:
- void tptp_addNetwork(network_list_t *list, int allow, tptp_host_wildcard_t wildcard, char *name, char *mask)
- int parseHostList(const char *initString, network_list_t **nList)
- BOOL tptp_checkHost(network_list_t *list, unsigned char *address).
- Recommend: Leave for stage 4.
RASocket:
/* IPV4 and IPV6 ipaddress compatable structure */
typedef struct {
unsigned char addrLength;
unsigned char *addr;
} ra_ipaddr_t;
The above is used only by the peer monitoring code. RABinding.c/RABinding.h, and hcjbnd.c.
- Recommend: Leave for stage 4.
typedef struct {
unsigned short addressLength;
unsigned char *addresses;
} ra_IPAddresses_t;
produced only by short ra_getLocalIPAddresses(ra_IPAddresses_t *addr).
used
by print.c of hcjbnd java_profiler: static unsigned
short printIPAddressAttribute(ThreadPrivateStorage *tps, unsigned short
current)
also used by print.c of hcjbnd java_profiler:
void
jvmpiAgent_printTraceStartElement(ThreadLocalStorage *tps, char
*options) (but the ra_IPAddresses_t isn't actually used)
- Recommend: Rewrite in stage 2.
typedef struct {
[...]
/* Peer monitoring related fields */
int usePeerAttachPort;
int
usePeerAttachAddress; // peerAttachAddress is used
only if this is set to 1, otherwise local host is used. If this is set
to 0, peerAttachAddress is NEVER used.
int peerAttachPort;
unsigned int peerAttachAddress;
// IPv4 IP Address.. seems to double as a local IP address.
network_list_t *network_list;
[...]
} cctl_state_data_t; (defined in ClientCtl.h)
- Recommend: Leave for stage 4.
ra_command.t:
- defined in RAComm.h of tptp/include/compatibility.
- defined in RATypes.h of src-native-new/src/transport/RACommon
struct {
ra_uint_t context;
ra_uint_t processId;
ra_string_t agent;
ra_string_t node; /* node->data is a 4 byte IP address */
ra_uint_t peerProcessId;
ra_string_t peerAgent;
ra_string_t peerNode; /* peerNode->data is a 4 byte IP address */
}agent_request_monitor, /* AGENT_REQUEST_ATTACH */
controller_request_monitor, /* CONTROLLER_REQUEST_MONITOR */
peer_unreachable; /* PEER_UNREACHABLE */
struct {
ra_uint_t context;
ra_uint_t consoleIP; /* This is transmitted, but is NOT ever used. */
ra_uint_t consolePort;
ra_string_t executable;
ra_string_t arguments;
ra_string_t location;
ra_array_t environment;
ra_array_t agents;
}launch_process; /* LAUNCH_PROCESS*/
struct {
ra_uint_t context;
ra_uint_t processId;
ra_string_t agent;
ra_uint_t ip; /* This value is transmitted, but is not ever used by the NEW AC (see below). */
ra_uint_t port;
}start_monitor_remote; /* START_MONITOR_REMOTE */
ARM/CRM/PU:
Recommendation: Wait for stage 4.
launch_process->consoleIP:
References
in only three projects: CompSupport, RACommon, and TPTPClientCompTL.
None of these projects use the value, they only translate it, read it
from a buffer, or write it to a buffer. I tested this by overwriting
the value in the AC and profiling from a remote machine, and it works
as expected.
Recommendation: Value is not used, no change required.
start_monitor_remote->ip:
hcjbnd.c:
-
The only places where start_monitor_remote->ip is used is under
RA_START_MONITORING_AGENT_REMOTE code, which isn't used with the
new AC.
- The only other references to start_monitor_remote are fields unrelated to IPv6. No rewrites required.
JvmpiWriter.c:
- Both references are RA_START_MONITORING_AGENT_REMOTE only.
hcthread.c:
- RA_START_MONITORING_AGENT_REMOTE only.
RACSupport.c (CompSupport):
- Reading from buffer, writing to buffer, and translation, only. No functional use here.
RAComm.c (RACommon):
- Reading from buffer, writing to buffer, and translation, only. No functional use here.
TPTPClientCompTL:
- IP address fields not used, no rewrite required.
Recommendation: No rewrites required.
Old Hyades AC Code / Agent/Client Compatibility Layer Code
Client CTL
tptp_int32 startTransportListener(tptp_object* tlo)
-
Once getTheSocket is replaced, this method will
need to be rewritten to use the new getTheSocket() method, and to
listen on multiple sockets, rather than just the one.
RACClientSuport.c:
int getClientIP(client_connection_block_t* ccb, unsigned char *buffer, int *length)
- Retrieves the address of the peer that is connected to the AC on the ccb.
- If the ccb is a native socket, then it calls getPeerName (which returns in 4 byte format) and stores it in buffer.
- If the ccb is a java socket, then it looks like it gets the 4-byte or 16 byte formats.
o
Connect2Ac.c - startProcess(...) - calls getClientIP(), then calls
openClientDataSocket() which returns a SOCKET, which is used from
hereon.
o RACmdHandlers.c - handleLaunchProcess(...), calls
startProcess() with the 6th parameter being the 4-byte address from
clientIP. Note: This value is NOT USED by startProcess.
o
RACmdHandlers.c - handleStartMonitoring(...), . called by
processMessage(). calls GetClientIP(), passes it directly into
openClientDataSocket.
Recommendation: When openClientDataSocket is rewritten, rewrite the above with calls to the new IPv4/IPv6 agnostic code.
Connect2AC.c:
PID
startProcess( client_connection_block_t* ccb, ra_string_t *exe,
ra_string_t *args, ra_string_t *location, ra_array_t *environment,
unsigned long remoteConsoleIP, unsigned short remoteConsolePort,
ra_array_t *finalEnvironment, SOCKET *consoleSock, ra_string_t *uuid):
- remoteConsoleIP arguments needs to be rewritten. HOWEVER, this function doesn't use the value for anything, or touch it at all. So no change here.
-
calls getClientIP() followed by openClientDataSocket(). The value
is then passed into openClientDataSocket(). The value is not used after
this.
o
startProcess is called only by BOOL handleLaunchProcess(
client_connection_block_t* ccb, ra_command_t* command ) in
RACmdHandlers.c
Recommendation: Rewrite the
getClientIP/openClientDataSocket() call to use struct
sockaddr_storage* equivalent. Leave the remoteConsoleIP param
alone (for now).
SOCKET openClientDataSocket(tptp_int32 ip, tptp_int32 port)
- called only by handleLaunchProcess and handleStartMonitoring, above.
- ONLY calls connectToTCPServer(ip, (unsigned short) port, &sock);
- Recommendation: When connectToTCPServer is rewritten, rewrite this.
tptp_int32
translateAndForwardPeerRequestMonitor( tl_state_data_t*
stateData, client_connection_block_t* ccb, tptp_int32 context,
tptp_string* peerHost,
tptp_string* peerPort,
tptp_string* peerAgentName,
tptp_string* peerAgentPID,
tptp_string* srcAgentName,
tptp_string* srcAgentPID )
- peerHost is a standard dots and numbers string. No changes to function signature required.
Recommendation: Wait for stage 4. IPv4Mize any functions that this function uses.
Native File Server
THREAD_USER_FUNC_RET_TYPE startNativeFileServer(LPVOID args)
- Exactly as above, once getTheSocket is rewritten, as described above, this method will
need to be rewritten to use the new getTheSocket() method, and to
listen on multiple sockets, rather than just the one.
- convertIPAddressStringToUlong is used in processServerReachCmd().
RASocket
RASocket exports the following functions, used by other projects:
ra_connectToTCPServer (hcjbnd.c, java_profiler, hcthread.c)
-
Note: The above code only calls this method on receiving
"RA_START_MONITORING_AGENT_REMOTE". The New AC ACTL does not ever send
this.
- Recommendation: Mark as IPv4 only, do not port.
int ra_writeToSocket(SOCKET fd, char *buffer, ra_uint_t byteCount) (RADataTransfer.c)
o called only in ra_writeMessageBlock(...)
o used only in hcjbnd.c, java_profiler, perfmon, hcthread.
o The code itself is a simple send(...) on a socket.
- Recommendation: Does not need to be be rewritten.
ra_getLocalIPAddress (not called)
ra_getLocalIPAddresses (java_profiler)
o
printIPAddressAttribute (At this point it is converted into a string,
e.g: "9.26.145.102,127.0.0.1". We could use the IPv6
structure between these two, and rewrite only this part)
Recommendation:
Rewrite ra_getLocalIPAddresses to return sockaddr_storage, and rewrite
printIPAddressAttribute to use this new struct.
- void ra_closeSocket(SOCKET sockfd) (hcjbnd.c, java_profiler, hcthread.c)
- The code itself is a simple shutdown on a socket. No changes.
- ra_getLocalHostName (java_profiler)
o
called by printHostNameAttribtue() (where it is converted to a
string... same conversion method as ra_getLocalIPAddresses above)
- Does not need to be rewritten. Is not IPv6 specific.
ra_win32InitializeSockets
- Code is not IPv6 specific. No rewrites needed.
RASocket
exports the following functions which are not referenced outside of
RASocket, and are not called within RASocket itself (they're unused):
- ra_createBoundUDPServer (RASocket only)
- ra_createTCPServer (RASocket only)
- ra_getFormattedLocalIPAddress (RASocket only)
GetAddress Revealed Problems (All Hyades, All Stage 4)
Note:
getAddress(...)
can be used to get the byte array from an InetAddress. In any number of
places this is used, but only 4 bytes are accepted.
This reveals problems in:
requestMonitorThroughPeer0p of RemoteComponentSkeleton:
public void requestMonitorThroughPeer_p(InetAddress addr, long port, String agentUUID, long timeout)
- requestMonitorThroughPeer0p(addr.getAddress(), port, agentUUID);
- private native void requestMonitorThroughPeer0p(byte[] addr, long port, String agentUUID);
-
Java_org_eclipse_hyades_internal_execution_remote_RemoteComponentSkeleton_requestMonitorThroughPeer0p___3BJLjava_lang_String_2(JNIEnv
*env, jobject obj, jbyteArray ipaddr, jlong port, jstring agentUUID)
- Create a ra_ipaddr_t addr, store the FULL address in there (however many bytes it is given), calls ra_requestPeerMonitor2_p.
-
Sets fields in command->info.agent_request_monitor and calls send
message on the resulting message. The command->tag is either
RA_AGENT_REQUEST_MONITOR or RA_AGENT_REQUEST_MONITOR_PORT depending on
the circumstance.
public void requestMonitorThroughPeer_p(InetAddress addr, long port, long pid, String agentName, long timeout) {
- requestMonitorThroughPeer0p(addr.getAddress(), port, pid, agentName);
- native void requestMonitorThroughPeer0p(byte[] addr, long port, long pid, String agentName);
-
Java_org_eclipse_hyades_internal_execution_remote_RemoteComponentSkeleton_requestMonitorThroughPeer0p___3BJJLjava_lang_String_2(JNIEnv
*env, jobject obj, jbyteArray ipaddr, jlong port, jlong pid, jstring
agentName)
- As above, except calls ra_requestPeerMonitor_p instead, which itself uses agent_request_monitor and either of those two tags depending on circumstance.
Recommendation: Neither of these technically need to change, as long as the parsing side is handling them properly.
StartMonitoringRemoteAgentCommand: setInetAddress(..)
SMRAC is sent by startMonitoring() of AgentImpl.
When
'start_monitor_remote' is supplemented/replaced with a IPv6 compatible
message, a new Java StartMonitoringRemoteAgentCommand will need to be
written to support this IPv6 message. Thus, this SMRAC command itself
probably won't change.
Recommendation:
Stage 4: Implement new IPv6 class, that will supplement this class. Essentially
the message that we send out in this class is just telling the agent
controller to connect back to us at a particular IP and port.So this new command should be easy to implement.
MonitorPeerRequestCommand: getPeerNode(). getTargetNode().
MPRC
kicks off the peer request monitoring feature. An agent sends this to
it's agent controller to begin the RPM process. This class will be
supplemented by a class that uses IPv6 compatible fields.
Recommendation: Stage 4: Same as SMRAC.
Message: public static int writeRAInetAddressToBuffer(byte[] buffer, int offset, RAInetAddress addr).
- Nothing calls it. Deprecate?
Console: public void run { }
- The Console class is used by the LaunchProcessCommand, and by Process/ProcessImpl.
-
Console stores its IP as a long. It does the conversion itself,
and the IP will be stored incorrectily if Java is using
IPv6 rather than IPv4.
- run() method then calls
determineServerReach() of IFileManagerExtended, which takes an
InetAddress. However, DetermineServerReach sends a String so it is IPv6
compatible.
- LaunchProcessCommand reads the console and writes the console value as per it's Hyades message.
- The IP address of Console is ONLY used by LaunchProcessCommand, and no one uses that value from LaunchProcessCommand.
-
And inside the agent controller, that value isn't used either. It's
read and written to the message, but never accessed or used. I had the
client sends 0s for this, and it worked fine (even connecting to a
remote machine).
Recommendation: Leave as is.
DataChannelImpl: hc_flushDCBufferToSocket
- Unused.