I have a problem that is stuck in my mind for almost 24 hours, and at this moment I don't know how to fix it.
Here is the thing: I want to have one 'main' socket on my server that processes all incoming data and sends it to other clients using PHP. That part goes fine, but I want to connect with that socket using multiple subdomains, e.g. ex.example.com. The thing with this is, that you cannot connect with that subdomain unless you have a socket running on it, and that just fills up your ports and that is what I'm trying to prevent.
The best solution is to make Apache process the incoming TCP request, saves the data on which domain you are connecting, and then redirects the client to the main socket, which processes the received data and immediately acts when the client is accepted.
Honestly, I have no idea how to do this. I'm searching for hours, but the only thing I've found was something on Stackoverflow that got close to it: Apache - handling TCP connections, but not HTTP requests
But with that piece of script I am not able to save data (which domain you're using) and send it to the main socket.
I don't know if this can be done by Apache or if it is possible at all, or if there are any other workarounds.
Thank you :)
You are confused about subdomains. Sockets, TCP, and IP all know absolutely nothing about names. DNS wasn't invented until that networking stack had been around for years.
Thus, you can point any number of domains at a single "socket" port on a machine.
Apache can route an incoming request to different "webspaces" (i.e. virtual hosts) based on the destination IP address of the incoming connection(1) or the HTTP/1.1 "Host" header(2). The former was how virtual hosts used to be done but now almost everybody uses the latter.
(1) A machine can have multiple IP addresses even with a single network card but ports are unique to any given protocol on that machine. You point different domains to different addresses and define a reverse-mapping on the webserver so it can tell how the request began.
(2) The value of the "host" is the DNS name that was given to the browser. Since this value is passed explicitly to the webserver, that server doesn't need to rely on tricks like #1.
Related
I have a reactphp script opening multiple ports for listening. Code comes down to trying to open a socket on port x, if occupied choose port+1.
I've found that I can open multiple sockets for the same port without error message which makes the above method of finding a "free" port invalid:
var_dump($s1 = stream_socket_server("tcp://127.0.0.1:7777", $errno, $errstr));
var_dump($s2 = stream_socket_server("tcp://127.0.0.1:7777", $errno, $errstr));
Both calls return a resource with different id. Why does this happen and is it possible that a port already has an open socket from the same process (without keeping book on the sockets)?
PS.: Opening two sockets from different processes fails as expected.
Related questions: Multiple UDP Sockets to listen for specific source on the same port
Update
See https://3v4l.org/6eWY1, it seems the decribed behaviour applies to Windows versions of PHP only.
Have a look at this technique to test if a port is open.
I get the same results with your code and this technique works for me to identify if a port was already open by the same process.
That could be an option if you don't mind the overhead.
FYI I do not know PHP and I primarily use Linux, so your mileage may vary. It seems though that I might help you with some tcp knowledge. If you already know this, forgive me and ignore my answer ;)
So I don't know how you connected to your server socket and how your server handled the connection, but if it is programmed correctly your server will not occupy the port, hence blocking future connections. You can of course do that if you want to.
Normally when you create a server, you want to have 1 known port, so that multiple clients can connect to it (like port 80 for http). The server uses 'listen' to listen for connections, followed by an 'accept' and finally a 'close'. The accept makes sure that you can get multiple connections via your server port.
Btw:
you can find a free port by opening a socket on port 0.
you can handle multiple sockets via 'select'
a nice book to read up on sockets is Working with Tcp sockets by Jesse Storimer (FYI I don't have stocks, only the book ;). But there are many intros to socket programming if your google fu is with you.
I've tried looking for this online, but am having trouble finding exactly what I am looking for.
Where I work we have one server that has multiple apache setups on it, all accessed by different subdomains, about 5 total (ex: abc.domain.com, xyz.domain.com, def.domain.com).
Problem is there is one mysql server, on a different physical server we need to connect to, that only allows connection from specific hosts (so say abc.domain.com). Whenever we try to connect to it from PHP, sometimes the login will fail because the user trying to login will come up on a different hostname. (ex user is root#xyz.domain.com, when root#abc.domain.com is the only one allowed). If the page is refreshed a couple time, it will eventually end up using the right hostname to login with and work fine.
My question is, is it PHP on the local server, or MYSQL on the remote server that determines what hostname the user is logging in from.
I know the easiest solution would be to add the other subdomains to the mysql server list of accepted hosts, but I have control over the PHP server, and the MYSQL server is a different department, and it would be much easier to come up with a solution on the PHP side of things.
Thanks
See here: How does mysql determine the hostname of its clients?. The MySQL server performs a reverse DNS lookup of the client IP. If you have multiple reverse entries, it's probably unpredictable which one will be used, which is why you see inconsistent results.
You should either remove the extra reverse DNS entries (they're not generally needed), or configure your permissions using the client IP rather than hostname.
I have a small home server (Ubuntu+XAMPP) and 2 PHP scripts: server.php and client.php, which both communicate to each other via sockets.
When I run server.php / client.php on the same machine (localhost), it works fine. Also, when I run server.php on the server, and client.php on the same server but from other local PC (i.e. local_server_ip/client.php), all works fine as well.
However, when I run server.php on the server and client.php on the other PC on the same network (replacing localhost with local_server_ip_addr in the client.php script), it fails with the actively refused connection error.
All necessary ports are forwarded in the router. I guess it is kind of security block on XAMPP/Linux and can be eliminated by some configuration file. I replaced Deny from all in the New XAMPP security concept with Allow from all in httpd-xamp.conf file, but it still fails.
Any help would be much appreciated.
(PS: server/client scripts examples taken from http://i-novice.net/sokety-v-php/ )
UPD: Have modified port 8080 (the one is dedicated for sockets in my system) to XXXXX. All works fine!
In the event that this happens dependably, it actually implies that the machine exists however that it has no administrations listening on the predetermined port, or there is a firewall ceasing you.
In the event that it happens periodically - you utilized "now and then" - and retrying succeeds, it is likely in light of the fact that the server has a full 'overabundance'.
When you are holding up to be acknowledged on a listening attachment, you are put in a build-up. This overabundance is limited and short - estimations of 1, 2 or 3 are not bizarre - thus the OS may be not able to line your solicitation for the "acknowledge" to devour.
The build-up is a parameter on the listen capacity - all dialects and stages have essentially the same API in such manner, even the C# one. This parameter is frequently configurable in the event that you control the server, and is likely read from a few settings document or the registry. Research how to arrange your server.
In the event that you composed the server, you may have substantial preparing in the acknowledge of your attachment, and this can be better moved to a different specialist string so your acknowledge is constantly prepared to get associations. There are different structural engineering decisions you can investigate that alleviate lining up customers and handling them successively.
Notwithstanding whether you can build the server build-up, you do need retry rationale in your customer code to adapt to this issue - as even with a long build-up the server may be getting bunches of different demands on that port around then.
There is an uncommon probability where a NAT switch would give this blunder if its ports for mappings be depleted. I think we can toss this probability as a lot of a long shot however, since the switch has 64K concurrent associations with the same destination location/port before weariness.
1- Let's say my computer ip address is 111.11.111.11, and the server that my php script is on is 222.22.222.22, so if i access and run the php script that is on the server and start a socket server, which ip do my clients need to connect to?
2- Is it possible to have a socket running on php which keeps reading, and responding to the clients until I close the browser, So basically what i'm trying to do is to start a socket which keeps reading, and accepting clients, and keeps communicating with them multiple times with each.
thanks for the answer, but i think i didn't explain well enough on my question 2, so let me make it easier:
Is it possible to create a chat server using php? because the point i was getting into was if it's possible to accept multiple clients and keep them alove.
222.22.222.22. But it sounds like you are starting up a socket server in response to a HTTP request. Probably, that won't work as intended, since the PHP interpreter terminates after the response is sent. If you had permissions, you could fork a separate socket server process, but I don't know what that would accomplish.
No. Even if you kept the interpreter running, there is no way to tell when the browser closes. The closest you can get is determining the browser (as determined by cookies or IP) stops communicating with you.
1- 222.22.222.22, your server's IP.
2- When a visitor arrives you can spawn a 'socket process' and implement a client side 'heartbeat' application using JavaScript/AJAX, but that implies you running the socket backend script (possibly) for a long time, which may cause problems (Like having a lot of PHP processes open, depending on the way your web server is set up this may cause problems)
I am trying to limit traffic to my website so that people trying to screenscrape mass amounts of data will be blocked after a while. I am supposed to do this based on the IPs of incoming requests. I believe I have the IP-limiting functionality written but, I'm stumped on how I can test it. I need to be able to change my IP address many times, to simulate valid traffic. I also need to test >20 different IPs, so a proxy solution for each one will not work for me.
I am testing the code on my local machine (running Ubuntu) so I can change my server settings (Apache) if I need to for this test.
I'm behind a corporate network so I cannot change MAC address/ARP settings to be "re-assigned" a new IP. I was hoping for some sort of localhost IP-changing type thing, so I could take advantage of the fact that the server and client were the same machine.
Also, I was trying to avoid changing the code before it is rolled out to production servers, but that may be the best way to do it.
How can I set this up?
Well, what you could do is instead of actually checking the IP do something like this:
$ip = '1337.1337.1337.1337';
Instead of:
$ip = $_SERVER['REMOTE_ADDR']
And then go on to do your IP checking code.
So then when you are done you could make your $ip variable code look like this:
//$ip = '1337.1337.1337.1337';
$ip = $_SERVER['REMOTE_ADDR']
So you can easily turn on and off the "debug switch"
EDIT:
Or even make the IP dynamic:
$ips = Array('192.168.1.220', '120.843.592.86', '256.865.463.563');
$ip = $ips[rand(1,count($ips)-1)];
You can easily do that by running the following command on linux:
ifconfig eth0:0 127.0.0.2
ifconfig eth0:1 127.0.0.3
etc... (creating fake local interfaces)
You may have to configure apache to listen on those ips if you're not listening on 0.0.0.0 (all interfaces), then you can directly access those IPs.
If you want to use other ips, you can easily do that too, but remember to remove them once your tests are done.
This will only work from your local machine, to your local machine.
There are many ways you can test this. The easiest way imo would be to create a list of ARP entries where the IP addresses you are impersonating point to the MAC address of the server. You could then write a simple app that sets the src address to each of the impersonated IP addresses, connect and send whatever HTTP request you want. The server should reply just fine.
You want to consider doing this at the firewall level (if not the corp border firewall than a SW firewall on your host). There are many situations where an abusive host can still take down or affect performance on your site if you are only limiting them at the application level. They are still consuming sockets on and web server worker threads even though you end up rejecting them. You may even have some code that has some expense before the IP check. It really all depends on how lightweight your application is, but one thing is sure, a firewall, whether hardware or sw, can block unruly clients way more efficiently than your application can.
This answer is probably overkill for this application, but I like using tcpdump / libpcap, winpcap, and raw sockets for generating traffic. You not only have great control over the volume going to and from your application, you learn a lot about what you can expect firewall/traffic filter settings to do for you and what kinds of traffic is being blocked that you didn't expect (or that you don't want blocked).
use the random function and set limit to rand(0,255) and concat string in to the IP format. when ever you calling you will get new IP address