Search code examples
pythonsocketssslmultiprocessingirc

SSL error with using multiprocessing and sockets


Python Version: 3.4.3

Arch Linux: 4.1.3-1-ARCH

I am getting this error when using a socket wrapped with the SSL module: ssl.SSLError: [SSL: SSLV3_ALERT_BAD_RECORD_MAC] sslv3 alert bad record mac (_ssl.c:1769)

Things you might need to know. I get this error when I pass a method to a multiprocess. I have a base class irc, my bot inherits irc and the bot is the one who passes the method off to the process as an argument. I am trying to make an irc bot that can use a plug-in type system.

I think I narrowed down to the socket closing after it goes to the multiprocess. However, this only happens when SSL is used.

Here is the pastebin of what I think could be wrong that you would need to know.

IRC SSL error

This happens after I send a command/plugin/addon to be used as multiprocessing check[3].main has been dynamically loaded as a module and .main is a function in that module, the connection closes. Normal sockets with no SSL works just fine and as intended, only if it's wrapped in SSL it seems to close the connection?

ssl.SSLError: [SSL: SSLV3_ALERT_BAD_RECORD_MAC] sslv3 alert bad record mac (_ssl.c:1769)

com_process = multiprocessing.Process(target=check[3].main, args=(check[0], check[1], check[2], self.sendIrc))

sendIrc is only being used as below in another class we have inherited from.
def sendIrc(self, data):
    if type(data) == str:
        self.sendData("PRIVMSG %s :%s\r\n" % (self.channel, data))
        return

sendData encode as utf-8 because python3:
def sendData(self, data):
    self.sock.send(data.encode('utf-8'))

check[3].main points to this module that has been dynamically loaded and ran under the multiprocessing: import time

def main(nick, comargvs, chan, send):
    print(nick, comargvs, chan)
    time.sleep(5)
    send("Success!")

After this is tun, the parent or calling main code gets the error I posted, but only when SSL is used.

And here is the GitHub Repository of the bot if you needed more info on how it works. I only use !test or test.py in addons to reproduce the error with and only with SSL, i.e. ssl = True in the config file, when SSL is disabled it works just fine and as expected.

This issue didn't happen until I started passing ircSend to the plugins/addons, when they die so does the socket in SSL. I was using queues before but decided to use this way of doing it.

Any help or why this error is being thrown or why it's only happening with SSL would be great.


Solution

  • This is solved now. I went with python 3 selector and queues. The issue was using a handle to the socket stream, which was okay generally, but with SSL I had errors that I posted initially.

    The issue, i think, was passing the handle to an SSL socket to a 'threaded'/multiprocess. When it exited so did the handle to the entire socket, but only when using ssl.

    Thread locks and multiprocessing locks didn't help, the RAND_add()and variants didn't help fix it either (that python docs recommended).

    The way I worked it was, anything dealing with the sock handle stays in main, reading a blocking socket was an issue, but moved to select with a timeout, so now the CPU isn't being raped, and things work.

    Solved code is here under main(): https://github.com/nulldigit90/TechBot/blob/master/ircbot/TechBot.py