Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 96379 Details for
Bug 165409
IPv6 Support
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
IPv6 Design Review
IPv6 Design Review.html (text/html), 51.54 KB, created by
Jonathan West
on 2008-04-16 23:55:37 EDT
(
hide
)
Description:
IPv6 Design Review
Filename:
MIME Type:
Creator:
Jonathan West
Created:
2008-04-16 23:55:37 EDT
Size:
51.54 KB
patch
obsolete
><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> ><html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"><title>IPv6 Design Review</title></head> ><body><div style="text-align: center;"><span style="font-weight: bold; text-decoration: underline;">IPv6 Design Review</span><br></div><span style="font-weight: bold;"></span><br><br><big><span style="text-decoration: underline;">IPv4 -> IPv6 Patterns</span></big><br><br>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.<br><br>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 *.<br><br>With the above being the case, the following utility functions are required to implement the AC functionality currently in use.<br><br>- >We need a function that converts standardized address -> hostname >code, which will take the address in either form and return a name (See convertAddrToHostname(...) )<br>- >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(...) )<br><br>- 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(...) )<br>- >We need a function that gets the standarized address(es) for any >given hostname/ip address. (See convertHostnameToAddrs(...))<br>- We need a function that gets the standardized address(es) for a local host. (See getLocalHostAddresses(...))<br><br>- We need a function that determines whether a standardized address is a local host address (See isAddrLocal(...) ).<br>- We need a function that compares (binary comparison) standardizes addresses with each other (See compareAddresses(...) )<br><br><span style="color: black;">- We need a function that converts the standardized address into its 4 (IPv4) or 16 (IPv6) byte representation, and vice versa.</span> (See getByteFormatFromSockAddr() and getSockAddrFromByteFormat() )<br><br>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.<br><span style="color: rgb(51, 0, 153);"></span><span style="color: rgb(51, 51, 255);"></span><br><big><span style="text-decoration: underline;">Central Guidelines</span></big><br><br><span style="font-weight: bold;">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.</span><br><br>- >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.<br><span style="color: black;"><br>- >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, </span><span style="font-weight: bold; color: black;">getSocketIPString</span><span style="color: black;"> >is called by the peer monitoring method <span style="font-style: italic;">getPeerConnectionInfo</span>. Create a >new method called <span style="font-weight: bold;">getSocketIPStringIPv4M(),</span> with the same contents as >the original, and replace any references in getPeerConnectionInfo with >the new IPv4 name.<span style="font-weight: bold;"> At the end of IPv4 function name </span></span><span style="font-weight: bold; color: black;">should be IPv4M, to allow us to track them</span><span style="color: black;">. </span><br style="color: rgb(51, 0, 153);"><span style="color: rgb(255, 102, 102);"></span><br><span style="color: black;">- Reserve porting the request peer monitoring functionality until stage 4. </span><br style="color: red;"><span style="color: black;">- >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</span>.<br><br>- Use the new 'getTheSocket' method which I have provided in the example file. <br>- 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.<br>- >Fix connectToTCPServer so that it takes the standardized address, as >above <span style="font-style: italic;">(I've written a replacement for this method, either >'connectToHostWithAddr' or 'connectToHostWithHostname', depending on >the context, usually the former)</span><br><br>- >Fix all functions that directly or indirectly pass the 4-byte IP >address into connectToTCPServer with the struct sockaddr_storage * >code equivalent.<br>- Having changed the method signatures of the above functions, fix any calling methods of these functions, ad infinitium.<br><br>- >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 */<br><span style="color: black;"></span><span style="color: rgb(51, 0, 153);"></span><br><span style="color: rgb(51, 0, 153);"></span>- Lower Priority: May want to comment out, the RAInetAddress java code.<br>- See function level recommendations below, for remaining functions.<br><br><br><br><br><big><span style="text-decoration: underline;">Intel / IBM Dependencies</span></big><br><br><span style="font-weight: bold;">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.</span><br><br><span style="font-weight: bold;">Stage 2</span>:<br>- >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.<br>- 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.<br>- Once Intel's stage 2 code is complete, a patch should be sent to IBM that includes the changes.<br>- >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.<br>- Once >complete, IBM will produce a patch that should be a working, >compileable AC, but with host access and request peer monitoring >functionality disabled.<br>- From here, we can pass to stage 3.<br><br><span style="font-weight: bold;">Stage 3+</span>:<br>- After Stage 2, we'll manage dependencies differently.<br><br><br><br><big><span style="text-decoration: underline;">New AC Code Methods where IPv4-only code is used</span></big><br><br><span style="font-weight: bold;">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.</span> <span style="font-weight: bold;">In many cases, these functions can merely be replaced with the updated socket code equivalent.</span><br><br><span style="font-weight: bold; text-decoration: underline;">AgentController.c</span>:<br><br><span style="font-weight: bold;">unsigned int parsePeerAttachAddress(char* str)</span>:<br>- Takes a dots and numbers IP addresse and returns it in 4 byte format.<br><br>Called by:<br>- parseAndProcessParameters(), which is called by main.<br>- Stored in <br> cm->peerInfo.usePeerAttachAddress = TRUE;<br> cm->peerInfo.peerAttachAddress = parsePeerAttachAddress(arg);<br><br>- See also, PeerAttachInfo_t, below.<br><br><span style="color: black;">Recommendation: Leave this for stage 4. </span>As long as the consumer doesn't use the two peer monitoring command line switches, this should be fine.<br><br><br><big><small><span style="font-weight: bold; text-decoration: underline;">ConnectionImpl.cpp</span></small>:</big><br><br><span style="font-weight: bold;">ConnectionImpl::getLocalIPAddress()</span> (not used)<br><br><span style="font-weight: bold;">ConnectionImpl::getIPAddress()</span> (used by itself)<br>- Returns IP address in 4-byte format (unsigned long).<br>- Used only as the first parameter to connectToTCPServer<br>- >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.<br><br><br><br><span style="font-weight: bold; text-decoration: underline;">TCPDataServer.cpp</span>:<br><br><span style="font-weight: bold;">TCPDataServer::getLocalIPAddress()</span> (used by itself, it would seem)<br>- Returns IP address in 4-byte format (unsigned long).<br>- Used only as the first parameter to connectToTCPServer<br>- Recommendation: When connectToTCPServer is fixed, this function should return the appropriate IPv6 struct.<br><br><span style="font-weight: bold; text-decoration: underline;">TPTP_INetAddress.cpp</span><big>:</big><br><br><span style="font-weight: bold;">TPTP_INetAddress::getAddress</span> (unused, however part of native client api... may be used by consuming product)<br>- Is merely a host name resolve.<br>- Input: Hostname (char *)<br>- Output: char * (dots and numbers IP address, string)<br>- Recommendation: Is self-contained, we need only to replace this with IPv6-based host name resolution.<br><br><br><big style="text-decoration: underline;"><small><span style="font-weight: bold;">TPTPCBE.cpp</span></small></big><big style="text-decoration: underline;">:</big><br style="text-decoration: underline;"><br><span style="font-weight: bold;">createSourceComponentID</span> (used, called by itself, merely prints the hostname)<br>- The offending code in this method only gets the local hostname (char *) and sprintfs it into a string. <br>- Recommendation: Self-contained, easily replaced.<br><br><br><big><small><span style="text-decoration: underline; font-weight: bold;">SocketListener.c</span></small>:</big><br><br><span style="font-weight: bold;">doListening</span> <br>- Rewrite the function using the new getTheSocket(...) call. bindAndListen call no longer needed. <br>- Code must now listen on multiple server sockets.<br>- Recommendation: Rewrite using the new getTheSocket(...) method, and the code must now listen on multiple server sockets.<br><br><big><small><span style="font-weight: bold; text-decoration: underline;">TransportOSCalls_win.c</span></small>:</big><br><br><span style="font-weight: bold;">printSocketRequest</span> (not used - may be for debug purposes)<br><br style="color: rgb(51, 0, 153);"><span style="font-weight: bold; color: rgb(18, 28, 18);">convertIPAddressStringToArray</span><br style="color: rgb(18, 28, 18);"><span style="color: rgb(18, 28, 18);">- input is an IP address in string form, output is 4 unsigned characters</span><br style="color: rgb(18, 28, 18);"><span style="color: rgb(18, 28, 18);"> >o in CCTLServer.c serveRequests() - Grabs's the peer's IP in string >form, calls this method, then passes it into tptp_checkHost.</span><br style="color: rgb(18, 28, 18);"><span style="color: rgb(18, 28, 18);"> >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.</span><br style="color: rgb(18, 28, 18);"><br style="color: rgb(18, 28, 18);"><span style="color: rgb(18, 28, 18);"> >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.</span><br style="color: rgb(18, 28, 18);"><span style="color: rgb(18, 28, 18);"><br>Recommend leaving this one alone for now, until the fourth stage. </span>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.<br style="color: rgb(18, 28, 18);"><span style="color: rgb(18, 28, 18);"></span><br> <br><span style="font-weight: bold;">convertIPAddressUlongToString</span> <br>- Converts the four byte IP format to a 'dots and numbers' string<br> o Used only by getPeerConnectionInfo in ClientCTL.c<br> o >Outputted as 'dots and numbers' to host portion: ><transportType>TPTP_CCTL</transportType><host>%s</host><port>%d</port><br> >o This call is only made when cctlData->usePeerAttachPort is >called. It is called on cctlData->peerAttachAddress.<br><br><span style="color: red;"></span>Recommendation: Because this is peer monitoring specific, recommend leaving it to stage 4. IPv4M it.<br><br><span style="font-weight: bold;">extractAddressFromSockAddr (not used)</span><br><br><br><br><big><small><span style="font-weight: bold; text-decoration: underline;">TransportOSCalls_linux.c (as above)</span></small>:</big><br><br>printSocketRequest (not used - may be for debug purposes)<br>convertIPAddressStringToArray<br>convertIPAddressUlongToString<br>extractAddressFromSockAddr (not used)<br><span style="color: black;">- Same as above.</span><br style="color: black;"><br><br><big><small><span style="font-weight: bold; text-decoration: underline;">TransportSupport</span></small>:</big><br><br>tptp_getLocalIPAddress (not used)<br><br><span style="font-weight: bold;">tptp_getLocalIPAddresses</span><br>- Stores the local IP addresses in 4 byte form (null terminated char* list format, inside a tptp_IPAddresses_t )<br> o Used by isLocalHost() and tptp_checkHost(), below.<br><span style="color: black;">- Recommendation: Because it's only used by the checkHost functionality, leave as is in stage 2.</span> IPv4M it.<br><br><span style="font-weight: bold;">isLocalHost</span><br>- Input is host name, output is either true or false.<br>- Called only by tptp_checkHost<br>- >Recommendation: Leave as in stage 2 (IPv4M it.). In stage 4, rewrite: >Self contained, rewrite to use IPv6 compliant code.<br> <br><span style="font-weight: bold;">tptp_checkHost </span><br>- Input is network_list_t, and an address in four byte format.<br> o Used by serverRequests() of CCTLServer.c <br>- Recommendation: Leave as in stage 2.<br style="color: black;"><span style="color: red;"><br><br><br><span style="color: black; font-style: italic;"><span style="text-decoration: underline;">Stage 4 Work (skip this section for Stage 2)</span>:</span><br><br><span style="color: black;">The structs related to the code are:<br> </span><br style="color: black;"><span style="color: black;">typedef struct {</span><br style="color: black;"><span style="color: black;"> network_list_node_t *head;</span><br style="color: black;"><span style="color: black;"> network_list_node_t *tail;</span><br style="color: black;"><span style="color: black;">} network_list_t;</span><br style="color: black;"><br style="color: black;"><br style="color: black;"><span style="color: black;">Stored in:</span><br style="color: black;"><span style="color: black;">{</span><br><span style="color: black;"> (...)</span><br style="color: black;"><span style="color: black;"> BOOL securityEnabled;</span><br style="color: black;"><span style="color: black;"> tptp_uint32 securedPort;</span><br style="color: black;"><span style="color: black;"> tptp_string *keystore;</span><br style="color: black;"><span style="color: black;"> tptp_string *keystorePassword;</span><br style="color: black;"><span style="color: black;"> network_list_t *network_list;</span><br style="color: black;"><span style="color: black;"> tptp_string *users;</span><br style="color: black;"><span style="color: black;">} cctl_state_data_t;</span><br style="color: black;"><br style="color: black;"><span style="color: black;">Unsupported, nothing will generate these entries: TPTP_HW_UNKNOWN, TPTP_HW_KNOWN, TPTP_HW_MAX_VALUE, </span><br style="color: black;"><span style="color: black;"></span><br style="color: black;"><span style="color: black;"><span style="font-style: italic;">TransportSupport.c</span>:</span><br style="color: black;"><br style="color: black;"><span style="color: black;">BOOL tptp_checkHost(network_list_t *list, unsigned char *address);</span><br style="color: black;"><br style="color: black;"><span style="color: black;">- Called only in THREAD_USER_FUNC_RET_TYPE serveRequests(LPVOID args)</span><br style="color: black;"><span style="color: black;"> o Gets the string host name of the peer connected to it</span><br style="color: black;"><span style="color: black;"> o Converts that to 4-byte format</span><br style="color: black;"><span style="color: black;"> o calls tptp_checkHost on that 4 byte format.</span><br style="color: black;"><span style="color: black;"> o Note: the tptp_checkHost called can be easily commented out.</span><br style="color: black;"><br style="color: black;"><span style="color: black;">- address is address in 4-byte format.</span><br style="color: black;"><br style="color: black;"><span style="color: black;">- begins at list->head</span><br style="color: black;"><span style="color: black;">- pulls a network_t out of current->entry</span><br style="color: black;"><span style="color: black;">- entry->wildcard = TPTP_HW_ALL, TPTP_HW_LOCAL, TPTP_HW_UNKNOWN, TPTP_HW_KNOWN, TPTP_HW_NET, TPTP_HW_NAMED</span><br style="color: black;"><br style="color: black;"><span style="color: black;">case TPTP_HW_ALL: </span><br style="color: black;"><span style="color: black;">- if allow return true, otherwise return false. Doesn't need to be rewritten.</span><br style="color: black;"><br style="color: black;"><span style="color: black;">case TPTP_HW_LOCAL: </span><br style="color: black;"><span style="color: black;">- needs to be rewriten</span><br style="color: black;"><span style="color: black;">- >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.</span><br style="color: black;"><br style="color: black;"><span style="color: black;">case TPTP_HW_NET:</span><br style="color: black;"><span style="color: black;">- needs to be rewritten</span><br style="color: black;"><span style="color: black;">- >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.</span><br style="color: black;"><span style="color: black;">- resolve the address into string format, and store the alternative names as well</span><br style="color: black;"><span style="color: black;">- compare the named ip listed in the file with the one we now have</span><br style="color: black;"><span style="color: black;">- compare aliases as well.</span><br style="color: black;"><br style="color: black;"><br style="color: black;"><span style="color: black;">The above constants are referenced in the following places:</span><br style="color: black;"><br style="color: black;"><span style="color: black;">- TPTP_HW_ALL (parseHostList in TPTPUtil.c)</span><br style="color: black;"><span style="color: black;">- TPTP_HW_LOCAL (parseHostList in TPTPUtil.c)</span><br style="color: black;"><span style="color: black;">- TPTP_HW_NET (tptp_addNetwork, parseHostList in TPTPUtil.cpp)</span><br style="color: black;"><span style="color: black;">- TPTP_HW_NAMED (tptp_addNetwork, parseHostList in TPTPUtil.cpp)</span><br style="color: black;"><span style="color: black;"></span><br style="color: black;"><br><br style="color: black;"><span style="color: black;"><span style="font-style: italic;">TPTPUtil.cpp</span>:</span><span style="color: black;"></span><br style="color: black;"><br style="color: black;"><span style="color: black; font-style: italic;">void tptp_addNetwork(network_list_t *list, int allow, tptp_host_wildcard_t wildcard, char *name, char *mask)</span><br style="color: black;"><span style="color: black;">- called by parseHostList(...)</span><br style="color: black;"><br style="color: black;"><span style="color: black;">network_t *network;</span><br style="color: black;"><br style="color: black;"><span style="color: black;">network->allow=allow; // This handles the allow field.</span><br style="color: black;"><span style="color: black;">network->wildcard=wildcard; // This handles TPTP_HW_ALL and TPTP_HW_LOCAL</span><br style="color: black;"><br style="color: black;"><span style="color: black;">if wildcard is TPTP_HW_NAMED:</span><br style="color: black;"><span style="color: black;">- This needs to be rewritten for IPv6.</span><br style="color: black;"><span style="color: black;">- 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.</span><br style="color: black;"><span style="color: black;">- ELSE, if a named host is specified here, then store that named host in network->hostname</span><br style="color: black;"><br style="color: black;"><br style="color: black;"><span style="color: black;">if wildcard is TPTP_HW_NET:</span><br style="color: black;"><span style="color: black;">- This needs to be rewritten for IPv6</span><br style="color: black;"><span style="color: black;">- network->net is 4 byte format IP address. </span><br style="color: black;"><span style="color: black;">- network->mask is 4 byte format IP address.</span><br style="color: black;"><span style="color: black;">- This code converts a text string into IPv4 IP format.</span><br style="color: black;"><span style="color: black;">- It converts net and mask to IPv4 4 byte format.</span><br style="color: black;"><br style="color: black;"><br style="color: black;"><span style="color: black; font-style: italic;">int parseHostList(const char *initString, network_list_t **nList):</span><br style="color: black;"><span style="color: black;">- Called by 'createTransportListener' of ClientCTL.c.</span><br style="color: black;"><br style="color: black;"><span style="color: black;">No IPv6 changes required.</span><br style="color: black;"><br style="color: black;"><span style="color: black;">(network_list_t is malloc here. It's entirely possible for it to be NULL.)</span><br style="color: black;"><br style="color: black;"><span style="color: black;">Under ><Hosts configuration="default">....</Hosts>, you will see >either <Allow host=""/> or <Deny host=""/> tags here.</span><br style="color: black;"><br style="color: black;"><span style="color: black;">You can specify, 'host', 'net', or 'mask' as the above attributes.</span><br style="color: black;"><br style="color: black;"><span style="color: black;">if host = 'ALL' then it calls tptp_addNetwork(*nList, 0, TPTP_HW_ALL, NULL, NULL);</span><br style="color: black;"><span style="color: black;">if host = 'LOCAL' then it calls tptp_addNetwork(*nList, 0, TPTP_HW_LOCAL, NULL, NULL);</span><br style="color: black;"><span style="color: black;">else host exists, but isn't either of the above, then: tptp_addNetwork(*nList, 0, TPTP_HW_NAMED, host, NULL);</span><br style="color: black;"><span style="color: black;">- Adds it to nList, which is a 'network_list_t'. The second value is either allow or deny.</span><br style="color: black;"><br style="color: black;"><span style="color: black;">However, if host is not specified, then either net or mask is specified, and it calls:</span><br style="color: black;"><span style="color: black;">- tptp_addNetwork(*nList, 0, TPTP_HW_NET, net, mask);</span><br style="color: black;"><br style="color: black;"><br><br><br></span><big><small><span style="font-weight: bold; text-decoration: underline;">TransportSupportSocket</span></small>:</big><br><br><span style="font-weight: bold;">getSocketPort (not used)</span><br><br><span style="font-weight: bold;">getHostInfo</span><br>Returns the IP address (4 byte format) of the given hostname.<br>Used by:<br>- unsigned long ConnectionImpl::getLocalIPAddress()<br>- unsigned long ConnectionImpl::getIPAddress(char* hostname) {<br>- unsigned long TCPDataServer::getLocalIPAddress()<br>- int getSocketIPString( SOCKET sock, char** ipAddrStr )<br><br>- Recommendation: Replace with equivalent struct sockaddr_storage * function. <br><br><span style="font-weight: bold;">convertIPAddressStringToUlong</span> <br>- Converts 'dots and numbers' IP address to 4 byte format.<br><span style="color: red;"><span style="color: black;"><br>Used by:</span><br style="color: black;"><span style="color: black;">- >tptp_int32 createSocketPeerConnection( server_block_t* pServerData, >tptp_string* sourceConnectionInfo, tptp_uint32* connectionID ) of >SocketListener.c</span><br><span style="color: black;">o parses the ><host></host> tag of sourceConnectionInfo, calls >convertIPAddressStringToULong, passes the address to >connectToTCPServer. </span><br><br style="color: black;"><span style="color: black;">- >tptp_int32 createPeerConnection( tptp_object* tlo, tptp_string* >sourceConnectionInfo, tptp_uint32* connectionID ) of ClientCTL.c</span><br style="color: black;"><span style="color: black;"></span></span><span style="color: red;"><span style="color: black;">o parses the ><host></host> tag of sourceConnectionInfo, calls >convertIPAddressStringToULong, passes the address to >connectToTCPServer. </span><br><br></span><span style="color: red;"><span style="color: black;">- int processServerReachCmd(fs_connection_block_t* con) of nativeFileServer.c</span><br style="color: black;"></span>o Reads an int from the connection (which it presumes to be the IP address), and calls connectToTCPServer() with that address.<br><br>- >Recommendation: Replace with equivalent struct sockaddr_storage * >function. Also, create an IPv4M'ed copy for reference by the peer >monitoring code.<br><span style="color: red;"><span style="color: black;"><br></span></span><br><br><span style="font-weight: bold;">getSocketIPString</span> <br>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)<br>o createSocketPeerConnection in SocketListener.c (used to place IP into an xml tag)<br>o createPeerConnection in ClientCTL.c. (used to place IP into an xml tag)<br>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 )<br>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 )<br>- >Recommendation: Replace with equivalent struct sockaddr_storage * >function. Create an IPv4M'ed copy for reference by the peer monitoring >code.<br><span style="font-weight: bold;"><br>getPeerIPString</span><br>- Given a socket, store the dots and numbers format for the person we're connected to.<br>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.<br>- Recommendation: Replace with equivalent struct sockaddr_storage * function.<br><br><span style="font-weight: bold;">getTargetHostInfo</span><br>- Given a host name string, return hostent.<br>o >Used only by unsigned long ConnectionImpl::getIPAddress(char* >hostname). Here it's used only to convert the string to the 4-byte >format <br>o When getIPAddress is rewritten, dump this method.<br>- Recommendaiton: This function is entirely IPv4, and should be removed. Rewrite getIPAddress to use sockaddr_storage *<br><br><span style="font-weight: bold;">getPeerName</span><br><span style="color: black;">- Given a socket, store the peer of the socket in 4 byte format. </span><br>o Used by int getClientIP(client_connection_block_t* ccb, unsigned char *buffer, int *length) of RACClientSupport.c. <br>o Called by getClientIP, the socket is read from ccb, and the four-byte address is stored in buffer.<br><br><br><span style="font-weight: bold;">connectToTCPServer</span> <br>- Given an IP address in 4 byte format, and a portnumber, return a SOCKET to that connection.<br>- >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.<br><span style="font-style: italic;"><br>Used by</span>:<br>o int ConnectionImpl::connect(INode* node, int port)<br>o int ConnectionImpl::connect(class INode* node, ConnectionInfo* connInfo)<br>o int ConnectionImpl::createDataConnection(int direction, int flags)<br><br>o void TCPDataServer::connect()<br><br>o >tptp_int32 createSocketPeerConnection( server_block_t* pServerData, >tptp_string* sourceConnectionInfo, tptp_uint32* connectionID ); in >SocketListener.c<br>o tptp_int32 createPeerConnection( tptp_object* >tlo, tptp_string* sourceConnectionInfo, tptp_uint32* connectionID >) in ClientCTL<br>o int processServerReachCmd(fs_connection_block_t* con) in nativeFileServer.c<br><br>o SOCKET openClientDataSocket(tptp_int32 ip, tptp_int32 port) in RACClientSupport.c<br><br><br><br><big><span style="text-decoration: underline;">Native Code Structs that reference IP Addresses</span></big><span style="text-decoration: underline;"></span><br><br><span style="font-weight: bold;">TransportSupport.c</span>:<br><br>typedef struct {<br> unsigned short addressLength;<br> unsigned char *addresses; <br>} <span style="font-weight: bold;">tptp_IPAddresses_t</span>;<br><br>- Referenced ONLY in TransportSupport.c, doesn't leave the C file.<br>- Used by isLocalHost() and tptp_checkHost().<br>- Data is stored in it by tptp_getLocalIPAddresses(...)<br><br><span style="color: black;">Recommendation: Leave as is for Stage 2.</span><br><br><br><span style="font-weight: bold;">MsgPipeline.h</span>:<br><br>/* Structure used to override peer monitoring defaults */<br>typedef struct PeerAttachInfo_tag<br>{<br> int usePeerAttachPort;<br> int usePeerAttachAddress; // Not an IP Address<br> int peerAttachPort;<br><span style="color: black;"> unsigned int peerAttachAddress; // IP address, 4 byte format.</span><br>} <span style="font-weight: bold;">PeerAttachInfo_t</span>;<br><br>Generated only by parseAndProcessParameters(...), which parses the command line.<br>Stored in ConnectionManager_t. <br><br>- >passed into setPeerAttachInfo (which copies the together the >ConnectionManager_t->peerInfo data structure and the >cctl_state_data_t of CCTL.)<br><br><span style="font-style: italic;">Call stack</span>:<br>return tl->setPeerAttachInfo( &tl->tlo, &cm->peerInfo );<br>tptp_int32 connectionManager_initializePeerConnectionTransport( ConnectionManager_t* cm, char* peerConnectionTransport );<br>tptp_int32 configurationManager_readConfigFile( ConfigurationManager_t* cm );<br>main(...) in AgentController.<br><br><br>Recommend: Leave PeerAttachInfo_t and parseAndProcessParameters() for stage 4.<br><br><br><span style="font-weight: bold;">TPTPUtils.h</span>:<br><br>typedef struct {<br> >int allow; > /* Is this an Allow entry or a >Deny? */<br> tptp_host_wildcard_t >wildcard; /* Is this a range of >addresses or an exact address? */<br> unsigned char >net[4]; /* The network address >information in network byte order. Note that this is<span style="color: rgb(0, 0, 102);"> <span style="font-weight: bold;">IPV4 >specific</span></span> */<br> unsigned char >mask[4]; /* the subnet mask >information in network byte order. Note that this is<span style="font-weight: bold; color: rgb(0, 0, 102);"> IPV4 >specific</span> */<br> char *hostname;<br>} <span style="font-weight: bold;">network_t</span>;<br><br>net/mask are used by:<br>- void tptp_addNetwork(network_list_t *list, int allow, tptp_host_wildcard_t wildcard, char *name, char *mask)<br>- int parseHostList(const char *initString, network_list_t **nList)<br>- BOOL tptp_checkHost(network_list_t *list, unsigned char *address).<br><br>- Recommend: Leave for stage 4.<br><br><span style="font-weight: bold;">RASocket</span>:<br><br>/* IPV4 and IPV6 ipaddress compatable structure */<br>typedef struct {<br> unsigned char addrLength;<br> unsigned char *addr;<br>} <span style="font-weight: bold;">ra_ipaddr_t</span>;<br>The above is used only by the peer monitoring code. RABinding.c/RABinding.h, and hcjbnd.c.<br><br>- Recommend: Leave for stage 4.<br><br><span style="color: red;"><span style="color: black;"><br></span></span><br><br>typedef struct {<br> unsigned short addressLength;<br> unsigned char *addresses; <br>} <span style="font-weight: bold;">ra_IPAddresses_t</span>;<br><br>produced only by short ra_getLocalIPAddresses(ra_IPAddresses_t *addr).<br>used >by print.c of hcjbnd java_profiler: static unsigned >short printIPAddressAttribute(ThreadPrivateStorage *tps, unsigned short >current)<br>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)<br><br>- Recommend: Rewrite in stage 2.<br><br><br>typedef struct {<br>[...]<br> /* Peer monitoring related fields */<br> int usePeerAttachPort;<br> >int >usePeerAttachAddress; <span style="color: rgb(51, 51, 255);">// 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.</span><br> int peerAttachPort;<br><span style="color: black;"> >unsigned int peerAttachAddress; > <span style="color: rgb(51, 51, 255);">// IPv4 IP Address.. seems to double as a local IP address.</span></span><br><br> network_list_t *network_list;<br>[...]<br>} <span style="font-weight: bold;">cctl_state_data_t</span>; (defined in ClientCtl.h)<br><br>- Recommend: Leave for stage 4.<br><br><br><br><span style="font-weight: bold;">ra_command.t</span>:<br>- defined in RAComm.h of tptp/include/compatibility.<br>- defined in RATypes.h of src-native-new/src/transport/RACommon<br><br><pre> struct {<br> ra_uint_t context;<br> ra_uint_t processId;<br> ra_string_t agent;<br> ra_string_t node; <span style="color: rgb(51, 51, 255);">/* node->data is a 4 byte IP address */</span><br> ra_uint_t peerProcessId;<br> ra_string_t peerAgent;<br> ra_string_t peerNode; <span style="color: rgb(51, 51, 255);">/* peerNode->data is a 4 byte IP address */</span><br style="color: rgb(51, 51, 255);"> }agent_request_monitor, /* AGENT_REQUEST_ATTACH */<br> controller_request_monitor, /* CONTROLLER_REQUEST_MONITOR */<br> peer_unreachable; /* PEER_UNREACHABLE */<br></pre><br><pre> struct {<br> ra_uint_t context;<br><span style="color: red;"> <span style="color: black;">ra_uint_t consoleIP;</span></span> <span style="color: rgb(51, 102, 255);">/* This is transmitted, but is NOT ever used. */</span><br> ra_uint_t consolePort;<br> ra_string_t executable;<br> ra_string_t arguments;<br> ra_string_t location;<br> ra_array_t environment;<br> ra_array_t agents;<br> }launch_process; /* LAUNCH_PROCESS*/<br></pre><br><pre> struct {<br> ra_uint_t context;<br> ra_uint_t processId;<br> ra_string_t agent;<br><span style="color: red;"> <span style="color: black;">ra_uint_t ip;</span></span><span style="color: black;"> <span style="color: rgb(51, 51, 255);">/* This value is transmitted, but is not ever used by the NEW AC (see below). */</span></span><br> ra_uint_t port;<br> }start_monitor_remote; /* START_MONITOR_REMOTE */</pre><br><br><div style="margin-left: 40px;"><span style="font-weight: bold;">ARM/CRM/PU:<br></span>Recommendation: Wait for stage 4.<br><span style="font-weight: bold;"><br>launch_process->consoleIP</span>:<br>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. <br>Recommendation: Value is not used, no change required.<br><br><span style="font-weight: bold;">start_monitor_remote->ip</span>:<br><span style="font-style: italic;">hcjbnd.c</span>:<br>- >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. <br>- The only other references to start_monitor_remote are fields unrelated to IPv6. No rewrites required.<br><br><span style="font-style: italic;">JvmpiWriter.c</span>:<br>- Both references are RA_START_MONITORING_AGENT_REMOTE only.<br><br><span style="font-style: italic;">hcthread.c</span>:<br>- RA_START_MONITORING_AGENT_REMOTE only.<br><br><span style="font-style: italic;">RACSupport.c (CompSupport)</span>:<br>- Reading from buffer, writing to buffer, and translation, only. No functional use here.<br><br><span style="font-style: italic;">RAComm.c (RACommon)</span>:<br>- Reading from buffer, writing to buffer, and translation, only. No functional use here.<br><br><span style="font-style: italic;">TPTPClientCompTL</span>:<br>- IP address fields not used, no rewrite required.<br><br>Recommendation: No rewrites required.<br></div><br><br><br><big><span style="text-decoration: underline;">Old Hyades AC Code / Agent/Client Compatibility Layer Code</span></big><br><br><br><span style="font-weight: bold; text-decoration: underline;">Client CTL</span><br><br><span style="font-weight: bold;">tptp_int32 startTransportListener(tptp_object* tlo)</span><br>- >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.<br><br><br><span style="font-weight: bold;">RACClientSuport.c</span>:<br><br><span style="font-weight: bold;">int getClientIP(client_connection_block_t* ccb, unsigned char *buffer, int *length)</span><br>- Retrieves the address of the peer that is connected to the AC on the ccb.<br>- If the ccb is a native socket, then it calls getPeerName (which returns in 4 byte format) and stores it in buffer.<br>- If the ccb is a java socket, then it looks like it gets the 4-byte or 16 byte formats.<br><br>o >Connect2Ac.c - startProcess(...) - calls getClientIP(), then calls >openClientDataSocket() which returns a SOCKET, which is used from >hereon.<br>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.<br>o >RACmdHandlers.c - handleStartMonitoring(...), . called by >processMessage(). calls GetClientIP(), passes it directly into >openClientDataSocket.<br><span style="color: red;"></span><br>Recommendation: When openClientDataSocket is rewritten, rewrite the above with calls to the new IPv4/IPv6 agnostic code.<br><br><br><br><span style="font-weight: bold;">Connect2AC.c</span>:<br><br><span style="font-weight: bold;">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)</span>:<br><br>- remoteConsoleIP arguments needs to be rewritten.<span style="font-weight: bold;"> </span>HOWEVER, this function doesn't use the value for anything, or touch it at all. So no change here.<br><br>- >calls getClientIP() followed by openClientDataSocket(). The value >is then passed into openClientDataSocket(). The value is not used after >this.<br><br><span style="font-weight: bold;"></span>o >startProcess is called only by BOOL handleLaunchProcess( >client_connection_block_t* ccb, ra_command_t* command ) in >RACmdHandlers.c<br><br>Recommendation: Rewrite the >getClientIP/openClientDataSocket() call to use struct >sockaddr_storage* equivalent. Leave the remoteConsoleIP param >alone (for now). <br><br><br style="color: black;"><span style="color: black; font-weight: bold;">SOCKET openClientDataSocket(tptp_int32 ip, tptp_int32 port)</span><br>- called only by handleLaunchProcess and handleStartMonitoring, above.<br>- ONLY calls connectToTCPServer(ip, (unsigned short) port, &sock);<br style="color: black;">- Recommendation: When connectToTCPServer is rewritten, rewrite this.<br><br><br><span style="font-weight: bold;">tptp_int32 >translateAndForwardPeerRequestMonitor( tl_state_data_t* >stateData, client_connection_block_t* ccb, tptp_int32 context, > tptp_string* peerHost,</span><br style="font-weight: bold;"><span style="font-weight: bold;">tptp_string* peerPort, >tptp_string* peerAgentName, > tptp_string* peerAgentPID, > tptp_string* srcAgentName, >tptp_string* srcAgentPID )</span><br>- peerHost is a standard dots and numbers string. No changes to function signature required.<br><br>Recommendation: Wait for stage 4. IPv4Mize any functions that this function uses.<br><br><br><span style="font-weight: bold; text-decoration: underline;">Native File Server</span><br><br><br><span style="font-weight: bold;">THREAD_USER_FUNC_RET_TYPE startNativeFileServer(LPVOID args)</span><br><br>- 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.<br>- convertIPAddressStringToUlong is used in processServerReachCmd(). <br><br><br><span style="font-weight: bold; text-decoration: underline;">RASocket</span><br><br>RASocket exports the following functions, used by other projects:<br><br><span style="font-weight: bold;">ra_connectToTCPServer (hcjbnd.c, java_profiler, hcthread.c)</span><br>- >Note: The above code only calls this method on receiving >"RA_START_MONITORING_AGENT_REMOTE". The New AC ACTL does not ever send >this.<br>- Recommendation: Mark as IPv4 only, do not port.<br><br><span style="font-weight: bold;">int ra_writeToSocket(SOCKET fd, char *buffer, ra_uint_t byteCount) (RADataTransfer.c)</span><br>o called only in ra_writeMessageBlock(...)<br>o used only in hcjbnd.c, java_profiler, perfmon, hcthread.<br>o The code itself is a simple send(...) on a socket.<br>- Recommendation: Does not need to be be rewritten.<br><br><span style="font-weight: bold;">ra_getLocalIPAddress (not called)</span><br><br><br><span style="font-weight: bold;">ra_getLocalIPAddresses (java_profiler)</span><br>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)<br>Recommendation: >Rewrite ra_getLocalIPAddresses to return sockaddr_storage, and rewrite >printIPAddressAttribute to use this new struct.<br><br><span style="font-weight: bold;">- void ra_closeSocket(SOCKET sockfd) (hcjbnd.c, java_profiler, hcthread.c)</span><br>- The code itself is a simple shutdown on a socket. No changes.<br><br><span style="font-weight: bold;">- ra_getLocalHostName (java_profiler)</span><br>o >called by printHostNameAttribtue() (where it is converted to a >string... same conversion method as ra_getLocalIPAddresses above)<br>- Does not need to be rewritten. Is not IPv6 specific.<br><br><span style="font-weight: bold;">ra_win32InitializeSockets</span><br>- Code is not IPv6 specific. No rewrites needed.<br><br><span style="font-weight: bold;">RASocket >exports the following functions which are not referenced outside of >RASocket, and are not called within RASocket itself (they're unused)</span>:<br>- ra_createBoundUDPServer (RASocket only)<br>- ra_createTCPServer (RASocket only)<br>- ra_getFormattedLocalIPAddress (RASocket only)<br><br><br><br><br><br><br><big><span style="text-decoration: underline;">GetAddress Revealed Problems (All Hyades, All Stage 4)</span></big><br><br>Note:<br>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.<br><br>This reveals problems in:<br><span style="font-weight: bold;">requestMonitorThroughPeer0p of RemoteComponentSkeleton:</span><br><br><span style="font-style: italic;">public void requestMonitorThroughPeer_p(InetAddress addr, long port, String agentUUID, long timeout)</span><br>- requestMonitorThroughPeer0p(addr.getAddress(), port, agentUUID);<br>- private native void requestMonitorThroughPeer0p(byte[] addr, long port, String agentUUID);<br>- >Java_org_eclipse_hyades_internal_execution_remote_RemoteComponentSkeleton_requestMonitorThroughPeer0p___3BJLjava_lang_String_2(JNIEnv >*env, jobject obj, jbyteArray ipaddr, jlong port, jstring agentUUID)<br><br>- Create a <span style="font-style: italic;">ra_ipaddr_t addr</span>, store the FULL address in there (however many bytes it is given), calls <span style="font-style: italic;">ra_requestPeerMonitor2_p</span>.<br>- >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.<br><br><span style="font-style: italic;">public void requestMonitorThroughPeer_p(InetAddress addr, long port, long pid, String agentName, long timeout) {</span><br>- requestMonitorThroughPeer0p(addr.getAddress(), port, pid, agentName);<br>- native void requestMonitorThroughPeer0p(byte[] addr, long port, long pid, String agentName);<br>- >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)<br>- As above, except calls <span style="font-style: italic;">ra_requestPeerMonitor_p</span> instead, which itself uses agent_request_monitor and either of those two tags depending on circumstance.<br><br>Recommendation: Neither of these technically need to change, as long as the parsing side is handling them properly.<br><br><br style="color: red;"><span style="font-weight: bold; color: black;">StartMonitoringRemoteAgentCommand: setInetAddress(..)</span><br>SMRAC is sent by startMonitoring() of AgentImpl.<br>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.<br style="color: black;"><br>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. <br><br><span style="font-weight: bold;">MonitorPeerRequestCommand: getPeerNode(). getTargetNode().</span><br>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. <br><br>Recommendation: Stage 4: Same as SMRAC.<br><br><span style="font-weight: bold;">Message: public static int writeRAInetAddressToBuffer(byte[] buffer, int offset, RAInetAddress addr).</span><br>- Nothing calls it. Deprecate?<br><br><span style="font-weight: bold;">Console: public void run { }</span><br>- The Console class is used by the LaunchProcessCommand, and by Process/ProcessImpl. <br>- >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.<br>- run() method then calls >determineServerReach() of IFileManagerExtended, which takes an >InetAddress. However, DetermineServerReach sends a String so it is IPv6 >compatible.<br>- LaunchProcessCommand reads the console and writes the console value as per it's Hyades message.<br>- The IP address of Console is ONLY used by LaunchProcessCommand, and no one uses that value from LaunchProcessCommand.<br>- >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). <br><br>Recommendation: Leave as is.<br><br><span style="font-weight: bold;">DataChannelImpl: hc_flushDCBufferToSocket</span><br><span style="color: red;"></span>- Unused.<br><span style="color: red;"></span><br></body></html>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"><title>IPv6 Design Review</title></head> <body><div style="text-align: center;"><span style="font-weight: bold; text-decoration: underline;">IPv6 Design Review</span><br></div><span style="font-weight: bold;"></span><br><br><big><span style="text-decoration: underline;">IPv4 -> IPv6 Patterns</span></big><br><br>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.<br><br>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 *.<br><br>With the above being the case, the following utility functions are required to implement the AC functionality currently in use.<br><br>- We need a function that converts standardized address -> hostname code, which will take the address in either form and return a name (See convertAddrToHostname(...) )<br>- 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(...) )<br><br>- 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(...) )<br>- We need a function that gets the standarized address(es) for any given hostname/ip address. (See convertHostnameToAddrs(...))<br>- We need a function that gets the standardized address(es) for a local host. (See getLocalHostAddresses(...))<br><br>- We need a function that determines whether a standardized address is a local host address (See isAddrLocal(...) ).<br>- We need a function that compares (binary comparison) standardizes addresses with each other (See compareAddresses(...) )<br><br><span style="color: black;">- We need a function that converts the standardized address into its 4 (IPv4) or 16 (IPv6) byte representation, and vice versa.</span> (See getByteFormatFromSockAddr() and getSockAddrFromByteFormat() )<br><br>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.<br><span style="color: rgb(51, 0, 153);"></span><span style="color: rgb(51, 51, 255);"></span><br><big><span style="text-decoration: underline;">Central Guidelines</span></big><br><br><span style="font-weight: bold;">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.</span><br><br>- 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.<br><span style="color: black;"><br>- 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, </span><span style="font-weight: bold; color: black;">getSocketIPString</span><span style="color: black;"> is called by the peer monitoring method <span style="font-style: italic;">getPeerConnectionInfo</span>. Create a new method called <span style="font-weight: bold;">getSocketIPStringIPv4M(),</span> with the same contents as the original, and replace any references in getPeerConnectionInfo with the new IPv4 name.<span style="font-weight: bold;"> At the end of IPv4 function name </span></span><span style="font-weight: bold; color: black;">should be IPv4M, to allow us to track them</span><span style="color: black;">. </span><br style="color: rgb(51, 0, 153);"><span style="color: rgb(255, 102, 102);"></span><br><span style="color: black;">- Reserve porting the request peer monitoring functionality until stage 4. </span><br style="color: red;"><span style="color: black;">- 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</span>.<br><br>- Use the new 'getTheSocket' method which I have provided in the example file. <br>- 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.<br>- Fix connectToTCPServer so that it takes the standardized address, as above <span style="font-style: italic;">(I've written a replacement for this method, either 'connectToHostWithAddr' or 'connectToHostWithHostname', depending on the context, usually the former)</span><br><br>- Fix all functions that directly or indirectly pass the 4-byte IP address into connectToTCPServer with the struct sockaddr_storage * code equivalent.<br>- Having changed the method signatures of the above functions, fix any calling methods of these functions, ad infinitium.<br><br>- 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 */<br><span style="color: black;"></span><span style="color: rgb(51, 0, 153);"></span><br><span style="color: rgb(51, 0, 153);"></span>- Lower Priority: May want to comment out, the RAInetAddress java code.<br>- See function level recommendations below, for remaining functions.<br><br><br><br><br><big><span style="text-decoration: underline;">Intel / IBM Dependencies</span></big><br><br><span style="font-weight: bold;">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.</span><br><br><span style="font-weight: bold;">Stage 2</span>:<br>- 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.<br>- 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.<br>- Once Intel's stage 2 code is complete, a patch should be sent to IBM that includes the changes.<br>- 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.<br>- Once complete, IBM will produce a patch that should be a working, compileable AC, but with host access and request peer monitoring functionality disabled.<br>- From here, we can pass to stage 3.<br><br><span style="font-weight: bold;">Stage 3+</span>:<br>- After Stage 2, we'll manage dependencies differently.<br><br><br><br><big><span style="text-decoration: underline;">New AC Code Methods where IPv4-only code is used</span></big><br><br><span style="font-weight: bold;">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.</span> <span style="font-weight: bold;">In many cases, these functions can merely be replaced with the updated socket code equivalent.</span><br><br><span style="font-weight: bold; text-decoration: underline;">AgentController.c</span>:<br><br><span style="font-weight: bold;">unsigned int parsePeerAttachAddress(char* str)</span>:<br>- Takes a dots and numbers IP addresse and returns it in 4 byte format.<br><br>Called by:<br>- parseAndProcessParameters(), which is called by main.<br>- Stored in <br> cm->peerInfo.usePeerAttachAddress = TRUE;<br> cm->peerInfo.peerAttachAddress = parsePeerAttachAddress(arg);<br><br>- See also, PeerAttachInfo_t, below.<br><br><span style="color: black;">Recommendation: Leave this for stage 4. </span>As long as the consumer doesn't use the two peer monitoring command line switches, this should be fine.<br><br><br><big><small><span style="font-weight: bold; text-decoration: underline;">ConnectionImpl.cpp</span></small>:</big><br><br><span style="font-weight: bold;">ConnectionImpl::getLocalIPAddress()</span> (not used)<br><br><span style="font-weight: bold;">ConnectionImpl::getIPAddress()</span> (used by itself)<br>- Returns IP address in 4-byte format (unsigned long).<br>- Used only as the first parameter to connectToTCPServer<br>- 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.<br><br><br><br><span style="font-weight: bold; text-decoration: underline;">TCPDataServer.cpp</span>:<br><br><span style="font-weight: bold;">TCPDataServer::getLocalIPAddress()</span> (used by itself, it would seem)<br>- Returns IP address in 4-byte format (unsigned long).<br>- Used only as the first parameter to connectToTCPServer<br>- Recommendation: When connectToTCPServer is fixed, this function should return the appropriate IPv6 struct.<br><br><span style="font-weight: bold; text-decoration: underline;">TPTP_INetAddress.cpp</span><big>:</big><br><br><span style="font-weight: bold;">TPTP_INetAddress::getAddress</span> (unused, however part of native client api... may be used by consuming product)<br>- Is merely a host name resolve.<br>- Input: Hostname (char *)<br>- Output: char * (dots and numbers IP address, string)<br>- Recommendation: Is self-contained, we need only to replace this with IPv6-based host name resolution.<br><br><br><big style="text-decoration: underline;"><small><span style="font-weight: bold;">TPTPCBE.cpp</span></small></big><big style="text-decoration: underline;">:</big><br style="text-decoration: underline;"><br><span style="font-weight: bold;">createSourceComponentID</span> (used, called by itself, merely prints the hostname)<br>- The offending code in this method only gets the local hostname (char *) and sprintfs it into a string. <br>- Recommendation: Self-contained, easily replaced.<br><br><br><big><small><span style="text-decoration: underline; font-weight: bold;">SocketListener.c</span></small>:</big><br><br><span style="font-weight: bold;">doListening</span> <br>- Rewrite the function using the new getTheSocket(...) call. bindAndListen call no longer needed. <br>- Code must now listen on multiple server sockets.<br>- Recommendation: Rewrite using the new getTheSocket(...) method, and the code must now listen on multiple server sockets.<br><br><big><small><span style="font-weight: bold; text-decoration: underline;">TransportOSCalls_win.c</span></small>:</big><br><br><span style="font-weight: bold;">printSocketRequest</span> (not used - may be for debug purposes)<br><br style="color: rgb(51, 0, 153);"><span style="font-weight: bold; color: rgb(18, 28, 18);">convertIPAddressStringToArray</span><br style="color: rgb(18, 28, 18);"><span style="color: rgb(18, 28, 18);">- input is an IP address in string form, output is 4 unsigned characters</span><br style="color: rgb(18, 28, 18);"><span style="color: rgb(18, 28, 18);"> o in CCTLServer.c serveRequests() - Grabs's the peer's IP in string form, calls this method, then passes it into tptp_checkHost.</span><br style="color: rgb(18, 28, 18);"><span style="color: rgb(18, 28, 18);"> 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.</span><br style="color: rgb(18, 28, 18);"><br style="color: rgb(18, 28, 18);"><span style="color: rgb(18, 28, 18);"> 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.</span><br style="color: rgb(18, 28, 18);"><span style="color: rgb(18, 28, 18);"><br>Recommend leaving this one alone for now, until the fourth stage. </span>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.<br style="color: rgb(18, 28, 18);"><span style="color: rgb(18, 28, 18);"></span><br> <br><span style="font-weight: bold;">convertIPAddressUlongToString</span> <br>- Converts the four byte IP format to a 'dots and numbers' string<br> o Used only by getPeerConnectionInfo in ClientCTL.c<br> o Outputted as 'dots and numbers' to host portion: <transportType>TPTP_CCTL</transportType><host>%s</host><port>%d</port><br> o This call is only made when cctlData->usePeerAttachPort is called. It is called on cctlData->peerAttachAddress.<br><br><span style="color: red;"></span>Recommendation: Because this is peer monitoring specific, recommend leaving it to stage 4. IPv4M it.<br><br><span style="font-weight: bold;">extractAddressFromSockAddr (not used)</span><br><br><br><br><big><small><span style="font-weight: bold; text-decoration: underline;">TransportOSCalls_linux.c (as above)</span></small>:</big><br><br>printSocketRequest (not used - may be for debug purposes)<br>convertIPAddressStringToArray<br>convertIPAddressUlongToString<br>extractAddressFromSockAddr (not used)<br><span style="color: black;">- Same as above.</span><br style="color: black;"><br><br><big><small><span style="font-weight: bold; text-decoration: underline;">TransportSupport</span></small>:</big><br><br>tptp_getLocalIPAddress (not used)<br><br><span style="font-weight: bold;">tptp_getLocalIPAddresses</span><br>- Stores the local IP addresses in 4 byte form (null terminated char* list format, inside a tptp_IPAddresses_t )<br> o Used by isLocalHost() and tptp_checkHost(), below.<br><span style="color: black;">- Recommendation: Because it's only used by the checkHost functionality, leave as is in stage 2.</span> IPv4M it.<br><br><span style="font-weight: bold;">isLocalHost</span><br>- Input is host name, output is either true or false.<br>- Called only by tptp_checkHost<br>- Recommendation: Leave as in stage 2 (IPv4M it.). In stage 4, rewrite: Self contained, rewrite to use IPv6 compliant code.<br> <br><span style="font-weight: bold;">tptp_checkHost </span><br>- Input is network_list_t, and an address in four byte format.<br> o Used by serverRequests() of CCTLServer.c <br>- Recommendation: Leave as in stage 2.<br style="color: black;"><span style="color: red;"><br><br><br><span style="color: black; font-style: italic;"><span style="text-decoration: underline;">Stage 4 Work (skip this section for Stage 2)</span>:</span><br><br><span style="color: black;">The structs related to the code are:<br> </span><br style="color: black;"><span style="color: black;">typedef struct {</span><br style="color: black;"><span style="color: black;"> network_list_node_t *head;</span><br style="color: black;"><span style="color: black;"> network_list_node_t *tail;</span><br style="color: black;"><span style="color: black;">} network_list_t;</span><br style="color: black;"><br style="color: black;"><br style="color: black;"><span style="color: black;">Stored in:</span><br style="color: black;"><span style="color: black;">{</span><br><span style="color: black;"> (...)</span><br style="color: black;"><span style="color: black;"> BOOL securityEnabled;</span><br style="color: black;"><span style="color: black;"> tptp_uint32 securedPort;</span><br style="color: black;"><span style="color: black;"> tptp_string *keystore;</span><br style="color: black;"><span style="color: black;"> tptp_string *keystorePassword;</span><br style="color: black;"><span style="color: black;"> network_list_t *network_list;</span><br style="color: black;"><span style="color: black;"> tptp_string *users;</span><br style="color: black;"><span style="color: black;">} cctl_state_data_t;</span><br style="color: black;"><br style="color: black;"><span style="color: black;">Unsupported, nothing will generate these entries: TPTP_HW_UNKNOWN, TPTP_HW_KNOWN, TPTP_HW_MAX_VALUE, </span><br style="color: black;"><span style="color: black;"></span><br style="color: black;"><span style="color: black;"><span style="font-style: italic;">TransportSupport.c</span>:</span><br style="color: black;"><br style="color: black;"><span style="color: black;">BOOL tptp_checkHost(network_list_t *list, unsigned char *address);</span><br style="color: black;"><br style="color: black;"><span style="color: black;">- Called only in THREAD_USER_FUNC_RET_TYPE serveRequests(LPVOID args)</span><br style="color: black;"><span style="color: black;"> o Gets the string host name of the peer connected to it</span><br style="color: black;"><span style="color: black;"> o Converts that to 4-byte format</span><br style="color: black;"><span style="color: black;"> o calls tptp_checkHost on that 4 byte format.</span><br style="color: black;"><span style="color: black;"> o Note: the tptp_checkHost called can be easily commented out.</span><br style="color: black;"><br style="color: black;"><span style="color: black;">- address is address in 4-byte format.</span><br style="color: black;"><br style="color: black;"><span style="color: black;">- begins at list->head</span><br style="color: black;"><span style="color: black;">- pulls a network_t out of current->entry</span><br style="color: black;"><span style="color: black;">- entry->wildcard = TPTP_HW_ALL, TPTP_HW_LOCAL, TPTP_HW_UNKNOWN, TPTP_HW_KNOWN, TPTP_HW_NET, TPTP_HW_NAMED</span><br style="color: black;"><br style="color: black;"><span style="color: black;">case TPTP_HW_ALL: </span><br style="color: black;"><span style="color: black;">- if allow return true, otherwise return false. Doesn't need to be rewritten.</span><br style="color: black;"><br style="color: black;"><span style="color: black;">case TPTP_HW_LOCAL: </span><br style="color: black;"><span style="color: black;">- needs to be rewriten</span><br style="color: black;"><span style="color: black;">- 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.</span><br style="color: black;"><br style="color: black;"><span style="color: black;">case TPTP_HW_NET:</span><br style="color: black;"><span style="color: black;">- needs to be rewritten</span><br style="color: black;"><span style="color: black;">- 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.</span><br style="color: black;"><span style="color: black;">- resolve the address into string format, and store the alternative names as well</span><br style="color: black;"><span style="color: black;">- compare the named ip listed in the file with the one we now have</span><br style="color: black;"><span style="color: black;">- compare aliases as well.</span><br style="color: black;"><br style="color: black;"><br style="color: black;"><span style="color: black;">The above constants are referenced in the following places:</span><br style="color: black;"><br style="color: black;"><span style="color: black;">- TPTP_HW_ALL (parseHostList in TPTPUtil.c)</span><br style="color: black;"><span style="color: black;">- TPTP_HW_LOCAL (parseHostList in TPTPUtil.c)</span><br style="color: black;"><span style="color: black;">- TPTP_HW_NET (tptp_addNetwork, parseHostList in TPTPUtil.cpp)</span><br style="color: black;"><span style="color: black;">- TPTP_HW_NAMED (tptp_addNetwork, parseHostList in TPTPUtil.cpp)</span><br style="color: black;"><span style="color: black;"></span><br style="color: black;"><br><br style="color: black;"><span style="color: black;"><span style="font-style: italic;">TPTPUtil.cpp</span>:</span><span style="color: black;"></span><br style="color: black;"><br style="color: black;"><span style="color: black; font-style: italic;">void tptp_addNetwork(network_list_t *list, int allow, tptp_host_wildcard_t wildcard, char *name, char *mask)</span><br style="color: black;"><span style="color: black;">- called by parseHostList(...)</span><br style="color: black;"><br style="color: black;"><span style="color: black;">network_t *network;</span><br style="color: black;"><br style="color: black;"><span style="color: black;">network->allow=allow; // This handles the allow field.</span><br style="color: black;"><span style="color: black;">network->wildcard=wildcard; // This handles TPTP_HW_ALL and TPTP_HW_LOCAL</span><br style="color: black;"><br style="color: black;"><span style="color: black;">if wildcard is TPTP_HW_NAMED:</span><br style="color: black;"><span style="color: black;">- This needs to be rewritten for IPv6.</span><br style="color: black;"><span style="color: black;">- 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.</span><br style="color: black;"><span style="color: black;">- ELSE, if a named host is specified here, then store that named host in network->hostname</span><br style="color: black;"><br style="color: black;"><br style="color: black;"><span style="color: black;">if wildcard is TPTP_HW_NET:</span><br style="color: black;"><span style="color: black;">- This needs to be rewritten for IPv6</span><br style="color: black;"><span style="color: black;">- network->net is 4 byte format IP address. </span><br style="color: black;"><span style="color: black;">- network->mask is 4 byte format IP address.</span><br style="color: black;"><span style="color: black;">- This code converts a text string into IPv4 IP format.</span><br style="color: black;"><span style="color: black;">- It converts net and mask to IPv4 4 byte format.</span><br style="color: black;"><br style="color: black;"><br style="color: black;"><span style="color: black; font-style: italic;">int parseHostList(const char *initString, network_list_t **nList):</span><br style="color: black;"><span style="color: black;">- Called by 'createTransportListener' of ClientCTL.c.</span><br style="color: black;"><br style="color: black;"><span style="color: black;">No IPv6 changes required.</span><br style="color: black;"><br style="color: black;"><span style="color: black;">(network_list_t is malloc here. It's entirely possible for it to be NULL.)</span><br style="color: black;"><br style="color: black;"><span style="color: black;">Under <Hosts configuration="default">....</Hosts>, you will see either <Allow host=""/> or <Deny host=""/> tags here.</span><br style="color: black;"><br style="color: black;"><span style="color: black;">You can specify, 'host', 'net', or 'mask' as the above attributes.</span><br style="color: black;"><br style="color: black;"><span style="color: black;">if host = 'ALL' then it calls tptp_addNetwork(*nList, 0, TPTP_HW_ALL, NULL, NULL);</span><br style="color: black;"><span style="color: black;">if host = 'LOCAL' then it calls tptp_addNetwork(*nList, 0, TPTP_HW_LOCAL, NULL, NULL);</span><br style="color: black;"><span style="color: black;">else host exists, but isn't either of the above, then: tptp_addNetwork(*nList, 0, TPTP_HW_NAMED, host, NULL);</span><br style="color: black;"><span style="color: black;">- Adds it to nList, which is a 'network_list_t'. The second value is either allow or deny.</span><br style="color: black;"><br style="color: black;"><span style="color: black;">However, if host is not specified, then either net or mask is specified, and it calls:</span><br style="color: black;"><span style="color: black;">- tptp_addNetwork(*nList, 0, TPTP_HW_NET, net, mask);</span><br style="color: black;"><br style="color: black;"><br><br><br></span><big><small><span style="font-weight: bold; text-decoration: underline;">TransportSupportSocket</span></small>:</big><br><br><span style="font-weight: bold;">getSocketPort (not used)</span><br><br><span style="font-weight: bold;">getHostInfo</span><br>Returns the IP address (4 byte format) of the given hostname.<br>Used by:<br>- unsigned long ConnectionImpl::getLocalIPAddress()<br>- unsigned long ConnectionImpl::getIPAddress(char* hostname) {<br>- unsigned long TCPDataServer::getLocalIPAddress()<br>- int getSocketIPString( SOCKET sock, char** ipAddrStr )<br><br>- Recommendation: Replace with equivalent struct sockaddr_storage * function. <br><br><span style="font-weight: bold;">convertIPAddressStringToUlong</span> <br>- Converts 'dots and numbers' IP address to 4 byte format.<br><span style="color: red;"><span style="color: black;"><br>Used by:</span><br style="color: black;"><span style="color: black;">- tptp_int32 createSocketPeerConnection( server_block_t* pServerData, tptp_string* sourceConnectionInfo, tptp_uint32* connectionID ) of SocketListener.c</span><br><span style="color: black;">o parses the <host></host> tag of sourceConnectionInfo, calls convertIPAddressStringToULong, passes the address to connectToTCPServer. </span><br><br style="color: black;"><span style="color: black;">- tptp_int32 createPeerConnection( tptp_object* tlo, tptp_string* sourceConnectionInfo, tptp_uint32* connectionID ) of ClientCTL.c</span><br style="color: black;"><span style="color: black;"></span></span><span style="color: red;"><span style="color: black;">o parses the <host></host> tag of sourceConnectionInfo, calls convertIPAddressStringToULong, passes the address to connectToTCPServer. </span><br><br></span><span style="color: red;"><span style="color: black;">- int processServerReachCmd(fs_connection_block_t* con) of nativeFileServer.c</span><br style="color: black;"></span>o Reads an int from the connection (which it presumes to be the IP address), and calls connectToTCPServer() with that address.<br><br>- Recommendation: Replace with equivalent struct sockaddr_storage * function. Also, create an IPv4M'ed copy for reference by the peer monitoring code.<br><span style="color: red;"><span style="color: black;"><br></span></span><br><br><span style="font-weight: bold;">getSocketIPString</span> <br>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)<br>o createSocketPeerConnection in SocketListener.c (used to place IP into an xml tag)<br>o createPeerConnection in ClientCTL.c. (used to place IP into an xml tag)<br>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 )<br>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 )<br>- Recommendation: Replace with equivalent struct sockaddr_storage * function. Create an IPv4M'ed copy for reference by the peer monitoring code.<br><span style="font-weight: bold;"><br>getPeerIPString</span><br>- Given a socket, store the dots and numbers format for the person we're connected to.<br>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.<br>- Recommendation: Replace with equivalent struct sockaddr_storage * function.<br><br><span style="font-weight: bold;">getTargetHostInfo</span><br>- Given a host name string, return hostent.<br>o Used only by unsigned long ConnectionImpl::getIPAddress(char* hostname). Here it's used only to convert the string to the 4-byte format <br>o When getIPAddress is rewritten, dump this method.<br>- Recommendaiton: This function is entirely IPv4, and should be removed. Rewrite getIPAddress to use sockaddr_storage *<br><br><span style="font-weight: bold;">getPeerName</span><br><span style="color: black;">- Given a socket, store the peer of the socket in 4 byte format. </span><br>o Used by int getClientIP(client_connection_block_t* ccb, unsigned char *buffer, int *length) of RACClientSupport.c. <br>o Called by getClientIP, the socket is read from ccb, and the four-byte address is stored in buffer.<br><br><br><span style="font-weight: bold;">connectToTCPServer</span> <br>- Given an IP address in 4 byte format, and a portnumber, return a SOCKET to that connection.<br>- 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.<br><span style="font-style: italic;"><br>Used by</span>:<br>o int ConnectionImpl::connect(INode* node, int port)<br>o int ConnectionImpl::connect(class INode* node, ConnectionInfo* connInfo)<br>o int ConnectionImpl::createDataConnection(int direction, int flags)<br><br>o void TCPDataServer::connect()<br><br>o tptp_int32 createSocketPeerConnection( server_block_t* pServerData, tptp_string* sourceConnectionInfo, tptp_uint32* connectionID ); in SocketListener.c<br>o tptp_int32 createPeerConnection( tptp_object* tlo, tptp_string* sourceConnectionInfo, tptp_uint32* connectionID ) in ClientCTL<br>o int processServerReachCmd(fs_connection_block_t* con) in nativeFileServer.c<br><br>o SOCKET openClientDataSocket(tptp_int32 ip, tptp_int32 port) in RACClientSupport.c<br><br><br><br><big><span style="text-decoration: underline;">Native Code Structs that reference IP Addresses</span></big><span style="text-decoration: underline;"></span><br><br><span style="font-weight: bold;">TransportSupport.c</span>:<br><br>typedef struct {<br> unsigned short addressLength;<br> unsigned char *addresses; <br>} <span style="font-weight: bold;">tptp_IPAddresses_t</span>;<br><br>- Referenced ONLY in TransportSupport.c, doesn't leave the C file.<br>- Used by isLocalHost() and tptp_checkHost().<br>- Data is stored in it by tptp_getLocalIPAddresses(...)<br><br><span style="color: black;">Recommendation: Leave as is for Stage 2.</span><br><br><br><span style="font-weight: bold;">MsgPipeline.h</span>:<br><br>/* Structure used to override peer monitoring defaults */<br>typedef struct PeerAttachInfo_tag<br>{<br> int usePeerAttachPort;<br> int usePeerAttachAddress; // Not an IP Address<br> int peerAttachPort;<br><span style="color: black;"> unsigned int peerAttachAddress; // IP address, 4 byte format.</span><br>} <span style="font-weight: bold;">PeerAttachInfo_t</span>;<br><br>Generated only by parseAndProcessParameters(...), which parses the command line.<br>Stored in ConnectionManager_t. <br><br>- passed into setPeerAttachInfo (which copies the together the ConnectionManager_t->peerInfo data structure and the cctl_state_data_t of CCTL.)<br><br><span style="font-style: italic;">Call stack</span>:<br>return tl->setPeerAttachInfo( &tl->tlo, &cm->peerInfo );<br>tptp_int32 connectionManager_initializePeerConnectionTransport( ConnectionManager_t* cm, char* peerConnectionTransport );<br>tptp_int32 configurationManager_readConfigFile( ConfigurationManager_t* cm );<br>main(...) in AgentController.<br><br><br>Recommend: Leave PeerAttachInfo_t and parseAndProcessParameters() for stage 4.<br><br><br><span style="font-weight: bold;">TPTPUtils.h</span>:<br><br>typedef struct {<br> int allow; /* Is this an Allow entry or a Deny? */<br> tptp_host_wildcard_t wildcard; /* Is this a range of addresses or an exact address? */<br> unsigned char net[4]; /* The network address information in network byte order. Note that this is<span style="color: rgb(0, 0, 102);"> <span style="font-weight: bold;">IPV4 specific</span></span> */<br> unsigned char mask[4]; /* the subnet mask information in network byte order. Note that this is<span style="font-weight: bold; color: rgb(0, 0, 102);"> IPV4 specific</span> */<br> char *hostname;<br>} <span style="font-weight: bold;">network_t</span>;<br><br>net/mask are used by:<br>- void tptp_addNetwork(network_list_t *list, int allow, tptp_host_wildcard_t wildcard, char *name, char *mask)<br>- int parseHostList(const char *initString, network_list_t **nList)<br>- BOOL tptp_checkHost(network_list_t *list, unsigned char *address).<br><br>- Recommend: Leave for stage 4.<br><br><span style="font-weight: bold;">RASocket</span>:<br><br>/* IPV4 and IPV6 ipaddress compatable structure */<br>typedef struct {<br> unsigned char addrLength;<br> unsigned char *addr;<br>} <span style="font-weight: bold;">ra_ipaddr_t</span>;<br>The above is used only by the peer monitoring code. RABinding.c/RABinding.h, and hcjbnd.c.<br><br>- Recommend: Leave for stage 4.<br><br><span style="color: red;"><span style="color: black;"><br></span></span><br><br>typedef struct {<br> unsigned short addressLength;<br> unsigned char *addresses; <br>} <span style="font-weight: bold;">ra_IPAddresses_t</span>;<br><br>produced only by short ra_getLocalIPAddresses(ra_IPAddresses_t *addr).<br>used by print.c of hcjbnd java_profiler: static unsigned short printIPAddressAttribute(ThreadPrivateStorage *tps, unsigned short current)<br>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)<br><br>- Recommend: Rewrite in stage 2.<br><br><br>typedef struct {<br>[...]<br> /* Peer monitoring related fields */<br> int usePeerAttachPort;<br> int usePeerAttachAddress; <span style="color: rgb(51, 51, 255);">// 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.</span><br> int peerAttachPort;<br><span style="color: black;"> unsigned int peerAttachAddress; <span style="color: rgb(51, 51, 255);">// IPv4 IP Address.. seems to double as a local IP address.</span></span><br><br> network_list_t *network_list;<br>[...]<br>} <span style="font-weight: bold;">cctl_state_data_t</span>; (defined in ClientCtl.h)<br><br>- Recommend: Leave for stage 4.<br><br><br><br><span style="font-weight: bold;">ra_command.t</span>:<br>- defined in RAComm.h of tptp/include/compatibility.<br>- defined in RATypes.h of src-native-new/src/transport/RACommon<br><br><pre> struct {<br> ra_uint_t context;<br> ra_uint_t processId;<br> ra_string_t agent;<br> ra_string_t node; <span style="color: rgb(51, 51, 255);">/* node->data is a 4 byte IP address */</span><br> ra_uint_t peerProcessId;<br> ra_string_t peerAgent;<br> ra_string_t peerNode; <span style="color: rgb(51, 51, 255);">/* peerNode->data is a 4 byte IP address */</span><br style="color: rgb(51, 51, 255);"> }agent_request_monitor, /* AGENT_REQUEST_ATTACH */<br> controller_request_monitor, /* CONTROLLER_REQUEST_MONITOR */<br> peer_unreachable; /* PEER_UNREACHABLE */<br></pre><br><pre> struct {<br> ra_uint_t context;<br><span style="color: red;"> <span style="color: black;">ra_uint_t consoleIP;</span></span> <span style="color: rgb(51, 102, 255);">/* This is transmitted, but is NOT ever used. */</span><br> ra_uint_t consolePort;<br> ra_string_t executable;<br> ra_string_t arguments;<br> ra_string_t location;<br> ra_array_t environment;<br> ra_array_t agents;<br> }launch_process; /* LAUNCH_PROCESS*/<br></pre><br><pre> struct {<br> ra_uint_t context;<br> ra_uint_t processId;<br> ra_string_t agent;<br><span style="color: red;"> <span style="color: black;">ra_uint_t ip;</span></span><span style="color: black;"> <span style="color: rgb(51, 51, 255);">/* This value is transmitted, but is not ever used by the NEW AC (see below). */</span></span><br> ra_uint_t port;<br> }start_monitor_remote; /* START_MONITOR_REMOTE */</pre><br><br><div style="margin-left: 40px;"><span style="font-weight: bold;">ARM/CRM/PU:<br></span>Recommendation: Wait for stage 4.<br><span style="font-weight: bold;"><br>launch_process->consoleIP</span>:<br>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. <br>Recommendation: Value is not used, no change required.<br><br><span style="font-weight: bold;">start_monitor_remote->ip</span>:<br><span style="font-style: italic;">hcjbnd.c</span>:<br>- 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. <br>- The only other references to start_monitor_remote are fields unrelated to IPv6. No rewrites required.<br><br><span style="font-style: italic;">JvmpiWriter.c</span>:<br>- Both references are RA_START_MONITORING_AGENT_REMOTE only.<br><br><span style="font-style: italic;">hcthread.c</span>:<br>- RA_START_MONITORING_AGENT_REMOTE only.<br><br><span style="font-style: italic;">RACSupport.c (CompSupport)</span>:<br>- Reading from buffer, writing to buffer, and translation, only. No functional use here.<br><br><span style="font-style: italic;">RAComm.c (RACommon)</span>:<br>- Reading from buffer, writing to buffer, and translation, only. No functional use here.<br><br><span style="font-style: italic;">TPTPClientCompTL</span>:<br>- IP address fields not used, no rewrite required.<br><br>Recommendation: No rewrites required.<br></div><br><br><br><big><span style="text-decoration: underline;">Old Hyades AC Code / Agent/Client Compatibility Layer Code</span></big><br><br><br><span style="font-weight: bold; text-decoration: underline;">Client CTL</span><br><br><span style="font-weight: bold;">tptp_int32 startTransportListener(tptp_object* tlo)</span><br>- 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.<br><br><br><span style="font-weight: bold;">RACClientSuport.c</span>:<br><br><span style="font-weight: bold;">int getClientIP(client_connection_block_t* ccb, unsigned char *buffer, int *length)</span><br>- Retrieves the address of the peer that is connected to the AC on the ccb.<br>- If the ccb is a native socket, then it calls getPeerName (which returns in 4 byte format) and stores it in buffer.<br>- If the ccb is a java socket, then it looks like it gets the 4-byte or 16 byte formats.<br><br>o Connect2Ac.c - startProcess(...) - calls getClientIP(), then calls openClientDataSocket() which returns a SOCKET, which is used from hereon.<br>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.<br>o RACmdHandlers.c - handleStartMonitoring(...), . called by processMessage(). calls GetClientIP(), passes it directly into openClientDataSocket.<br><span style="color: red;"></span><br>Recommendation: When openClientDataSocket is rewritten, rewrite the above with calls to the new IPv4/IPv6 agnostic code.<br><br><br><br><span style="font-weight: bold;">Connect2AC.c</span>:<br><br><span style="font-weight: bold;">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)</span>:<br><br>- remoteConsoleIP arguments needs to be rewritten.<span style="font-weight: bold;"> </span>HOWEVER, this function doesn't use the value for anything, or touch it at all. So no change here.<br><br>- calls getClientIP() followed by openClientDataSocket(). The value is then passed into openClientDataSocket(). The value is not used after this.<br><br><span style="font-weight: bold;"></span>o startProcess is called only by BOOL handleLaunchProcess( client_connection_block_t* ccb, ra_command_t* command ) in RACmdHandlers.c<br><br>Recommendation: Rewrite the getClientIP/openClientDataSocket() call to use struct sockaddr_storage* equivalent. Leave the remoteConsoleIP param alone (for now). <br><br><br style="color: black;"><span style="color: black; font-weight: bold;">SOCKET openClientDataSocket(tptp_int32 ip, tptp_int32 port)</span><br>- called only by handleLaunchProcess and handleStartMonitoring, above.<br>- ONLY calls connectToTCPServer(ip, (unsigned short) port, &sock);<br style="color: black;">- Recommendation: When connectToTCPServer is rewritten, rewrite this.<br><br><br><span style="font-weight: bold;">tptp_int32 translateAndForwardPeerRequestMonitor( tl_state_data_t* stateData, client_connection_block_t* ccb, tptp_int32 context, tptp_string* peerHost,</span><br style="font-weight: bold;"><span style="font-weight: bold;">tptp_string* peerPort, tptp_string* peerAgentName, tptp_string* peerAgentPID, tptp_string* srcAgentName, tptp_string* srcAgentPID )</span><br>- peerHost is a standard dots and numbers string. No changes to function signature required.<br><br>Recommendation: Wait for stage 4. IPv4Mize any functions that this function uses.<br><br><br><span style="font-weight: bold; text-decoration: underline;">Native File Server</span><br><br><br><span style="font-weight: bold;">THREAD_USER_FUNC_RET_TYPE startNativeFileServer(LPVOID args)</span><br><br>- 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.<br>- convertIPAddressStringToUlong is used in processServerReachCmd(). <br><br><br><span style="font-weight: bold; text-decoration: underline;">RASocket</span><br><br>RASocket exports the following functions, used by other projects:<br><br><span style="font-weight: bold;">ra_connectToTCPServer (hcjbnd.c, java_profiler, hcthread.c)</span><br>- Note: The above code only calls this method on receiving "RA_START_MONITORING_AGENT_REMOTE". The New AC ACTL does not ever send this.<br>- Recommendation: Mark as IPv4 only, do not port.<br><br><span style="font-weight: bold;">int ra_writeToSocket(SOCKET fd, char *buffer, ra_uint_t byteCount) (RADataTransfer.c)</span><br>o called only in ra_writeMessageBlock(...)<br>o used only in hcjbnd.c, java_profiler, perfmon, hcthread.<br>o The code itself is a simple send(...) on a socket.<br>- Recommendation: Does not need to be be rewritten.<br><br><span style="font-weight: bold;">ra_getLocalIPAddress (not called)</span><br><br><br><span style="font-weight: bold;">ra_getLocalIPAddresses (java_profiler)</span><br>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)<br>Recommendation: Rewrite ra_getLocalIPAddresses to return sockaddr_storage, and rewrite printIPAddressAttribute to use this new struct.<br><br><span style="font-weight: bold;">- void ra_closeSocket(SOCKET sockfd) (hcjbnd.c, java_profiler, hcthread.c)</span><br>- The code itself is a simple shutdown on a socket. No changes.<br><br><span style="font-weight: bold;">- ra_getLocalHostName (java_profiler)</span><br>o called by printHostNameAttribtue() (where it is converted to a string... same conversion method as ra_getLocalIPAddresses above)<br>- Does not need to be rewritten. Is not IPv6 specific.<br><br><span style="font-weight: bold;">ra_win32InitializeSockets</span><br>- Code is not IPv6 specific. No rewrites needed.<br><br><span style="font-weight: bold;">RASocket exports the following functions which are not referenced outside of RASocket, and are not called within RASocket itself (they're unused)</span>:<br>- ra_createBoundUDPServer (RASocket only)<br>- ra_createTCPServer (RASocket only)<br>- ra_getFormattedLocalIPAddress (RASocket only)<br><br><br><br><br><br><br><big><span style="text-decoration: underline;">GetAddress Revealed Problems (All Hyades, All Stage 4)</span></big><br><br>Note:<br>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.<br><br>This reveals problems in:<br><span style="font-weight: bold;">requestMonitorThroughPeer0p of RemoteComponentSkeleton:</span><br><br><span style="font-style: italic;">public void requestMonitorThroughPeer_p(InetAddress addr, long port, String agentUUID, long timeout)</span><br>- requestMonitorThroughPeer0p(addr.getAddress(), port, agentUUID);<br>- private native void requestMonitorThroughPeer0p(byte[] addr, long port, String agentUUID);<br>- Java_org_eclipse_hyades_internal_execution_remote_RemoteComponentSkeleton_requestMonitorThroughPeer0p___3BJLjava_lang_String_2(JNIEnv *env, jobject obj, jbyteArray ipaddr, jlong port, jstring agentUUID)<br><br>- Create a <span style="font-style: italic;">ra_ipaddr_t addr</span>, store the FULL address in there (however many bytes it is given), calls <span style="font-style: italic;">ra_requestPeerMonitor2_p</span>.<br>- 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.<br><br><span style="font-style: italic;">public void requestMonitorThroughPeer_p(InetAddress addr, long port, long pid, String agentName, long timeout) {</span><br>- requestMonitorThroughPeer0p(addr.getAddress(), port, pid, agentName);<br>- native void requestMonitorThroughPeer0p(byte[] addr, long port, long pid, String agentName);<br>- 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)<br>- As above, except calls <span style="font-style: italic;">ra_requestPeerMonitor_p</span> instead, which itself uses agent_request_monitor and either of those two tags depending on circumstance.<br><br>Recommendation: Neither of these technically need to change, as long as the parsing side is handling them properly.<br><br><br style="color: red;"><span style="font-weight: bold; color: black;">StartMonitoringRemoteAgentCommand: setInetAddress(..)</span><br>SMRAC is sent by startMonitoring() of AgentImpl.<br>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.<br style="color: black;"><br>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. <br><br><span style="font-weight: bold;">MonitorPeerRequestCommand: getPeerNode(). getTargetNode().</span><br>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. <br><br>Recommendation: Stage 4: Same as SMRAC.<br><br><span style="font-weight: bold;">Message: public static int writeRAInetAddressToBuffer(byte[] buffer, int offset, RAInetAddress addr).</span><br>- Nothing calls it. Deprecate?<br><br><span style="font-weight: bold;">Console: public void run { }</span><br>- The Console class is used by the LaunchProcessCommand, and by Process/ProcessImpl. <br>- 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.<br>- run() method then calls determineServerReach() of IFileManagerExtended, which takes an InetAddress. However, DetermineServerReach sends a String so it is IPv6 compatible.<br>- LaunchProcessCommand reads the console and writes the console value as per it's Hyades message.<br>- The IP address of Console is ONLY used by LaunchProcessCommand, and no one uses that value from LaunchProcessCommand.<br>- 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). <br><br>Recommendation: Leave as is.<br><br><span style="font-weight: bold;">DataChannelImpl: hc_flushDCBufferToSocket</span><br><span style="color: red;"></span>- Unused.<br><span style="color: red;"></span><br></body></html>
View Attachment As Raw
Actions:
View
Attachments on
bug 165409
:
80048
|
91219
|
91220
|
92067
|
96037
|
96378
| 96379 |
99618
|
99619
|
99622
|
99735