Creating a TCP Pipeline architecture with ZeroMQ and PHP? - php

After seeing ZeroMQ is the answer (http://vimeo.com/20605470), by Ian Barber, i got excited about testing out the pipeline pattern presented by him. However, he uses an IPC example: https://github.com/ianbarber/ZeroMQ-Talk/tree/master/worker
How this should work with TCP? How can i instantiate workers through TCP instead of process forking?

It will look almost exactly the same, but instead of using ipc:// sockets names you would use tcp:// socket names. So instead of this:
$work->bind("ipc:///tmp/work");
$ctrl->bind("ipc:///tmp/control");
You might have this:
$work->bind("tcp://*:8080");
$ctrl->bind("tcp://*:8081");
This has the work socket listening on port 8080 and the ctrl socket listening on port 8081. Your connect operations would look something like:
$work->connect("tcp://1.2.3.4:8080");
(Assuming the ip address of your server was 1.2.3.4).

Related

Why doesn't stream_socket_server block the port from additional sockets on Windows?

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.

Can we run node and apache both on same port

I have a application in nodejs and PHP. For now i am using different both.
Can i run node and apache both on same port 8080
Is, there is any way to run any application both on 8080
Thanks
An port is usually connected only to one application. So you have to use different ports.
Proxy -
But you could for example create an virtual host in apache and configure this host as proxy. In this configuration you could access the node.js server on the same port. The node.js server would run on another port.
For TCP based applications, no. You can have only one application listening on a single port at time. If you had 2 network cards, you could have one application listen on the first IP and the second one on the second IP, both using port 8080.... but I doubt that is your case.
I guess you can run them on UDP protocol, which could allow you to have two applications listen to the same port, but as UDP is unreliable and it doesn't establish connection, just sends/receives packets. You might experience big packet loss on UDP.
So, short answer - no.
Actually, there might be a way using iptables. Add a rule of this nature
iptables -A INPUT \
-p tcp \
-m bpf --bytecode "14,0 0 0 20,177"
-j redirect .. Port 80
Check the first few bytes of the connection, and redirect the connection. Then you can accept both http and node.js on the same port, but have the servers running on separate ports.
The syntax above is incorrect, and I have not tried it, but I know people who have used this strategy successfully.

Request service name via TCP socket

I'm making a simple port scanner in PHP, and am trying to figure out how I'd request the name of the service I'm connecting to, similar to how Nmap is able to discover services.
I'm using fsockopen() to open the socket, so I'd use fwrite($socket, "WHAT SERVICE AM I COMMUNICATING WITH?") to ask the question, then listen using fgets($socket).
How do I ask the service what it is?
It's hard coded into the program what the different ports are for. The remote applications don't report them. There are tons of lists on the internet that provide this information.
Same thing for looking at standard services and responses from similar services on different OSs. That's how nmap guesses what OS it's talking to.
Here is a decent starting point.
Here is the source file with the port mappings for nmap.
The scary part is the code that tells which versions and such is running. That's here and I'm glad I don't have to write this :\
Last one, pretty sure this is the file that says how to guess which OS a remote computer is: here

Gearman - Client

Researching PHP/Gearman. I'm trying to get an understanding of how the Gearman Server/Process determines what constitutes a "valid" client.
In the docs that I've seen, the docs show a number of clients connecting to the the Gearman Server. However, I've not found anything that describes how the server "validates" the workers, or restricts the workers/clients from accessing/getting work from the Server.
As an example, I create a Gearman Server, and I have a network with 5 child machines, each of which has a "worker". My evil friend Steve adds another machine to the network, with it's own worker..
How do I stop Steve's worker from getting work from my Server!
Is there a way to have the client/worker register itself, so I can essentially allocate IDs to the clients/workers???
I'm fairly certain that there's a way to do this, but I haven't come across it yet.
I'm testing on a Linux env, using PHP/MySQL/Gearman.
Thanks
Like memcached, gearman has no access control or authentication whatsoever.
Your best solution is to rely on your OS, e.g firewall rules.
Namely iptables should block all incoming traffic to port 4730 (standard gearman port), like this
iptables -A INPUT -p tcp --dport 4730 -s server1 -j ACCEPT
...
iptables -A INPUT -p tcp --dport 4730 -s server5 -j ACCEPT
iptables -A INPUT -p tcp --dport 4730 -j DROP
That way, you still can use Gearman from localhost.
Disclaimer : this rule is on top of my head, please double check these rules before running it on production server.
Hope this helps !
By listening (1) either only on localhost or (2) settings up proper firewall rules if you need outside access. Gearman is created with the intention of having as little overhead as possible, there is no authentication protocol. If this is not enough, only listening on localhost & using SSH tunnels to that machine is a possibility. Also a possibility is using the HTTP protocol (see here), and putting a validating proxy in front of it.
Gearman servers should only be accessible on your internal network. The network your application lives on should not have unauthorized devices on it. Your application servers shouldn't be sharing a network with your wireless router. Gearman will only send jobs to servers registered to that particular server with the same task name. If one of the employees at your company registers a task with the same name to your production Gearman master as a joke, you have bigger problems.

PHP: ARP?? Replying to an ARP Request

I know this may be an impossible question, since we are dealing with two different layers of the network, but is it possible to send a reply to an ARP request using PHP sockets?
If so how....such as What port and ip address would you connect the socket to? Again, I understand that arp doesn't use a port number...at least not that I can tell.
I want to do it in PHP, but for those that are going to question my intentions, it is ultimately for a program I am writing for a some piece of hardware. It seems that as though the NIC does not reply to ARP requests, so I want to generate the response manually.
Basically, the only sort of functions that would get me close are socket functions. UDP and TCP.
Oh, I forgot....if Arp is not possible with sockets, is it possible that when I broadcast an "A" record for my hostname, that I can give my MAC address to the router in some sort of dns answer, so the router can respond to arp requests for the hardware's ip address.
ARP runs on the link layer, sockets run on IP. If your host does not respond to ARP requests, it can never correctly receive TCP or UDP packets. You need to implement ARP in the operating system or network stack. It is not possible nor desirable to do so in PHP.
As Sjoerd says: no way through the 'normal' channels as ARP isn't even IP. But if you can call libpcap from PHP, you can use it to sniff ARP requests and also inject replies.
Reading your edits: DNS also won't help as it manages IP addresses, not MAC ones.

Categories