Run Non-Twisted-based Python script daemonized with twistd - twisted

I'm writing a Python program consisting of a server (using Twisted) and a client (without Twisted)
The server part is implemented using Twisted and Twisted's application framework and launched with Twistd to be daemonized.
The client which runs on a different server is a simple Python script without any Twisted stuff (and no application framework specific stuff). It should also be run as a Daemon. FYI, this is the source:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket
import sys
import time
import syslog
SERVER_IP = '127.0.0.1'
SERVER_PORT = 43278
BEAT_PERIOD = 1
class HeartbeatClient:
'''
A Client sending heartbeats to a monitoring server.
'''
def __init__(self, server_ip, port, beat_period):
syslog.syslog( ('Sending heartbeat to IP %s , port %d' +
'\n press Ctrl-C to stop\n')
% (SERVER_IP, SERVER_PORT))
def run(self):
while True:
hbSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
hbSocket.sendto('PyHB', (SERVER_IP, SERVER_PORT))
if __debug__:
print 'Time: %s' % time.ctime()
time.sleep(BEAT_PERIOD)
if __name__ == '__main__':
hbc = HeartbeatClient()
hbc.run()
Now I wonder if I can daemonize the client also with Twistd? Therefore I would have create an Twisted-Application out of the client. But all examples I saw concerning Twisted applications where implementing some Twisted internet-server stuff (like in my case internet.UDPServer...), which my client does not use.
So is it possible to use Twistd to launch my client as a daemon, and what changes do I have to make? Should I rewrite the client to take full use of Twisted? If yes, are there any similar examples out there how to write a Twisted based network client?
Or do I have to use a different daemonize library for the client? There is a good library for that, but I'm trying to be consistent and use the same daemonizing mechanism for client and server.

With Twisted, as a tac file, your HeartbeatClient would look something like this:
from twisted.application.service import Application, Service
from twisted.internet import reactor
from twisted.internet.task import LoopingCall
from twisted.internet.protocol import DatagramProtocol
class HeartbeatClient(Service):
def startService(self):
self._call = LoopingCall(self._heartbeat)
self._call.start(BEAT_PERIOD)
def stopService(self):
self._call.stop()
def _heartbeat(self):
port = reactor.listenUDP(0, DatagramProtocol())
port.write('PyHB', (SERVER_IP, SERVER_PORT))
port.stopListening()
application = Application("PyHB")
HeartbeatClient().setServiceParent(application)
Note the use of reactor.listenUDP, even though you're only sending UDP datagrams, not receiving any. UDP doesn't really have the concept of clients and servers, it only has open ports. All UDP ports can send and receive datagrams. That's why there's only reactor.listenUDP, not reactor.connectUDP.
Aside from that, LoopingCall gives you the loop you want, and putting the code into a custom Service subclass lets you start and stop the loop at the appropriate times.

Related

mininet connect to remote ODL controller with python code

I'm new to mininet, I want to see the network topology using opendaylight(carbon) controller. I have tried command:
sudo mn --topo linear,3 --mac \
--controller=remote,ip=10.109.253.152,port=6633 \
--switch ovs,protocols=OpenFlow13,stp=1
And the opendaylight can successfully show the whole topology. And Then, I want to show the same result by using python code solely. However, it doesn't work.
#!/usr/bin/python
from mininet.net import Mininet
from mininet.node import RemoteController, OVSSwitch
from mininet.log import info, setLogLevel
from mininet.cli import CLI
def RemoteCon():
net = Mininet(controller=RemoteController, switch=OVSSwitch)
c1 = net.addController('c1', ip='10.109.253.152',port=6633)
h1 = net.addHost('h1')
h2 = net.addHost('h2')
s1 = net.addSwitch('s1')
net.addLink(s1, h1)
net.addLink(s1, h2)
net.build()
net.start()
CLI(net)
net.stop()
if __name__ == '__main__':
setLogLevel('info')
RemoteCon()
Oh, by the way, does the switches have default forwarding functionality? Sometimes, I have hosts and switch connected to each other and hosts can ping each other while running above code, h1 cannot ping h2 and vice versa.
Thanks in advance.
I'm assuming you are using the l2switch feature in OpenDaylight.
if you search this forum, you'll find others complaining of inconsistent
connectivity when using l2switch. You are probably hitting bugs, but
after a restart of OpenDaylight, it might be ok. By default, with l2switch
it should learn the links of the topology, and create the flows to allow
all hosts to ping every other host.
as for your python script to run mininet, I don't see anything obvious.
Can you look in the OpenDaylight karaf.log for any clues? Or check the
OVS logs for other clues? If you are just simply not seeing anything
in the topology viewer, then my guess is that the OVS is not connecting
to OpenDaylight at all.
One thing to double check. I don't know how the python script is deciding
which openflow version to use, but maybe it's using 1.0 and that's the
big difference from your command line, which sets it to 1.3?
I see that you missed starting your switch to communicate with the controller. Try
s1.start([c1])
This defines which controller the switch is connected to. Hope this helps.
You should give protocols parameter to addSwitch function as command line:
s1 = net.addSwitch('s1',switch=OVSSwitch,protocols='OpenFlow10')

How to send multiple identical HTTP POST message instantly

I have people cheating in my game by sending multiple HTTP POST message the game server (php + apache) to gain items. I have fixed that loophole but I want to test if my fix was correct.
I have tried some of the chrome plugin to send POST messages but I cant imitate sending them in the same instant, for example 5 identical POST message all send out less that 100ms to the same IP in between them.
I have a Centos and a windows machine, would appreciate any script or program recommendation.
If you have Python installed (your CentOS machine would), the following will do what you're after using only built-ins. You'll just need to tweak the conn.request line to pass in any body or headers your server requires.
from threading import Thread
import httplib, sys
REQUESTS = 5
def doRequest():
conn = httplib.HTTPConnection("www.google.com")
conn.request("POST", '/some/url')
for i in range(REQUESTS):
t = Thread(target=doRequest)
t.daemon = True
t.start()

