Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Oct 20 14:59
    IgorKaplya opened #385
  • Oct 20 10:05
    Hugie opened #384
  • Oct 20 09:51
    Hugie opened #383
  • Oct 14 17:29
    rlebeau commented #382
  • Oct 14 17:29
    rlebeau commented #382
  • Oct 14 17:28
    rlebeau commented #382
  • Oct 14 17:25
    rlebeau labeled #382
  • Oct 14 02:42
    hzmnet edited #382
  • Oct 14 02:41
    hzmnet opened #382
  • Oct 11 19:25
    rlebeau closed #380
  • Oct 11 19:10
    rlebeau assigned #381
  • Oct 11 19:09
    rlebeau edited #381
  • Oct 11 19:09
    rlebeau milestoned #381
  • Oct 11 19:09
    rlebeau labeled #381
  • Oct 11 19:09
    rlebeau labeled #381
  • Oct 11 19:09
    rlebeau opened #381
  • Oct 11 09:02
    Arthur-Regnier commented #380
  • Oct 09 01:01
    rlebeau commented #380
  • Oct 09 00:24
    rlebeau labeled #380
  • Oct 08 07:21
    Arthur-Regnier edited #380
DelphiWorlds
@DelphiWorlds
ok.. that error happens on iOS Simulator.. not on Win32
DelphiWorlds
@DelphiWorlds
...and also errors on iOS
Remy Lebeau
@rlebeau
@DelphiWorlds Sending a UDP broadcast will go out on a single IP interface of the OS's choosing, unless you bind the socket to a specific interface beforehand, or use the broadcast IP of a specific subnet rather than the generic 255.255.255.255 broadcast address. If you want to broadcast on all available interfaces, you have to send a broadcast to each one individually.
Remy Lebeau
@rlebeau
@DelphiWorlds I can't comment on your 10049 error without seeing how you are binding the IPs to begin with. The MulticastGroup is the network multicast IP address that you want to send/receive packets on (the IP that routers watch for on packets), which is different than the local IP address that you bind sockets to. IPv4 multicast group addresses are in the 224.x.x.x to 239.x.x.x range. IPv6 multicast group addresses are in the FF0x:x:x:x:x:x:x:x range
DelphiWorlds
@DelphiWorlds
I'm not going beyond the router, so I assume I won't need multicast? I just need to make sure the broadcast is seen through the correct connection..
I need to loop through the available IPs and send on each
DelphiWorlds
@DelphiWorlds
ok.. I need multicast because IPv6 is involved
procedure TNetworkingModel.ConfigureUDPBindings(const AListener: TIdIPMCastClient);
var
LHandle: TIdSocketHandle;
I: Integer;
begin
AListener.Bindings.Clear;
for I := 0 to FLocalAddresses.Count - 1 do
begin
LHandle := AListener.Bindings.Add;
LHandle.IPVersion := FLocalAddresses.Addresses[I].IPVersion;
LHandle.IP := FLocalAddresses.Addresses[I].IPAddress;
LHandle.Port := AListener.DefaultPort;
end;
end;
oops
not that good with gitter
procedure TNetworkingModel.ConfigureUDPBindings(const AListener: TIdIPMCastClient);
var
  LHandle: TIdSocketHandle;
  I: Integer;
begin
  AListener.Bindings.Clear;
  for I := 0 to FLocalAddresses.Count - 1 do
  begin
    LHandle := AListener.Bindings.Add;
    LHandle.IPVersion := FLocalAddresses.Addresses[I].IPVersion;
    LHandle.IP := FLocalAddresses.Addresses[I].IPAddress;
    LHandle.Port := AListener.DefaultPort;
  end;
end;
that's how I'm configuring the bindings
DelphiWorlds
@DelphiWorlds
if I don't attempt to bind the IPv6 addresses, no error
DelphiWorlds
@DelphiWorlds
TIdIPMCastServer also errors if attempting a Send on an IPv6 address

Debugger Exception Notification

Project dyld_sim raised exception class EIdSocketError with message 'Socket Error # 49

Cannot assign requested address.'.

Break Continue Help

