MongoDB Ruby driver and IPV6 connection failure - ruby

I'm using MongoDBs on three different computers only accessible by IPV6.
I'm able to connect to those DBs using php5 driver, command line interface (with the option --ipv6) and an UI app called "MongoHUB".
The only driver unable to connect thru IPV6 is the ruby one.
Any tip using it, for example, does exist an option when creating a MongoClient by uri stating the address is an ipv6 one, as with command line ?

The MongoDB Ruby driver doesn't support IPv6 yet (just an oversight/no one had requested it), but it will be fully supported in our next release.
Add yourself as a watcher to this ticket here to follow the progress:
https://jira.mongodb.org/browse/RUBY-700

Related

TIdHTTP indy component and IPVersion property (firemonkey)

i am using the TIdHTTP component on a multi-device app (building in Rad Studio Tokyo 10.2.3). All i'm doing is downloading a file to my local app folder (iOS). I want to make sure it works with IPv6 but i don't see the "IPVersion" property for TIdHTTP. I see it on other indy components in rad studio (e.g. IdFTP).
Is there a way to set IPVersion in code for the TIdHTTP component? Below is a snip of the code i'm using to download the file. If it fails on IPv4 it is supposed to try IPv6 next:
UnicodeString LFileName = System::Ioutils::TPath::Combine(System::Ioutils::TPath::GetDocumentsPath(), "myfile.txt");
TFileStream* fs = new TFileStream(LFileName, fmCreate);
Form1->TIdHTTP->ConnectTimeout = 8000; // give it 8 seconds
Form1->TIdHTTP->ReadTimeout = 8000;
try
{
UnicodeString URL = "http://myservername.com/myfile.txt";
Form1->TIdHTTP->Get(URL, fs);
Form1->TIdHTTP->Disconnect();
// ShowMessage("Good download via IPv4");
}
catch(const System::Sysutils::Exception &)
{
try
{
Form1->TIdHTTP->Disconnect(); // clean up from IPv4 try
UnicodeString URL = "http://[myservername.com]/myfile.txt";
Form1->TIdHTTP->Get(URL, fs);
Form1->TIdHTTP->Disconnect();
// ShowMessage("Good download via IPv6");
Righ now i just put brackets around the domain name in hopes that this would work for IPv6...i won't know for sure until i can get a truly IPv6 only network setup (working on it).
UPDATE: I just had an app accepted to Apple Store that uses this approach so obviously it passed IPv6 testing. FYI
I found this discussion in which Remy Lebeau states:
TIdHTTP parses IP version info only from the URL itself, so if you need to send a request to an IPv6 target (IP address or hostname), you have to tell TIdHTTP to use IPv6 by wrapping the hostname portion of the URL in square brackets, eg:
s := idHTTP.Post('http://[IPv6 address or hostname]/resource', ...);
Otherwise TIdHTTP uses IPv4 instead.
This bracketed syntax is a requirement when using IPv6 address literals in
URLs, per RFCs 2732 and 3986. But when using a hostname instead, there is
no such syntax requirement. Connecting to a hostname requires a DNS lookup
to discover the host's available IP addresses and their respective IP versions, and then connect to those addresses as needed until one succeeds.
Indy does not currently implement that kind of connection model. It first
allocates a socket based on the client's IPVersion property, THEN performs
a DNS request suited for that IPVersion, and then finally connects to the
first IP address reported by DNS. This is a known limitation of Indy, which
would require a redesign of Indy's internal logic to fix. However, it can
be worked around manually in most Indy client components by performing
your own DNS lookup ahead of time and then looping through the results, setting Indy's Host and IPVersion properties and calling Connect() on each loop iteration.
However, TIdHTTP is a special case, because it derives the Host and IPVersion values from the requested URL, overriding anything the calling code might set manually. However, it is also because of this model that would potentially allow TIdHTTP to be updated to perform its own DNS loop internally without having to rewrite all of Indy's client components to match. Except that Indy does not currently implement a function that returns all of the IP addresses of a hostname, only the first IP address of a particular version. Until such a function is added to Indy in a cross-platform manner, TIdHTTP cannot be updated to auto-detect IPv4/IPv6 hosts.
As such, this confirms my approach should work (trying IPv4 first and then IPv6 if that fails) using the brackets.
Also, I edited my code to show a "Disconnect" prior to trying the IPv6 in case the IPv4 left a mess.

How do I configure phoenix to use sockets with postgresql

PostgreSQL supports using unix sockets rather than TCP sockets. How do I configure the following block to use unix sockets.
# Configure your database
config :my_app, Sample.Repo,
adapter: Ecto.Adapters.Postgres,
database: "ecto_simple",
username: "postgres",
password: "postgres"
As of March 2018, Postgrex now supports connecting via sockets.
This can be done by supplying a socket or socket_dir option. Here's the changelog from where I picked this up and the source code where you can see an exhaustive list of all options.
From the source code:
:socket_dir - Connect to Postgres via UNIX sockets in the given directory;
The socket name is derived based on the part. This is the preferred method
for configuring sockets and it takes precedence over the hostname. If you are
connecting to a socket outside of the Postgres convention, use :socket instead;
:socket - Connect to Postgres via UNIX sockets in the given path.
This is especially useful (I suppose) if you're on AppEngine which requires you to connect through an SQL proxy through localhost (127.0.01) which works only through a proxy connection.
PostgreSQL prefers unix sockets to TCP sockets on the grounds of performance and privacy. If not already available: TCP can be enabled on the server if you follow simple documentation and have access to do so.
The avenue of client connection is set via environment variables, in particular: PGHOST. From experience drivers such as libpq expect to work that way - it would be shocking if Postgrex did not.
See: https://hexdocs.pm/postgrex/Postgrex.html
The value to supply in PGHOST varies according to the configuration of the server as seen in the file: "postgresql.conf".
It is possible that you may need to create a directory for sockets and set permissions. The following should help: http://iamvery.com/2013/06/17/postgresapp-with-unix-socket.html
To get a more precise answer you will need to mention your operating system and version; also your version of PostgreSQL.

Connecting to MySQL (on Google Cloud SQL) via JDBC and IPv6?

I would like to connect to Google Cloud SQL from an external application using JDBC and the instance's IPv6 address as shown on my Google Developers Console (here obfuscated):
String url = "jdbc:mysql://abcd:abcd:abcd:abcd:abcd:abcd:abcd:abcd";
String user = "root";
String password = "<also_obfuscated>";
connection = DriverManager.getConnection(url, user, password);
This leads to the following exception:
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:
Cannot load connection class because of underlying exception:
'java.lang.NumberFormatException:
For input string: "abcd:abcd:abcd:abcd:abcd:abcd:abcd:abcd"'.
I am using the latest JDBC driver for MySQL. Connection via JDBC and IPv4 works but requires an extra configuration step and incurs (small) extra cost.
So is it even possible to connect to MySQL via JDBC and IPv6 and if so how?
UPDATE According to the documentation, this URL should work for IPv6:
jdbc:mysql://address=(protocol=tcp)(host=abcd:abcd:abcd:abcd:abcd:abcd:abcd:abcd)(port=3306)
However, now I'm getting the following exception:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:
Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago.
The driver has not received any packets from the server.
Besides the JDBC driver supporting IPv6 (which it does, according to the documentation), and the client OS supporting IPv6 (which mine should as it is OS X Yosemite), and the server OS supporting IPv6 (which the Google Cloud does because it reports an IPv6 server address) what other pieces need to be in place in order for IPv6 client-server connections to work?
E.g. does my ISP have to provide any particular support?
You need to register the IPV6 address from which you'll be coming into Google Cloud SQL, among the authorized addresses on the Cloud SQL console.
You can check that IPv6 address e.g by visiting sites such as whatismyv6.com .
Then, all your ISP has to do is to provide a stable IPV6 address (alas, even to these days, not all do -- alas, AT&T Uverse, my ISP at home, does not, for example).
Even from locations where I could reliably get a stable IPv6 address, I had exactly the same problem, originally -- until it dawned on me that, if I'm coming in with an IPv6 address and what I've authorized is an IPv4 one, Google Cloud SQL cannot "translate" one into the other to find out I'm in fact authorized!-)
Note that if you don't have and can't get an IPv6 address from which to connect (e.g. connecting from a home machine through an ISP that does not yet support IPv6) then you can hit the "Request IPv4 address" button under Google Developers Console / Storage / Cloud SQL / [Your Intance] / Access Control / IP Address and you will get one assigned (within a few seconds) which will cost $0.01 per hour, paid from your free $300 of credit if you still have that credit available. Once you move your app to, for example, one of Google's app servers, you will no doubt be able to get an IPv6 address. Release the IPv4 address when unused to save credit.
Try
String url = "jdbc:mysql://[abcd:abcd:abcd:abcd:abcd:abcd:abcd:abcd]";
In URLs literal IPv6 addresses have to be surrounded by [] so that the parser can see the difference between parts of the address and the optional port number which is also separated by a :.
It is often easier to use hostnames instead of literal IP addresses. It stays independent of the used IP protocol and changing addresses is easier as well.

Connect to IBM DB2 with SQuirreL "Reply.fill(). Message: Insufficient data. ERRORCODE=-4499, SQLSTATE=08001"

I have now tried 2 days to connect to external DB2 database with SQuirreL. I always get error:
[jcc][t4][2030][11211][3.58.82] A communication error occurred during operations
on the connection's underlying socket, socket input stream, or socket output
stream. Error location: Reply.fill(). Message: Insufficient data.
ERRORCODE=-4499, SQLSTATE=08001
I am using IBM DB2 Universal JDBC driver v9.7 FP5. I have as well tried v9.5.
One thing is that the DB2 is tunneled with Putty. Server runs linux with IBM DB2 v7.1. I am using Win7x64.
I have ran over many forum topics on the web which cover this error, but none of them has actually worked for me. (ie. iReport to DB2 connection ERRORCODE=-4499, SQLSTATE=08001)
First I thought that maybe this related to port that isn't corretcly tunneled. But I removed the port from Putty session conf and different error occured.
Stack trace as well for the problem:
com.ibm.db2.jcc.am.io: [jcc][t4][2030][11211][3.58.82] A communication error
occurred during operations on the connection's underlying socket, socket input
stream, or socket output stream. Error location: Reply.fill(). Message:
Insufficient data. ERRORCODE=-4499, SQLSTATE=08001
at com.ibm.db2.jcc.am.ed.a(ed.java:319)
at com.ibm.db2.jcc.t4.a.a(a.java:416)
at com.ibm.db2.jcc.t4.a.a(a.java:411)
at com.ibm.db2.jcc.t4.cb.b(cb.java:227)
at com.ibm.db2.jcc.t4.cb.c(cb.java:249)
at com.ibm.db2.jcc.t4.cb.c(cb.java:360)
at com.ibm.db2.jcc.t4.cb.v(cb.java:1145)
at com.ibm.db2.jcc.t4.db.a(db.java:42)
at com.ibm.db2.jcc.t4.b.m(b.java:1238)
at com.ibm.db2.jcc.t4.b.b(b.java:1112)
at com.ibm.db2.jcc.t4.b.c(b.java:700)
at com.ibm.db2.jcc.t4.b.b(b.java:686)
at com.ibm.db2.jcc.t4.b.a(b.java:367)
at com.ibm.db2.jcc.t4.b.<init>(b.java:307)
at com.ibm.db2.jcc.DB2SimpleDataSource.getConnection(DB2SimpleDataSource.java:214)
at com.ibm.db2.jcc.DB2Driver.connect(DB2Driver.java:456)
My best guess was and is still that JDBC universal driver is not backward compatible with DB2 v7.1.
It works on an other development machine (coworker) with 32bit XP on it. I have tried to put it working on different 32bit XP but the same result occurs.
Can anyone at least describe the root of this anomaly?
Edit
http://www.ibm.com/developerworks/forums/thread.jspa?messageID=14779629
This cannot be a firewall or tunneling error. Successfully opened a tunnel to correct port with telnet.
You need to locate and use the DB2 7.2 or DB2 7.1 client code (aka DB2 Client Application Enabler). Prior to DB2 8.1, IBM used a different, platform-dependent protocol called DB2RA for communication between the client and server. DB2 8.1 switched to the standard DRDA protocol. DB2 8.x clients could, in specific configurations, talk to DB2 7.x servers.
Alternatively, if you are using a Java application, you could try to locate/use the Type 3 JDBC driver (COM.ibm.db2.jdbc.net.DB2Driver). This driver is clientless (it has a 3-tier architecture, because it requires a so-called "JDBC Applet Server" to be running on the database server. You can see if it's running on your linux box by looking for a process called db2jd. Generally this process will show up as, for example, db2jd 6789, where 6789 is the port number the applet server is listening on. If you don't see this process you can start it (as the DB2 instance owner) by executing the db2jstrt command.
Another possibility: You may need to restart the computer. In my case, this worked for me. I got this error after installing a special build of DB2 10.5.
For more diagnostics, you can get your IBM JDBC driver version using: java com.ibm.db2.jcc.DB2Jcc -version
Or, try: java -cp ./db2jcc.jar com.ibm.db2.jcc.DB2Jcc -version. Then co-relate the driver version to the Db2 version. Link with more details.

TCP: Address already in use exception - possible causes for client port? NO PORT EXHAUSTION

stupid problem. I get those from a client connecting to a server. Sadly, the setup is complicated making debugging complex - and we run out of options.
The environment:
*Client/Server system, both running on the same machine. The client is actually a service doing some database manipulation at specific times.
* The cnonection comes from C# going through OleDb to an EasySoft JDBC driver to a custom written JDBC server that then hosts logic in C++. Yeah, compelx - but the third party supplier decided to expose the extension mechanisms for their server through a JDBC interface. Not a lot can be done here ;)
The Symptom:
At (ir)regular intervals we get a "Address already in use: connect" told from the JDBC driver. They seem to come from one particular service we run.
Now, I did read all the stuff about port exhaustion. This is why we have a little tool running now that counts ports and their states every minute. Last time this happened, we had an astonishing 370 ports in use, with the count rising to about 900 AFTER the error. We aleady patched the registry (it is a windows machine) to allow more than the 5000 client ports standard, but even then, we are far far from that limit to start with.
Which is why I am asking here. Ayneone an ide what ELSE could cause this?
It is a Windows 2003 Server machine, 64 bit. The only other thing I can see that may cause it (but this functionality is supposedly disabled) is Symantec Endpoint Protection that is installed on the server - and being capable of actinc as a firewall, it could possibly intercept network traffic. I dont want to open a can of worms by pointing to Symantec prematurely (if pointing to Symantec can ever be seen as such). So, anyone an idea what else may be the cause?
Thanks
"Address already in use", aka WSAEADDRINUSE (10048), means that when the client socket prepared to connect to the server socket, it first tried to bind itself to a specific local IP/Port pair that was already in use by another socket, either an active one or one that has been closed but is still in the FD_WAIT state. This has nothing to do with the number of ports that are available.
I'm having the same issue on a Windows 2000 Server with a .Net application connecting to a SQL Server 7.0. There's like 10 servers with the same configuration and only one is showing this error several times a day. With a small test program I'm able to reproduce the error by just establishing a TCP connection on the SQL Server listening port. Running CurrPorts (http://www.nirsoft.net/utils/cports.html) shows there's still plenty of available ports in range 1024-5000.
I'm out of ideas and would like to know if you've found a solution since you've posted your question.
Edit : I finally found the solution : a worm was present on the server (WORM_DOWNAD.A) and exhausted local ports without being noticed.

Resources