How can I set TTL for DNS Caching with Delphi SOAP webservices? - web-services

I have a Delphi Application accessing a web service on the Internet.
The provider of said service has now changed to a cloud based infrastructure and came to me with the following request:
"Please configure networkaddress.cache.ttl in the file $JAVA_HOME/jre/lib/security/java.security as follows: networkaddress.cache.ttl=60"
Accordung to the web service provider this is necessary for the service to deliver correct results under all circumstances.
He has checked the connection of my appication and it appears to him that once started it sticks with the same IP-address.
Restarting the Applications did solve this for once.
I have been importing the WSDL using the wizard provided by the IDE so I am using an instance of THTTPRIO to access the web service.
The THTTPRIO-instance is created in FormCreate() of the main form.
The Application is running 24/7 and accesses several methods of the web service regularly.
Does the Delphi SOAP framwork use DNS caching at all?
If yes, is there a similar property like networkaddress.cache.ttl in Java?
Is there a good workaround for the issue (e.g. reinstancing the wrapper class just before every call to the service instead of only once in FormCreate)?
EDIT:
The Application is compiled using Delphi 10.1. Berlin (originally developed with Delphi XE7). It is running on an Windows 7 machine.

Have you found DnsFlushResolverCache?
In order to clear DNS resolver cache like what IPCONFIG /flushdns
does, programmatically:
Requires dnsapi.dll which requires Win2000 or later. As usual, MS does
not document the API
Source: http://brannockdevice.blogspot.de/2006/04/winxp-flushing-dns-programatically.html

I've been digging into the source code a little and I believe I found an answer.
The Delphi SOAP framwork doesn't seem to do any DNS caching on its own.
It's just that the connection to the web service is done with the first request via the Windows InternetConnect() function and the resulting handle ist stored and reused from then on.
Here's a little more background information on this:
The THTTPRIO class communicates with the web service through an instance of THTTPReqResp:
property HTTPWebNode: THTTPReqResp read GetHTTPWebNode write SetHTTPWebNode;
THTTPReqResp calls the Connect() method before every request which again uses a WinApi function to estabish a connection and stores the resulting handle in a field:
FInetConnect := InternetConnect(FInetRoot, PChar(FURLHost), FURLPort, PChar(FUserName), PChar(FPassword), INTERNET_SERVICE_HTTP, 0, NativeUInt(Self));
But - the Connect() method only does this if it is not already connected - the following code is found just at the beginning of the Connect() method:
if (FConnected) then
Exit;
By doing so the connection just stays open from the first request on.
Following requests are simply using the stored handle from InetConnect.
For my problem with the cloud service it should be sufficient to create my own instance of THTTPRIO and pass it to the function returning the web service interface:
RIO := THTTPRIO.Create(nil);
FM := GetFleetManagerAPISoap(FALSE, '', RIO);
Then I will just disconnect each time before calling any web service function:
RIO.HTTPWebNode.Connect(FALSE);
In theory that should finally lead to a fresh connection via InternetConnect() and hopefully my problem will be solved.
(Still have to test this, though)

I think that you can set it globally in Windows registry.
Open regedit.exe and navigate to:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters.
In the right pane, add the following value:
Name: DefaultTTL,
Type: REG_DWORD,
Valid Range: 1-255
Restar the computer.
https://technet.microsoft.com/en-us/library/cc957530.aspx

Related

How to make existing DCOM (OPC) application run as a service?

