As of now, I'm using the below code to get DNS name of the given IPAddress. Instead of fetching it for each IPAddress in the network, I want to fetch all the DNS entries (IPAddress - HostName mapping) from the DNS Server in one go. Is it possible? If so, how to do it?
InetAddress addr = InetAddress.getByName(address);
dnsname = addr.getCanonicalHostName().trim();
From a public DNS server, there is no way to pull out all the data it holds. Enumerating all the IP addresses one by one is the only solution.
If you have a special relationship with the DNS server (for instance, it is managed by your employer), you may request from the DNS administrator a right to transfer the whole zone (the DNS request known as AXFR). They may authorize your IP address or gives you a TSIG key to authentify yourself.
Then, you will have to find a way to do a zone transfer (possibly with TSIG authentication) in Java. Using these keywords, I find some code and documentation. Use a code search engine like Google Code Search or Krugle to find examples of use.
[DNS experts will probably scream "Use zone walking on NSEC" but most DNS zones are not signed with NSEC.]
Related
When creating a channel like this
ManagedChannelBuilder.forAddress("mybackend", 6565)
And mybackend is a DNS A record with multiple IP addresses.
Does GRPC round-robin between the records or does it just stick to one for the lifetime of the channel?
If not, would it work if I do?
ManagedChannelBuilder.forTarget("dns:///mybackend:6565")
Or is this capability just not available?
NettyChannelBuilder.forAddress(SocketAddress) is the API that can only access a single IP, due to InetSocketAddress's eager resolution.
forAddress(String, int) was retrofit to use forTarget(String) internally. So it is a convenience and converts to something similar to forTarget(host + ":" + port), but with some extra logic to handle IPv6 literals. The "dns:///" prefix is added to target strings when they fail to parse. See the forTarget() docs for both details. So it is essentially equivalent to using forTarget("dns:///mybackend:6565").
gRPC, by default, doesn't round-robin over multiple addresses. By default it does "pick-first" which stops on the first working address (potentially choosing a different address when reconnecting). You can change that via a service config or defaultLoadBalancingPolicy("round_robin").
I create snmp trap receiver using snmp4j. I managed to receive the pdu and process it. I need the targeted ip address as my machine have multiple ip addresses. I could thinking either two ways:
Retrieve entire command in my trap receiver which is "snmpset -v 1 -c M xx.xxx.x.x 1.3.6.1.4.1.161.3.6.37.2.1.3.2 i 2" so that I can get the ip address by removing other strings." But the only thing I could retrieve is only the variable, value and pdu type.
Using method to retrieve the targeted ip address. But couldn't find one. I used event.getTransportMapping().getListenAddress() but getting 0.0.0.0/161 as I need to listen to many ip address. Used event.getPeerAddress() but getting ip address of the sender's machine.
Really appreciate for any kind of help. Thanks in advance.
Solved by:
UdpAddress udpHostAdress = (UdpAddress) cmdRespEvent.getTransportMapping().getListenAddress();
String ipAdd = udpHostAdress.getInetAddress().getHostAddress();
System.out.println("Target IP = " + ipAdd);
If you are trying to handle security of the trap receiver, you are wrong here use snmp v3 to handle this. v3 has security mechanism called Engine ID.
If I am not wrong, one can connect to a Cassandra cluster knowing at least one of the nodes that is in the cluster, and then the others can be discovered.
Lets say I have three nodes (1, 2 and 3) and I connect to those nodes like this:
Cluster.builder().addContactPoints("1,2,3".split(",")).build();
Then, if node 3 for example goes down, and the IP cannot be resolved, this line of code will throw an IllegalArgumentException as stated in the docs:
#throws IllegalArgumentException if no IP address for at least one of {#code addresses} could be found
Why would anyone want this behavior? I mean, if one of the nodes is down, I want the app to be able to run, as the Cassandra is still working fine.
I have checked this Cassandra Java driver: how many contact points is reasonable?
but that does not answer my question as it doesn't say anything about hosts than can't be reachable.
How should I handle this? Maybe this is changed in another version of the java driver? I am currently using cassandra-driver-core-3.0.3
This validation is only to make sure that all the provided hosts can be resolved, it doesn't even check if a Cassandra server is running on each host. So it is basically to ensure that you did not do any typos while providing the hosts as indeed it doesn't assume that it could be a normal use case to have a provided host that cannot be resolved.
As workaround in your case (host been removed from the DNS entries), you could simply call the method addContactPoint(String address) explicitly instead of using addContactPoints(String... addresses) (which behind the scene simply call addContactPoint(String address) for each provided address) and manage the exception by yourself.
The code could be something like this:
Cluster.Builder builder = Cluster.builder();
// Boolean used to check if at least one host could be resolved
boolean found = false;
for (String address : "1,2,3".split(",")) {
try {
builder.addContactPoint(address);
// One host could be resolved
found = true;
} catch (IllegalArgumentException e) {
// This host could not be resolved so we log a message and keep going
Log.log(
Level.WARNING,
String.format("The host '%s' is unknown so it will be ignored", address)
);
}
}
if (!found) {
// No host could be resolved so we throw an exception
throw new IllegalStateException("All provided hosts are unknown");
}
Cluster cluster = builder.build();
FYI: I've just created a ticket to propose an improvement in the Java driver https://datastax-oss.atlassian.net/browse/JAVA-1334.
As Nick mentioned, it's based on DNS resolution, not Cassandra server health.
If you remove hosts from your environment more often than you recompile your application, then you should consider not baking your contact points into the code, and instead, feed them in through some other means (environment variable, REST service, a single DNS name that always resolves to one live seed, etc).
The documentation there is just in regards to "resolving" the contact points that are passed in. So converting hostnames to ip addresses. If you are specifying ip addresses to begin with, they will not be resolved, simply checked for validity. If you are using hostnames then each contact point will need to be resolvable. This doesn't mean that the cassandra machine needs to be running, just that a DNS lookup on the hostname returns any ip address. So the case where things would break would be if you removed a DNS entry for one of your contact points and restarted your application.
How would you get the domain name of from a TCP connection?
As I'm trying to make a proxy type software but it must detect what the domain is and then go where it needs to. However I'm unsure how to get the domain name from the client.
There is no general way to get the target domain or host name from of the TCP connection, because a connection is only defined by its target IP address and not the host name and there might be several names for a single target IP address. But while there is no general way to get the target name from all TCP connections it is possible with some protocols on top of HTTP:
In case of HTTP you might look at the HTTP Host header which contains the target host name and is set by nearly all HTTP stacks (required with HTTP/1.1).
With SSL you might try to extract the host name from the initial ClientHello message in the SSL handshake, in case the client uses SNI (server name indication). All modern browsers use SNI, but older browser like IE8 not and also not older Java, Python, Perl, Ruby ... applications.
You may use the following code snippet which will give local domain name -
try {
InetAddress me = InetAddress.getLocalHost();
String dottedQuad = me.getHostAddress();
System.out.println("My address is " + dottedQuad);
} catch (UnknownHostException e) {
System.out.println("I'm sorry. I don't know my own address.");
}
I'm using Spring's RestTemplate class to get XML from a web service outside my organisation.
Due to a change in local firewall rules, I need to specify a specific source port in my HTTP requests. Now I can't find anything in the api, on stackoverflow or any tutorial on how to do this.
Is this not possible?
More generally, in descriptions online, I have found that using a specific source port was generally done with UDP based connections/applications. Is this something that is not usually done with TCP?
(I really don't think it helps, but here's the code snippet, as asked by a commenter below):
MyRequest request = new MyRequest(); //whole thing done via jackson
RestTemplate templ = new RestTemplate();
this.serviceUrl = String.format("%s:%d", properties.getServiceUrl()
properties.getServicePort());
ExptectedResponse response = templ.postForObject(serviceUrl, request, ExptectedResponse.class);
The source port of a TCP connection is chosen at random from the ephemeral port range 49152-65535. TCP port ranges are shown here: RFC 6056 - Ephemeral Ports
"The dynamic port range defined by IANA consists of the 49152-65535
range, and is meant for the selection of ephemeral ports."
The port selection process differs depending on the operating system being used. This is much lower level than a typical Java application and therefore is out of your applications control.
Technically you can could force the OS to select a specified port, but as I mentioned is OS specific and breaks the classic portability of a Java application. There is a good post on Super User that talks about this subject here.
I would suggest talking to the department that made the firewall change and see if they can allow outbound connections from normal port range.