santycg
santycg

Reputation: 129

Delphi Datasnap connection error with IPv6 (iOS)

We have an iOS and Android app that uses Datasnap to connect to end-user's datasnap Windows database servers from their mobiles/tablets. Everything was working fine, except now Apple rejects the new version of our app because it is not IPv6 compatible. Ok

Our Firemonkey mobile app (Delphi Seattle) lets end-users to set up their own server configuration (IP and Port). They must have a Windows PC server application running in their own server, so, there isn't any HOSTNAME. They just know their server Public IP address. The server application is installed in a simple Windows PC. Not a web server, domain, etc. so there isn't any server host-name, but an IP address.

After following Apple's instructions to create a IPv6 private shared network, the problem exists. I get "Server Unreachable" error when trying to connect to any IP address from my iPad. I have read that using brackets [ ] with the hostname will work, but I can't get it. Maybe it only works with hostnames, not ip addresses?

Here is a simplified portion of code where I do the connection to the server:

Client side (mobile app): - TSQLConnection (Datasnap Driver. Communication protocol: tcp/ip) - TDSProviderConnection

    SQLConnection1.Params.Values['HostName'] := MY_SERVER_IP;
    try
        DSProviderConnection1.Connected:=true;
    except
        showmessage('error');
    end;

I have tried XX.XX.XX.XX and [XX.XX.XX.XX] values for MY_SERVER_IP with no success. I don't know if I have to change something in the server's Windows application or just on client-side (mobile/firemonkey)

Any solution?

Upvotes: 2

Views: 759

Answers (1)

santycg
santycg

Reputation: 129

I got it

I found a chinese forum with some tricks I haven't found before.

It is possible to configure the Datasnap Communication IP version with the following parameter:

TDBXDatasnapProperties(SQLConnection1.ConnectionData.Properties).CommunicationIPVersion

By default, if empty, it is IPv4. So, on the TSQLConnection.OnBeforeConnect event, just added the following line:

// You need to know if you are on IPv4 or IPv6 first. I explain it later.

if ipversion='IPv4' then   
    TDBXDatasnapProperties(SQLConnection1.ConnectionData.Properties).CommunicationIPVersion:='IP_IPv4'
else
    TDBXDatasnapProperties(SQLConnection1.ConnectionData.Properties).CommunicationIPVersion:='IP_IPv6';

And that's all!! Of course, you need to know if you are on a IPv4 network or in a IPv6 one. I do this with a TidTcpClient component. That component has a 'IPVersion' parameter you can set up.

So, first, try to connect using IPVersion:=Id_IPv4. If successful, you are on a IPv4 network. If not, then you probably are on a IPv6 network (or server is down). So...

    IdTCPClient1.IPVersion:=Id_IPv4;  // <--  try IPv4 first
    IdTCPClient1.Host:=MY_IP;
    try
        IdTCPClient1.Connect;
        result:=true;
        ipversion := 'IPv4';      // <-- will tell us what ip version to use
    except
    end;

    if IdTCPClient1.Connected=false then
    begin
        try
            IdTCPClient1.IPVersion:=Id_IPv6;  // <--  now try IPv6
            IdTCPClient1.Connect;
            result:=true;
            ipversion:='IPv6';    // <-- will tell us what ip version to use
        except
        end;
    end;

And that's all. Now the app works fine on both IPv4 and IPv6 from my iPad!

Upvotes: 0

Related Questions