Background:
I have used developed an OPC server based on LightOPC (https://github.com/Sayen/LightOPC). This works perfectly fine as a local executable. The only problem is that I want multiple clients to connect to the same instance of the exe so they can share data. Currently, even if the DCOM settings are such that it runs as a specific user, it seems that sometimes multiple instances of the exe start. The only solution has been to set it to run as the Interactive User. However this has an issue where it won't run if no user is logged in. I believe the right way is to make it run as a windows service.
Question:
How can I take my DCOM local executable and make it into a service?
Things I tried:
Based off of this question: Create Windows service from executable I used the NSSM( the non-Sucking Service Manager ) to make my exe into a service name MYOPCSERVICE.
Then based on some other googling and examining other OPC servers that run as services, I modified the following registry key:
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\WOW6432Node\AppID{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} (where X's are my AppId) and added a "Local Service" key with the value of "MYOPCSERVICE".
After doing this, when I used DCOMCNFG, my DCOM Application shows up as Application Type = Local Service.
However, after adding this registry key, when I try to start the service or connect to the OPC server, the service fails to start with "CoRegisterClassObject() failed. Exiting..."
I found this document: https://learn.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-coregisterclassobject which has the following:
As of Windows Server 2003, if a COM object application is registered
as a service, COM verifies the registration. COM makes sure the
process ID of the service, in the service control manager (SCM),
matches the process ID of the registering process. If not, COM fails
the registration. If the COM object application runs in the system
account with no registry key, COM treats the objects application
identity as Launching User.
I don't know if this is the issue, and I also don't really understand what it means. What is the "process ID" being referred to? Is this the 1-4 digit integer that all Windows processes have? Or is this the name of the service and does it have to match the name of the executable or the class or the AppId?
Update:
I have been experimenting more, and I am starting to get the feeling that it isn't possible to use NSSM to make the COM executable into a service. It seems like the exe of the service needs to be the one that calls CoRegisterClassObject. I have made a simple service based off of Simple Windows Service in c++ https://www.codeproject.com/script/Articles/ViewDownloads.aspx?aid=499465 and when I do so, I can successfully call CoRegisterClassObject with the AppId of {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} if this AppId registry key contains the string LocalService = MYOPCSERVICE.
I think Windows is enforcing a rule that only the exe registered as a service (which is nssm.exe) is allowed to call CoRegisterClassObject. However nssm spawns another exe (the local OPC executable) and it doesn't pass along this ability. Does this sound accurate? Is there any work around besides having to write all my own service handlers?

ColdFusion 11 console doesn't use Windows service wrapper to start app server

I have a ColdFusion11 environment with two app servers defined. The default cfusion server was created with a Windows system service wrapper to go along with it; the second app server, for some reason, was not.
The SC tool was later used to create a Windows service wrapper for the second app server; however, when the 2nd app server is controlled within the cfusion Enterprise Manager instance, it does not use the Windows Service wrapper to control it. Is there a configuration file I can amend that will instruct CF to invoke the Windows service wrapper to control this second service? This is particularly important as this 2nd server instance has a logon identity that must be used at startup, but if the server is restarted within the CF console, the identity is obviously not used.
In effect, I need to tell the cfusion enterprise manager to use the Windows service wrapper to control the 2nd app server instance, not to just control it directly. I'm assuming there is a configuration setting buried deep within the bowels of CF that would allow me to specify this.
I've tried searching the XML configuration files, looking for a non-obvious setting within them that might point to a startup configuration parameter, but so far have found nothing. Something must control how a secondary app server is managed, so I thought I'd ask here for some insight.
For the sake of anyone else who might encounter this situation, I've discovered the answer. It has nothing to do with changing the configuration of the application server itself.
When the ColdFusion11 administrator console is told to start an instance of another application server within the Enterprise Manager, it first queries the Windows Service Control database for a defined service of the exact name "ColdFusion 11 Application Server [AppServerName]" (without the brackets). If it finds such a service, CF automatically invokes the service wrapper and starts it. Absent that, a direct invocation of the CF instance commences.
The solution to the issue for an app server created without a Windows service wrapper is, when the 'sc' utility is invoked to create the service, to provide a service name that exactly matches the format above.

C++: Application architecture with API

My application it's C++ service. And I need to add API for it. I consider that it will be XML/JSON RPC based API. How should I design a program for reusing existing code base and provide API.
I see following options:
My application will work via RPC layer. Seems that it's bad option due to low performance;
Before starting of service I will fork it and run my application in the first process and RPC server in the second; Seems ok, but how to restart RPC server in this case?
I guess there is a well known pattern for such issues.
Thanks.
If you can use a web server, then the FastCGI concept might be what you're looking for. One of the main duties of FastCGI is to allow you to put on a public API (from the web server) that internally calls the "real" application, in your case the resident C++ service. So all work is done at the web server to create the public API using any technology you wish, and little or no code changes done in your C++ service.

WebRequest timed out in windows service

I use WebRequest in a client to consume a web service on Internet. Each request is triggered in a separate thread.
It works well if hosting the client in IIS. But most of the requests will get timed out error if the client is hosted in a windows service.
When I tried to debug the problem using Fiddler, the WebRequest worked well as all traffic went through 127.0.0.1:8888
Without Fiddler, the traffic goes to Internet directly through a random port, and the time out problem hits again.
The windows service runs under Local System account.
Why do I get time out if the client is in windows service without using a proxy?
Update: My original question wasn't clear. The requests are made concurrently (or at a very short interval). This is to do with the connection limit in the ServicePoint class. By default only 2 connections are allowed to the same external destination. If the destination is local, the limit will be int.Max value. That's why fiddler can magically fix the problem with the proxy. So I manually set the DefaultConnectionLimit to 100 and the requests are on wire.
Adjusting HttpWebRequest Connection Timeout in C#
The most common source of problems that is "magically" fixed by running Fiddler is when your .NET code fails to call Close() on the object returned by GetResponseStream(). See http://www.telerik.com/automated-testing-tools/blog/13-02-28/help-running-fiddler-fixes-my-app.aspx for more details.

Time Syncronization via Web Service Call

Say are dealing with a Windows network that for internet access must pass through a firewall that you have no control over. Said firewall apparently blocks the known time protocols (NTP,daytime,etc) and you know from experience that those who control
it will not allow any exceptions.
Is it possible to sync this "Windows" (could be linux) computer via a web service call which grabs the time from a server out on the internet?
Is there another reliable method for updating time on the server, like pulling from a website and passing it to the ntp client?
HTTP Time Protocol:
http://www.vervest.org/fiki/bin/view/HTP/WebHome
It takes the date from the http server itself, not from a website served by it