I'm having a hard time figuring out the best way to approach this problem. Security is not much of a concern in this particular setup, but performance is.

I have a script that will Telnet to a telecommunications switch and run a series of commands, display the output, and logout of the switch. This is currently written in Perl, uses Net::Telnet, and is ran via CGI in a browser form. I will be rewriting it in Python.

The Problem: There is default username this script uses, but it can only be logged in once. So if 2 or more people are using this script in a web browser, then an error will occur. Also, it takes about 10 seconds for the script to completely run due to the predefined commands that need to be sent.

So the idea that I have is to create a daemon that will connect to the switch via Telnet or SSH > Login > Run a series of predefined commands, then wait for other commands that will come in via the web form.

Is this something you guys would recommend or should I completely rethink the idea? Would it be best to listen to a port? Any good resources on how to create something like this?

Thanks!

Recommended Answers

All 5 Replies

A part of the question is what do you want to do when a user is busy using the telnet connection. Should other users receive an error message, or should they wait ? If your server runs in a posix environment, your cgi script could perhaps acquire a system's semaphore before its telnet session and release the semaphore after the session. You could use this module for this http://semanchuk.com/philip/posix_ipc/#semaphore . Other instances of the script could try to acquire the semaphore with a timeout and send an error page when the timeout expires.

In this case I would prefer the user to wait up to 1 min vs receiving an error. I like where you're going with this and it might be a much more simple way to implement vs the always on connection.

If I had 25 users click the link at once (highly unlikely so just a hypothetical), would they all queue up and process in a sequential manner?

if the result off query would be independant of the one asking I would produce web page of results and give that to others requesting the information other either with password or checking for trusted domain (could be faked but sequrity was not so big concern). It is also possible that your script is unnecessary slow.

I would prefer the results to be displayed independently vs an entire page of results. A possibility is to store the results temporarily into a database (MySQL or SQLite) I suppose and then retrieve the result based on the phone number that was entered in the previous form.

The script is slow due to the fact it has to send multiple commands and such. The script does a little bit of parsing, but only for a few lines of text.

So this goes back to the idea of the Daemon, which would keep the connection alive and ready for the command and print the output to the database.

Here is a small test with a semaphore and no daemon. Here is the server

# server.py
# mock server which starts several script.py subprocesses,
# randomly waiting between the launches.
import random
import subprocess
import time

USERS = 5

def main():
    scripts = []
    for i in range(USERS):
        p = subprocess.Popen("python script.py", shell=True)
        scripts.append(p)
        time.sleep(random.uniform(0.0, 4.0))
    for s in scripts:
        s.wait()
        
if __name__ == "__main__":
    main()

And here are the scripts

# script.py
# mock cgi script (which does not produce html)
# this script acquires a semaphore, then waits randomly between 8 and 12 seconds
# to simulate being busy
import os
import posix_ipc as ipc
import random
import time

TIMEOUT = 20.0

def main():
    sem = ipc.Semaphore("/thread_378059_semaphore",
                            flags = ipc.O_CREAT, initial_value = 1)
    try:
        sem.acquire(TIMEOUT)
        print "user script (pid %d) acquired the semaphore" % os.getpid()
        try:
            # this is where your telnet session goes instead of the time.sleep()
            time.sleep(random.uniform(8.0, 12.0))
        finally:
            print "user script (pid %d) about to release the semaphore" % os.getpid()
            sem.release()
            sem.close()
    except ipc.BusyError:
        print "user script (pid %d) was timed out" % os.getpid()
        
if __name__ == "__main__":
    main()

Here is an exemple output

user script (pid 16819) acquired the semaphore
user script (pid 16819) about to release the semaphore
user script (pid 16828) acquired the semaphore
user script (pid 16828) about to release the semaphore
user script (pid 16839) acquired the semaphore
user script (pid 16845) was timed out
user script (pid 16881) was timed out
user script (pid 16839) about to release the semaphore

These tests were run in linux OS. With a TIMEOUT of 60.0 seconds, no user is timed out.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.