DelphiWorlds
@DelphiWorlds
even if I ignore the IPv6 addresses, my client (192.168.56.100) doesn't receive a broadcast from the server (192.168.56.1)
Remy Lebeau
@rlebeau
@DelphiWorlds how are you sending the broadcast? What does that code look like?
DelphiWorlds
@DelphiWorlds
Francesco Marano may have given me a solution in the forums.. the thread starts here:
https://forums.embarcadero.com/message.jspa?messageID=887844&tstart=0
I neglected to consider that the IPMCast classes have their own IPVersion property, as well as MulticastGroup property.. doh
DelphiWorlds
@DelphiWorlds
if you read Francesco's last reply, his example code works on Windows, fails on iOS.. same error
It fails when setting the client active
DelphiWorlds
@DelphiWorlds
TIdStackVCLPosix.GetLocalAddressList fails to retrieve any addresses for me on my Android 7 device, so I've created this Gist, in case it's of any use:
https://gist.github.com/DelphiWorlds/0733b6611707c8d5725ee42fd1ae01fd
Remy Lebeau
@rlebeau
@DelphiWorlds TIdStackVCLPosix.GetLocalAddressList() being broken on Android is a known issue. There are comments to that effect in the code. I stay away from using Embarcadero's JNI Bridge interfaces because 1) they are not portable (they only work in Delphi, not in FreePascal), and 2) there are threading issues related to accessing Java objects in native code, so I try to stick with native solutions. Which I have not implemented for Android yet.
DelphiWorlds
@DelphiWorlds
ok.. no clues about what might be causing the failure on iOS? I'm also having problems attempting to broadcast on each IP address.. for some reason or another using a loop it broadcasts only on the last address
procedure TForm1.SendBroadcast(const AServer: TIdIPMCastServer; const ABroadcast: string);
var
  I: Integer;
begin
  for I := 0 to FLocalAddresses.Count - 1 do
  begin
    if FLocalAddresses[I].IPVersion = AServer.IPVersion then
    begin
      AServer.Active := False;
      AServer.BoundIP := FLocalAddresses[I].IPAddress;
      AServer.BoundPort := AServer.Port;
      AServer.Active := True;
      AServer.Send(ABroadcast);
    end;
  end;
end;
Remy Lebeau
@rlebeau
@DelphiWorlds I'm not a multicast expert, or an iOS user, I can't tell you why it fails on iOS. What is the actual error? On which line of code? Where are you setting AServer.MulticastGroup? Is that group valid on all networks you are trying to bind to?
DelphiWorlds
@DelphiWorlds
I posted the error earlier, and it occurs when attempting to set Active to True on the TIdIPMCastClient
Remy Lebeau
@rlebeau
@DelphiWorlds the code above is server, not client. Do you have problems if you use a separate TIdIPMCastServer for each local IP, instead of binding and re-binding a single TIdIPMcastServer over and over?
DelphiWorlds
@DelphiWorlds
I mean earlier than that
For now I'll assume it's because the MulticastGroup value is invalid.. I'm far from a multicast expert, too ;-)
Remy Lebeau
@rlebeau
@DelphiWorlds What is the EXACT error? What does the EXACT call stack look like when the error is raised?
DelphiWorlds
@DelphiWorlds
I posted the exact error message earlier.. one moment and I'll have a call stack
Exact error message again:
Project dyld_sim raised exception class EIdSocketError with message 'Socket Error # 49
Cannot assign requested address.'.
Call stack:
System._DbgExcNotify(0,$C9B3010,$909364 {'EIdSocketError'},$6306C8,nil)
System.NotifyReRaise
:00017cc7 NotifyReRaise + $13
IdStack.TIdStack.RaiseSocketError(49)
IdStack.TIdStack.RaiseLastSocketError
IdStack.TIdStack.CheckForSocketError(-1)
IdStackVCLPosix.TIdStackVCLPosix.SetSocketOption(9,41,12,(no value),20)
IdStackBSDBase.TIdStackBSDBase.MembershipSockOpt(9,???,'0:0:0:0:0:0:0:0',12,Id_IPv6)
IdStackBSDBase.TIdStackBSDBase.AddMulticastMembership(9,'FF01:0:0:0:0:0:0:1','0:0:0:0:0:0:0:0',Id_IPv6)
IdSocketHandle.TIdSocketHandle.AddMulticastMembership('FF01:0:0:0:0:0:0:1')
:00633c46 TIdSocketHandle.AddMulticastMembership + $3A
IdIPMCastBase.TIdIPMCastBase.SetActive(True)
Multicast.TMulticastModule.EnableServices(True)
Multicast.TMulticastModule.Create($D820800)
the same code works on Windows.. but I'm guessing that may be irrelevant given differences in OS
Remy Lebeau
@rlebeau
@DelphiWorlds The error is coming from setsockopt() when adding a local IP to the multicast group, which is done after the socket is bound locally. The local IP that is being passed in is 0:0:0:0:0:0:0 (aka in6addr_any), which comes from the TIdSocketHandle.IP property, which is updated after binding. If the socket is bound to a specific local IP and not to in6addr_any, the TIdSocketHandle.IP property should not be all zeros. That implies a possible failure in TIdSocketHandle.UpdateBindingLocal(). But no matter, because the local IP is not currently being passed to setsockopt(IPV6_ADD_MEMBERSHIP) in IPv6, it is set to the default multicast interface instead. Maybe that is what iOS is complaining about.
DelphiWorlds
@DelphiWorlds
I see what you mean (from MembershipSockOpt)
DelphiWorlds
@DelphiWorlds
Some information here:
https://forums.developer.apple.com/message/71107
I'm still digesting it...
Looks like the interface number does matter
DelphiWorlds
@DelphiWorlds
...or not? seems to be conflicting info on the 'net..
mezen
@mezen