Send login packet to Minecraft Server

Is there a way to send a login packet to Minecraft server from Python?
Here is what I have right now:
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
addr = ("localhost", 25565)
client.connect(addr)
client.sendall(chr(0x02))
client.sendall(chr(0xFD))
client.sendall(chr(0xCD)) # After sending this line server still don't kick me
client.sendall(chr(0x06)+str(117)+str(70)+str(-46)) # And now server kicks me :-(
client.sendall(chr(0x03)+str("Hello World"))
print client.recv(4096)
client.close()
I'd like to send login packets with a non-premium username (or one that doesn't exist if it is possible)
An alternative would be to use someone-else's python library that does it for you - like quarry or others mentioned here. Also see this related question.

How to enter SSL PEM pass phrase only once in gevent streamServer?

Every time a client connects to the server I get a prompt to enter the PEM pass phrase. I want to only enter it on startup of the server and not have to enter it again. The Twisted Matrix framework only requires the pass phrase on startup, why not gevent? Or am I using gevent wrong?
The code below works fine if I use a certificate that require no PEM pass phrase, but I want to use a certificate with a pass phrase.
from gevent.server import StreamServer
from gevent.pool import Pool
from gevent import monkey
class SocketPool(object):
def __init__(self): self.pool = Pool(1000)
def listen(self, socket):
while True:
line = socket.recv(1024)
if not line: break
print line
socket.close()
break
def add_handler(self, socket, address):
print "connection made:", address
if self.pool.full(): raise Exception("At maximum pool size")
else: self.pool.spawn(self.listen, socket)
def shutdown(self): self.pool.kill()
monkey.patch_all()
sockPool = SocketPool()
server = StreamServer(('', 5000), sockPool.add_handler, keyfile='key.pem', certfile='cert.pem')
server.serve_forever()
There doesn't appear to be an easy way to fix this on python 2.7. Internally, gevent.server uses the python ssl module which calls the OpenSSL library from C. The _ssl.sslwrap() function creates a new SSLContext for each call and this is why you are prompted for the key passphrase each time a connection is made.
Twisted uses pyOpenSSL instead of the ssl module. In pyOpenSSL you create your SSLContext first and that single context is used each time a connection is made. Thus you are only prompted for the passphrase once when using Twisted.
Python 3.2 adds an ssl.SSLContext class with a wrap_socket() method. If you were on this version or later then you could patch the gevent code to work more like Twisted, i.e. use a single SSLContext and replace the call to _ssl.sslwrap() with a call to the wrap_socket() method. It doesn't appear that gevent is ported to python3, though.
You could offload SSL handling by gevent by placing an SSL proxy in front so incoming SSL connections to a public port are proxied to your gevent server on an unencrypted internal port. You could write your own proxy with Twisted or use a dedicated proxy like stunnel. However, this might negate some or all of the reasons you wanted to use gevent in the first place.
You could patch your _ssl module either to cache SSLContexts or to use another way of accepting the passphrase. _ssl in python 2.7 uses the default passphrase callback, which interactively prompts to enter the passphrase. This wouldn't be that difficult, but it requires that you know at least a bit of C, the python C API, and the OpenSSL API, plus you would have to build and override the module everywhere you deploy.
You could patch gevent with your own code to wrap a socket with SSL. This can be done entirely in python with a library like pyOpenSSL, but getting it right is probably a fair amount of work.
Finally, you could just use an unencrypted key. Perhaps putting the key on a RAM disk or on an encrypted file system (or both) would address whatever security requirements you have.

How to spawn long-running-processes in Twisted

Preface
I'm writing an web-server that gives to users an access to some program written on C (I'm using an Python wrapper over this C-program, it is PyCLIPS). To serve a lot of users, the web-server has to start a lot of copies of this C-program, because one copy can serve very few users in the same time, about 1-3 users. In addition, each user should work only with his own copy, therefore should be a lot of copies of the C-program.
This C-program is a CLIPS engine if it'll help to understand.
So, to solve this design problem, I want write a Twisted TCP server that will be like a pool of long-running-processes. Each of long-running-processes is a small Twisted TCP server that gives an access to one copy of the C-program.
In example, a user ask the pool-server to reserve a long-running-process for him, then the pool-server create and run a long-running-process that starts listening on some port, then the pool-server return the host and port of this long-running-process to user. Now, user can communicate with this long-running-process directly.
Questions
How start these long-running-process from the pool-server? The pool-server and each of long-running-processes are should be separate Twisted servers.
Is Twisted a good choice for these aims?
Maybe there are another ways how solve this design problem?
Thanks a lot.
Using Twisted for this sounds like it makes sense. The low-level API that supports running processes in Twisted is reactor.spawnProcess. Some examples of its usage are given in the process howto document.
This API is well suited for dealing with many long running processes, and as with all I/O APIs in Twisted, it works well when combined with another event source, such as a web server users can use to request new processes be started up.
reactor.spawnProcess is more like the standard library subprocess module than like the multiprocessing package. It gives you a way to launch a child process running a particular executable, with particular arguments, etc. It does not provide a high-level API for running a particular Python function in another process. However, it's not too hard to build such a thing (at least for a particular case). Consider this approach:
from sys import executable
from os import environ
from twisted.internet import reactor
implementation = """\
from yourapp import somefunction
somefunction()
"""
reactor.spawnProcess(executable, [executable, "-c", implementation], env=environ)
reactor.run()
This just launches a new Python interpreter (whichever one you happen to be running) and uses the -c option to specify a program on the command line for it to run.