We have an application server, a TCP protocol type and stream socket type, that is behind an NGINX load balancer but planned to be migrated to AWS with either NLB or ALB. Based on the info I got from the answers of the related questions here in StackOverflow, ALB is only for HTTP/HTTPS so it might not be a good option for our case. Anyway, based on AWS's documentation here, https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-target-groups.html#client-ip-preservation, “Before enabling proxy protocol on a target group, the application server must expect and can parse the proxy protocol v2 header, otherwise, it might fail". Could it be the reason why clients cannot access the application server when Proxy Protocol V1 or V2 is enabled at proxy server or load balancer?
The issue is our client apps can connect to the application server when proxy protocol is disabled but not when enabled.
Below are the code snippets. The class variable FSocket is of TTCPBlockSocket type and CanRead is TBlockSocket method under blcksock unit of Synapse library. I suspect that "if FSocket.CanRead(1000)
" always returns false, because it doesn't stop to the next line when I set debug break point. I was thinking of parsing the proxy protocol header to know if information related to it is available. When it is available the application will just proceed to create the client session. Not sure if that is a good idea. But even if it is, I do not know how to do it. Does anybody familiar with Synapse and has worked with proxy protocol before? Any idea or code samples on parsing proxy protocol header for me to start with? Thanks in advance.
procedure TSynapseMidasDaemon.Execute;
var
lClientHandle: TSocket;
lSession: TSynapseMidasSession;
begin
FSocket.CreateSocket;
FSocket.Bind(FIPAddress, IntToStr(FPort));
FSocket.setLinger(True, 1000);
FSocket.Listen;
while not Terminated do
begin
if FSocket.CanRead(1000) then
begin
lClientHandle := FSocket.Accept;
if FSocket.LastError = 0 then
begin
// we have a winner
try
// create a client session
lSession := TSynapseMidasSession.Create(Self, lClientHandle, FLogSystem, FSettings);
lSession.Resume;
except
on e: Exception do
begin
LogEventFmt(evlError, 'Daemon Socket Failure [%s]', [e.Message]);
InterlockedDecrement(FStatistics.Accepted);
InterlockedIncrement(FStatistics.Rejected);
end;
end;
end; //else we had a socket failure. Moving on.
end;
Sleep(0);// play nice with others.
end;
end;
function TBlockSocket.CanRead(Timeout: Integer): Boolean;
var
ti, tr: Integer;
n: integer;
begin
if (FHeartbeatRate <> 0) and (Timeout <> -1) then
begin
ti := Timeout div FHeartbeatRate;
tr := Timeout mod FHeartbeatRate;
end
else
begin
ti := 0;
tr := Timeout;
end;
Result := InternalCanRead(tr);
if not Result then
for n := 0 to ti do
begin
DoHeartbeat;
if FStopFlag then
begin
Result := False;
FStopFlag := False;
Break;
end;
Result := InternalCanRead(FHeartbeatRate);
if Result then
break;
end;
ExceptCheck;
if Result then
DoStatus(HR_CanRead, '');
end;