I have still problems with HTTP and NTLM Proxy :( IdAuthenticationNTLM, IdAuthenticationSSPI, IdAuthenticationDigest are used in the interface uses section
For debugging I created event handler for every event of TIdHTTP with logging all method parameters.
First OnStatus (with hsConnecting) will be fired, then OnStatus again (with hsConnected), OnHeadersAvailable, OnWorkBegin (AWorkCountMax = 2609), OnWork (AWorkCount = 2609) and OnWorkEnd as last... No OnProxyAuthorization or OnSelectProxyAuthorization is called!
The received header is

Proxy-Authenticate: Negotiate
Proxy-Authenticate: NTLM
Date: Tue, 06 Jun 2017 09:07:12 GMT
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/html; charset="UTF-8"
Content-Length: 2609
Accept-Ranges: none
Proxy-Connection: keep-alive

The component will be created via

  LHttp := TIdHTTP.Create(nil);
  LHttp.ProxyParams.ProxyServer := LProxy.ProxyServer;
  LHttp.ProxyParams.ProxyPort := LProxy.ProxyPort;
  if LProxy.UseAuthentification then
  begin
    LHttp.ProxyParams.BasicAuthentication := True;
    LHttp.ProxyParams.ProxyUsername := LProxy.Username;
    LHttp.ProxyParams.ProxyPassword := LProxy.Password;
  end;
  LHttp.Request.UserAgent := 'My Client ' + CVersion; // WebServer will always accept this user agent
  LHttp.OnAuthorization := HTTP1Authorization;
  LHttp.OnChunkReceived := HTTP1ChunkReceived;
  LHttp.OnConnected := HTTPConnected;
  LHttp.OnDisconnected := HTTPDisconnected;
  LHttp.OnHeadersAvailable := HTTP1HeadersAvailable;
  LHttp.OnProxyAuthorization := HTTP1ProxyAuthorization;
  LHttp.OnRedirect := HTTP1Redirect;
  LHttp.OnSelectAuthorization := HTTP1SelectAuthorization;
  LHttp.OnSelectProxyAuthorization := HTTP1SelectProxyAuthorization;
  LHttp.OnStatus := HTTP1Status;
  LHttp.OnWork := HTTP1Work;
  LHttp.OnWorkBegin := HTTP1WorkBegin;
  LHttp.OnWorkEnd := HTTP1WorkEnd;

  LHttp.Get(LUrl, LFileStream, [CAccepted_WebServerResponses]);

Did I miss something?
I also have Wireshark logs of the Get-Trys. The first Get from Indy sends already a Proxy-Authorization in Basic, is that correct? But Answer is always HTTP/1.1 407 Proxy Authorization required and there is no more traffic, no second attampt is maded. My biggest problem is, I have no test enviremont. Every change I do, I have to create a new binary and give it to a customer (which knows that they are experimental and, for now, is happy to be a alpha tester).

DelphiWorlds
@DelphiWorlds
which version of Indy?
mezen
@mezen
The one shipped with Delphi Berlin
DelphiWorlds
@DelphiWorlds
are you unable to debug this yourself? if the result is 407, the OnSelectProxyAuthorization event should be called, unless MaxAuthRetries is exceeded.. what do you have that set to?
actually, equal to, or exceeded
mezen
@mezen
Nop, I have no proxy which requires NTLM authentication, so I cant debug, only building binaries and give it to my customer :(
MaxAuthRetries is unchanged, so it should still be on 3 (as Indy default)
I also tried to send a second GET after the first failed one with MauxAuthRetries = 42. No success :(
(Only a lot of more traffic in the wireshark log, but all the same as the first try: Indy only sends a GET with basic authentication and proxy answers with 407)