Can not connect to an abstract unix socket in python - python

I have a server written in c++ which creates and binds to an abstract unix socket with a namespace address of "\0hidden". I also have a client which is written in c++ also and this client can successfully connect to my server. BTW, I do not have the source code of this client. Now I am trying to connect to my server using a client I have written in python with no success. I do not understand why my python client is not working. I am posting the relevant parts of my server and client codes.
Server
#define UD_SOCKET_PATH "\0hidden"
struct sockaddr_un addr;
int fd,cl;
if ( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
{
syslog(LOG_CRIT, "Error creating socket!");
exit(1);
}
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, UD_SOCKET_PATH, sizeof(addr.sun_path)-1);
unlink(UD_SOCKET_PATH);
if (::bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1)
{
syslog(LOG_CRIT, "Bind error");
exit(1);
}
if (listen(fd, MAX_CONN_PENDING) == -1)
{
syslog(LOG_CRIT, "Listen error");
exit(1);
}
syslog(LOG_INFO, "Start listening.");
And my client code
#! /opt/python/bin/python
import os
import socket
import sys
# Create a UDS socket
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
server_address = "\0hidden"
print >>sys.stderr, 'connecting to %s' % server_address.decode("utf-8")
try:
sock.connect(server_address)
except socket.error, msg:
print >>sys.stderr, msg
sys.exit(1)
After running the client I get the following error output:
connecting to hidden
[Errno 111] Connection refused
And for some extra information I am posting the relevant parts of the strace outputs of my working c++ client and non-working python client:
Working c++ client:
socket(PF_FILE, SOCK_STREAM, 0) = 3
connect(3, {sa_family=AF_FILE, path=#""}, 110) = 0
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77d7000
write(1, "Sent message is: 00014 www.googl"..., 38) = 38
write(3, "00014 www.google.com", 20) = 20
recv(3, "014 Search Engines", 99, 0) = 18
write(1, "014 Search Engines\n", 19) = 19
close(3) = 0
exit_group(0) = ?
None working python client:
socket(PF_FILE, SOCK_STREAM, 0) = 3
connect(3, {sa_family=AF_FILE, path=#"hidden"...}, 9) = -1 ECONNREFUSED (Connection refused)
write(2, "Traceback (most recent call last"..., 35) = 35
write(2, " File \"./uds.py\", line 13, in <"..., 40) = 40
open("./uds.py", O_RDONLY|O_LARGEFILE) = 4
fstat64(4, {st_mode=S_IFREG|0755, st_size=839, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7792000
read(4, "#! /opt/python/bin/python\nimport"..., 4096) = 839
write(2, " ", 4) = 4
write(2, "sock.connect('\\0hidden')\n", 25) = 25
close(4) = 0
munmap(0xb7792000, 4096) = 0
write(2, " File \"/opt/python/lib/python2."..., 64) = 64
open("/opt/python/lib/python2.7/socket.py", O_RDONLY|O_LARGEFILE) = 4
fstat64(4, {st_mode=S_IFREG|0755, st_size=20234, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7792000
read(4, "# Wrapper module for _socket, pr"..., 4096) = 4096
read(4, "oo long.\"\n errorTab[10064] = "..., 4096) = 4096
write(2, " ", 4) = 4
write(2, "return getattr(self._sock,name)("..., 39) = 39
close(4) = 0
munmap(0xb7792000, 4096) = 0
write(2, "socket", 6) = 6
write(2, ".", 1) = 1
write(2, "error", 5) = 5
write(2, ": ", 2) = 2
write(2, "[Errno 111] Connection refused", 30) = 30
write(2, "\n", 1) = 1
rt_sigaction(SIGINT, {SIG_DFL, [], 0}, {0x810fbe0, [], 0}, 8) = 0
close(3) = 0
exit_group(1) = ?
And also when I run my c++ client, I get this strace output from my server:
0, NULL) = 12
futex(0x80646a4, FUTEX_CMP_REQUEUE_PRIVATE, 1, 2147483647, 0x8064688, 360) = 10
futex(0x8064688, FUTEX_WAKE_PRIVATE, 1) = 1
accept(5,
But when I run my python client, no output is shown on strace. So it seems like I am trying to connect to a wrong address, but my address is defined as "\0hidden" in both my server and my client.

Your C++ doesn't do quite what you think it does. This line:
strncpy(addr.sun_path, UD_SOCKET_PATH, sizeof(addr.sun_path)-1);
Copies a single null character '\0' into addr.sun_path. Note this line in the manpage for strncpy():
If the length of src is less than n, strncpy() writes additional null
bytes to dest to ensure that a total of n bytes are written.
As a result your C++ actually connects to an abstract domain socket at "\0". Python does the right thing here and connects to an abstract domain socket at "\0hidden".

Related

How to parse DNS Question field with python raw sockets?

I'm trying to parse question field in a DNS packet where I can read domain and DNS response from a DNS server. I can extract a DNS header, but I'm having trouble to parse the question field because the size of the data is unknown.
I follow this example, but the part of extracting the question field is not working.
What I need is someone to show me the way to do it properly.
I have this code where everything is right...
This is my code:
#!/usr/bin/env python3
from socket import *
import struct
import binascii
def ethernet_frame(raw_data):
mac_dest, mac_src, protocol = struct.unpack('! 6s 6s H',
raw_data[:14])
return byte_to_hex_mac(mac_dest), byte_to_hex_mac(mac_src),
htons(protocol), raw_data[14:]
def byte_to_hex_mac(mac_bytes):
addr = binascii.hexlify(mac_bytes).decode("ascii")
return ":".join([addr[i:i+2] for i in range(0,12,2)])
def data_packet_udp(data):
tuple_data_udp = struct.unpack('! H H H H', data[:8])
port_src = tuple_data_udp[0]
port_dest = tuple_data_udp[1]
udp_len = tuple_data_udp[2]
udp_checksum = tuple_data_udp[3]
return port_src, port_dest, udp_len, udp_checksum, data[8:]
def data_packet_ipv4(data):
tuple_data_ipv4 = struct.unpack("!BBHHHBBH4s4s", data[:20])
version = tuple_data_ipv4[0]
header_len = version >> 4
type_service = tuple_data_ipv4[1]
length_total = tuple_data_ipv4[2]
identification = tuple_data_ipv4[3]
offset_fragment = tuple_data_ipv4[4]
ttl = tuple_data_ipv4[5]
protocols = tuple_data_ipv4[6]
checksum_header = tuple_data_ipv4[7]
ip_src = inet_ntoa(tuple_data_ipv4[8])
ip_dest = inet_ntoa(tuple_data_ipv4[9])
length_header_bytes = (version & 15) * 4
return version, header_len, type_service, + \
length_total, identification, offset_fragment, + \
ttl, protocols, checksum_header, ip_src, ip_dest,
data[length_header_bytes:]
def data_packet_dns(data):
tuple_data_dns = struct.unpack('!HHHHHH', data[:12])
identification = tuple_data_dns[0]
flags = tuple_data_dns[1]
number_queries = tuple_data_dns[2]
number_response = tuple_data_dns[3]
number_authority = tuple_data_dns[4]
number_additional = tuple_data_dns[5]
qr = (flags & 32768) != 0
opcode = (flags & 30720 ) >> 11
aa = (flags & 1024) != 0
tc = (flags & 512) != 0
rd = (flags & 256) != 0
ra = (flags & 128) != 0
z = (flags & 112) >> 4
rcode = flags & 15
return identification, flags, number_queries, number_response, + \
number_authority, number_additional, qr, opcode, aa, tc, + \
rd, ra, z, rcode
sock = socket(AF_PACKET, SOCK_RAW, ntohs(0x0003))
while True:
raw_dados, addr = sock.recvfrom(65536)
mac_dest, mac_src, protocol, payload = ethernet_frame(raw_dados)
if protocol == 8:
( version, header_len, type_service,
length_total, identification, offset_fragment,
ttl, protocols, checksum_header,
ip_src, ip_dest, data ) = data_packet_ipv4(payload)
if protocols == 17:
port_src, port_dest, udp_len, udp_checksum, data =
data_packet_udp(data)
print("--------- HEADER UDP ----------")
print("Port Source : {}".format(port_src))
print("Port Dest : {}".format(port_dest))
print("UDP Length : {}".format(udp_len))
print("UDP Checksum : {}\n".format(udp_checksum))
if port_src == 53 or port_dest == 53:
(identification, flags, number_queries, \
number_response,number_authority,number_additional, \
qr, opcode, aa, tc, rd, ra, z, rcode) = data_packet_dns(data)
print("\t--------- HEADER DNS ----------")
print("\tidentification : {}".format(identification))
print("\tFlags : {}".format(flags))
print("\tnumber_queries : {}".format(number_queries))
print("\tnumber_response : {}".format(number_response))
print("\tnumber_authority : {}".format(number_authority))
print("\tnumber_additional : {}".format(number_additional))
print("\tQr : {}".format(qr))
print("\tOpcode : {}".format(opcode))
print("\tAA : {}".format(aa))
print("\tTC : {}".format(tc))
print("\tRD : {}".format(rd))
print("\tRA : {}".format(ra))
print("\tZ : {}".format(z))
print("\tRCODE : {}".format(rcode))

sending hex data over serial port with checksum

I am new to python and I am trying to write a code to send hex serial data to a radio and receive hex data in response. radio_init_buf variable store the hex data to be sent. The last two bytes with store checksum. radio_init_buf[3] tells the size.
import sys
import glob
import numpy as np
import serial
class serial_communication():
PORT = 'COM2'
# RETURN_VALUE = None
def list_serial_ports(self):
""" Lists serial port names
:raises EnvironmentError:
On unsupported or unknown platforms
:returns:
A list of the serial ports available on the system
"""
if sys.platform.startswith('win'):
ports = ['COM%s' % (i + 1) for i in range(0,10)]
elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):
# this excludes your current terminal "/dev/tty"
ports = glob.glob('/dev/tty[A-Za-z]*')
elif sys.platform.startswith('darwin'):
ports = glob.glob('/dev/tty.*')
else:
raise EnvironmentError('Unsupported platform')
result = []
for port in ports:
try:
s = serial.Serial(port)
s.close()
result.append(port)
except (OSError, serial.SerialException):
pass
return result
def serial_open(self):
self.ser = serial.Serial()
self.ser.baudrate = 9600
self.ser.port = sc.PORT
self.ser.parity = serial.PARITY_NONE
self.ser.stopbits = serial.STOPBITS_ONE
self.ser.bytesize = serial.EIGHTBITS
self.ser.writeTimeout = 1000
self.ser.timeout = 1000
try:
self.ser.open()
print("Port OPENED")
self.initialize(self.ser)
except Exception as e:
print("error opening serial port: " + str(e))
exit()
return self.ser
def checksum(self, crc_packet, crc_packet_length):
crc_table= np.array([0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040],dtype=np.uint16)
saved_crc_byte1 = crc_packet[crc_packet_length - 1]
saved_crc_byte2 = crc_packet[crc_packet_length - 2]
crc_packet[crc_packet_length - 1] = 0
crc_packet[crc_packet_length - 2] = 0
crc = 0
for crc_loop in range(0,crc_packet_length):
crc = (crc >> 8) ^ crc_table[(crc ^ crc_packet[crc_loop]) & 0xFF]
def initialize(self,serial_port):
ser = serial_port
if ser.isOpen():
print("Initialising...")
try:
ser.flushInput() # flush input buffer, discarding all its contents
ser.flushOutput() # flush output buffer, aborting current output
# and discard all that is in buffer
# write data
#f = open('F:/output.txt', 'wb')
radio_init_buf = np.array([0xAA, 0x00, 0x00, 0x08, 0x09, 0x32, 0x0, 0x0],dtype=np.uint8)
#radio_init_buf="\xAA\x00\x00\x08\x09\x32\x00\x00"
print(radio_init_buf)
self.checksum(radio_init_buf,radio_init_buf[3])
print(radio_init_buf)
ser.write(radio_init_buf)
serial.time.sleep(0.5) # give the serial port sometime to receive the data
#return_value = ser.read(7)
print(return_value)
print("Initialisation Complete")
#comm Link Check
print("Communication Link Checking..")
comm_check_buf = np.array([0xAA, 0x06, 00, 6, 0x0B, 0x70],dtype=np.uint8)
ser.write(comm_check_buf)
print("Link Check Complete")
#clear non-volatile memory
clear_nvm_buf = np.array([0xAA, 0x82, 00, 7, 1, 0, 0],dtype=np.uint8)
self.checksum(clear_nvm_buf, clear_nvm_buf[3])
ser.write(clear_nvm_buf)
#ser.close()
except Exception as e1:
print ("error communicating...: " + str(e1))
ser.close()
else:
print("cannot open serial port ")
sc = serial_communication()
print(sc.list_serial_ports())
sc.serial_open()
When i run the code i get:
['COM1', 'COM2', 'COM3']
Port OPENED
Initialising...
[170 0 0 8 9 50 0 0]
[170 0 0 8 9 50 0 0]
b'\xaa\x90\x00\x12\x01\x0c\x00'
Initialisation Complete
Communication Link Checking..
Link Check Complete
Instead of [170 0 0 8 9 50 0 0], i want the hex data.
Also, it is not returning radio_init_buf with checksum. The result after calling checksum is same.
Displaying in hex:
for n in radio_init_buf:
print("{:#x}".format(n), end='')
print()
{:#x} - a format string, #: adds the 0x prefix, x: presentation will be in hex,
In one line:
print(("{:#x} "*len(radio_init_buf)).format(*radio_init_buf))
It creates a string of length len(radio_init_buf).
In *radio_init_buf , '*' unpacks the list.

How to use raw socket in Python

i try to send a selfmade tcp-packet via raw socket in python3 (with windows 10). Inside the ip-header i want to set protocol to TCP (=6).
The paket i send is:
E\x00\x00\x00\xd41\x00\x00\xff\x06\x00\x00\xc0\xa8\xb29\xc0\xa8\xb2\x01
but I receive (and wireshark detects the same)
E\x00\x00FN\xe7\x00\x00\x80\xff\x00\x00\n\xac\x02e\n\xac
so now it is 255 (uknown)
srcport = 11001
def sendTCP(dest_ip, dest_port,fin, syn, rst, psh, ack, urg):
payload = b'[TESTING]\n'
ip = make_ip(socket.IPPROTO_TCP, source_ip, dest_ip)
tcp = make_tcp(srcport, dest_port, payload, 123, 0, fin, syn, rst, psh, ack, urg)
packet = ip + tcp + payload
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
s.sendto(packet, (dest_ip, 0))
ans = s.recv(1024)
print(ans)
def make_ip(proto, srcip, dstip, ident=54321):
saddr = socket.inet_aton(srcip)
daddr = socket.inet_aton(dstip)
ihl_ver = (4 << 4) | 5
return struct.pack('!BBHHHBBH4s4s' ,
ihl_ver, 0, 0, ident, 0, 255, proto, 0, saddr, daddr)
def make_tcp(srcport, dstport, payload, seq=123, ackseq=0,
fin=False, syn=False, rst=False, psh=False, ack=False, urg=False,
window=5840):
offset_res = (5 << 4) | 0
flags = (fin | (syn << 1) | (rst << 2) |
(psh <<3) | (ack << 4) | (urg << 5))
return struct.pack('!HHLLBBHHH',
srcport, dstport, seq, ackseq, offset_res,
flags, window, 0, 0)
if __name__ == '__main__':
sendTCP('10.172.2.101',80, False, True, False, False, False, False)

Nginx's worker process hangs and takes full CPU

I've a setup with Nginx, uWSGI and a Python Flask app. Below you can find server directive from Nginx configuration:
location /api {
try_files $uri #api;
}
location #api {
include uwsgi_params;
uwsgi_pass 127.0.0.1:3031;
}
I start uWSGI with uwsgi --ini /etc/uwsgi.ini. That file looks like this:
[uwsgi]
uid = root
gid = root
socket = 127.0.0.1:3031
module = iris.api
callable = app
Requests to / work fine, Nginx returns the "Welcome to Nginx"-page.
But request to /api are failing. The first request at /api/analog_output/1 is passed via uWSGI to the Python app. The Python app returns with a HTTP 200 response, but Nginx doesn't finish the request by sending this response back to the client.
--- Operational MODE: single process --- WSGI app 0 (mountpoint='') ready in 11 seconds on interpreter 0x1567e8 pid: 957 (default app)
--- uWSGI is running in multiple interpreter mode --- spawned uWSGI worker 1 (and the only) (pid: 957, cores: 1)
[pid: 957|app: 0|req: 1/1] 10.0.0.125 () {42 vars in 712 bytes} [Sun Jan 14 17:22:49 2007] GET /api/analog_output/1 => generated 135 bytes in 66 msecs (HTTP/1.1 200) 2 headers in 72 bytes (1 switches on core 0)
Below you can find the output of strace bind to the Nginx worker.
17:27:39.127453 gettimeofday({1168795659, 128279}, NULL) = 0
17:27:39.129180 write(4, "2007/01/14 17:27:39 [info] 970#0"..., 83) = 83
17:27:39.130169 epoll_wait(8, {{EPOLLIN, {u32=651592, u64=2410198208213320}}}, 512, -1) = 1
17:27:44.680001 gettimeofday({1168795664, 680353}, NULL) = 0
17:27:44.682734 accept4(6, {sa_family=AF_INET, sin_port=htons(53845), sin_addr=inet_addr("10.0.0.125")}, [16], SOCK_NONBLOCK) = 3
17:27:44.685625 epoll_ctl(8, EPOLL_CTL_ADD, 3, {EPOLLIN|EPOLLRDHUP|EPOLLET, {u32=651816, u64=651816}}) = 0
17:27:44.688045 epoll_wait(8, {{EPOLLIN, {u32=651816, u64=651816}}}, 512, 60000) = 1
17:27:44.690552 gettimeofday({1168795664, 691682}, NULL) = 0
17:27:44.693043 recv(3, "GET /api/analog_output/1 HTTP/1."..., 1024, 0) = 426
17:27:44.695848 stat64("/usr/html/api/analog_output/1", 0xbeb8f730) = -1 ENOENT (No such file or directory)
17:27:44.698599 epoll_ctl(8, EPOLL_CTL_MOD, 3, {EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET, {u32=651816, u64=13170497834292212264}}) = 0
17:27:44.701146 getsockname(3, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("10.0.0.195")}, [16]) = 0
17:27:44.703848 socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 10
17:27:44.706386 ioctl(10, FIONBIO, [1]) = 0
17:27:44.708823 epoll_ctl(8, EPOLL_CTL_ADD, 10, {EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET, {u32=651928, u64=2525337691484824}}) = 0
17:27:44.711468 connect(10, {sa_family=AF_INET, sin_port=htons(3031), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
17:27:44.714574 epoll_wait(8, {{EPOLLOUT, {u32=651816, u64=13170497834292212264}}, {EPOLLOUT, {u32=651928, u64=2525337691484824}}}, 512, 60000) = 2
17:27:44.717109 gettimeofday({1168795664, 718064}, NULL) = 0
17:27:44.719461 recv(3, 0xbeb8f89c, 1, MSG_PEEK) = -1 EAGAIN (Resource temporarily unavailable)
17:27:44.721999 getsockopt(10, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
17:27:44.724476 writev(10, [{"\0\310\2\0\f\0QUERY_STRING\0\0\16\0REQUEST_ME"..., 716}], 1) = 716
17:27:44.729618 epoll_wait(8, {{EPOLLIN|EPOLLOUT, {u32=651928, u64=2525337691484824}}}, 512, 60000) = 1
17:27:44.793473 gettimeofday({1168795664, 794585}, NULL) = 0
17:27:44.796026 recv(10, "HTTP/1.1 200 OK\r\nContent-Type: a"..., 4096, 0) = 207
But now the Nginx's worker hangs with full CPU. Further requests aren't processed.
What is going on? And how can I fix it?
Your location block looks incomplete. Not in front of a machine at the moment, but try adding:
proxy_redirect off;
edit: the #app location block

Why did I get a Segmentation Fault in Python when /tmp is mounted with noexec?

I am running a custom Python 2.7.3 application on CherryPy in Linux. When I used a service script in /etc/init.d/ to start or stop the service, I encountered a Segmentation Fault (SIGSEGV). Strangely, I did not receive a SIGSEGV if I ran the start or stop command manually from the shell, using "python /path/to/file.py --stop". The service script executes the same command.
After some debugging, by chance, I discovered that my /tmp was mounted with a "noexec" option. I removed the "noexec" option and the application was able to start and stop via the service scripts without any segmentation faults.
When I first encountered the issue, I ran strace and generated a core dump. Nothing from either tool gave me any indication that /tmp was the culprit. My question is this: How could I have used strace or gdb to help me identify that "noexec" on /tmp was causing the segmentation faults?
Here is some output from gdb when analyzing the core dump:
(gdb) bt full
#0 PyObject_Malloc (nbytes=4) at Objects/obmalloc.c:788
bp = 0x7f6b0fd1c6e800 \Address 0x7f6b0fd1c6e800 out of bounds\
pool = 0x7f6b0fd1c000
next = \value optimized out\
size = 0
#1 0x00007f6b0f7fd8e6 in _PyUnicode_New (length=1) at Objects/unicodeobject.c:345
new_size = 4
unicode = 0x3873480
#2 0x00007f6b0f7fdd4e in PyUnicodeUCS2_FromUnicode (u=0x38367cc, size=)
at Objects/unicodeobject.c:461
unicode = \value optimized out\
(There is a lot more output, this is just the first few lines)
Here is some output from strace on the failure:
3046 open("/usr/local/python2.7/lib/python2.7/site-packages/oauthlib/common.py", O_RDONLY) = 9
3046 fstat(9, {st_mode=S_IFREG|0644, st_size=13310, ...}) = 0
3046 open("/usr/local/python2.7/lib/python2.7/site-packages/oauthlib/common.pyc", O_RDONLY) = 10
3046 fstat(10, {st_mode=S_IFREG|0644, st_size=16043, ...}) = 0
3046 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fbc9ff9d000
3046 read(10, "\3\363\r\n}\321\322Tc\0\0\0\0\0\0\0\0\5\0\0\0##\2\0sd\2\0\0d\0"..., 4096) = 4096
3046 fstat(10, {st_mode=S_IFREG|0644, st_size=16043, ...}) = 0
3046 read(10, "\0\0\0C#\2\0s\330\0\0\0t\0\0|\0\0t\1\0\203\2\0s\36\0t\0\0|\0"..., 8192) = 8192
3046 read(10, "thon2.7/site-packages/oauthlib/c"..., 4096) = 3755
3046 read(10, "", 4096) = 0
3046 close(10) = 0
3046 munmap(0x7fbc9ff9d000, 4096) = 0
3046 --- SIGSEGV (Segmentation fault) # 0 (0) ---
After fixing the problem, here's a snippet from strace, from the same point where it tries to load oauthlib/common.pyc - notice that the only difference appears to be a brk() before munmap():
3416 open("/usr/local/python2.7/lib/python2.7/site-packages/oauthlib/common.pyc", O_RDONLY) = 10
3416 fstat(10, {st_mode=S_IFREG|0644, st_size=16043, ...}) = 0
3416 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5791f2c000
3416 read(10, "\3\363\r\n}\321\322Tc\0\0\0\0\0\0\0\0\5\0\0\0##\2\0sd\2\0\0d\0"..., 4096) = 4096
3416 fstat(10, {st_mode=S_IFREG|0644, st_size=16043, ...}) = 0
3416 read(10, "\0\0\0C#\2\0s\330\0\0\0t\0\0|\0\0t\1\0\203\2\0s\36\0t\0\0|\0"..., 8192) = 8192
3416 read(10, "thon2.7/site-packages/oauthlib/c"..., 4096) = 3755
3416 read(10, "", 4096) = 0
3416 brk(0x372f000) = 0x372f000
3416 close(10) = 0
3416 munmap(0x7f5791f2c000, 4096) = 0
3416 close(9) = 0
What information can help me point the blame at /tmp's mount options?
For those who would have the same problem as I had and find this page:
My CherryPy server.py ran fine on my Win10 system on python3.8 but failed with segmentation fault on my Linux system which had python3.6.1.
Switching to python3.8 on Linux solved my problem.

Categories

Resources