send packets to ipv6 link local multicast addr - python

I write some sample code in different languages to send packets to ipv6 link local multicast addr(ff02::fb), but it doesn't always work.
the python version:
#!/usr/bin/env python
MYPORT = 5353
MYGROUP_6 = 'ff02::fb'
MYTTL = 1 # Increase to reach other networks
import time
import struct
import socket
import sys
def main():
sender(MYGROUP_6)
def sender(group):
addrinfo = socket.getaddrinfo(group, None)[0]
s = socket.socket(addrinfo[0], socket.SOCK_DGRAM)
# Set Time-to-live (optional)
ttl_bin = struct.pack('#i', MYTTL)
s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, ttl_bin)
while True:
data = repr(time.time())
s.sendto(data + '\0', (addrinfo[4][0], MYPORT))
time.sleep(1)
if __name__ == '__main__':
main()
this one works on linux(3.13.0-24-generic), but get error "no route to host" on OS X(10.10 Yosemite).
Then I write a simple Go program to try again:
package main
import (
"fmt"
"net"
)
func main() {
addr, err := net.ResolveUDPAddr("udp6", "[ff02::fb]:5353")
if err != nil {
fmt.Printf("ResolveUDPAddr err: %v\n", err)
return
}
if conn, err := net.DialUDP("udp6", nil, addr); err == nil {
if _, err = conn.Write([]byte("hello")); err != nil {
fmt.Printf("Write failed, %v\n", err)
}
} else {
fmt.Printf("DialUDP err: %v\n", err)
}
return
}
this one gets error "connect: invalid argument" on linux, and the same error "no route to host" with sample above on OS X. Finally, I try the low-level C language:
/*
* Examples:
* >sender 224.0.22.1 9210 6000 1000
* >sender ff15::1 2001 65000 1
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h> /* for usleep() */
#define SOCKET int
int mcast_send_socket(char* multicastIP, char* multicastPort, int multicastTTL, struct addrinfo **multicastAddr) {
SOCKET sock;
struct addrinfo hints = { 0 }; /* Hints for name lookup */
/*
Resolve destination address for multicast datagrams
*/
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_NUMERICHOST;
int status;
if ((status = getaddrinfo(multicastIP, multicastPort, &hints, multicastAddr)) != 0 )
{
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
return -1;
}
/*
Create socket for sending multicast datagrams
*/
if ( (sock = socket((*multicastAddr)->ai_family, (*multicastAddr)->ai_socktype, 0)) < 0 ) {
perror("socket() failed");
freeaddrinfo(*multicastAddr);
return -1;
}
/*
Set TTL of multicast packet
*/
if ( setsockopt(sock,
(*multicastAddr)->ai_family == PF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP,
(*multicastAddr)->ai_family == PF_INET6 ? IPV6_MULTICAST_HOPS : IP_MULTICAST_TTL,
(char*) &multicastTTL, sizeof(multicastTTL)) != 0 ) {
perror("setsockopt() failed");
freeaddrinfo(*multicastAddr);
return -1;
}
/*
set the sending interface
*/
if((*multicastAddr)->ai_family == PF_INET) {
in_addr_t iface = INADDR_ANY; /* well, yeah, any */
if(setsockopt (sock,
IPPROTO_IP,
IP_MULTICAST_IF,
(char*)&iface, sizeof(iface)) != 0) {
perror("interface setsockopt() sending interface");
freeaddrinfo(*multicastAddr);
return -1;
}
}
if((*multicastAddr)->ai_family == PF_INET6) {
unsigned int ifindex = 0; /* 0 means 'default interface'*/
if(setsockopt (sock,
IPPROTO_IPV6,
IPV6_MULTICAST_IF,
(char*)&ifindex, sizeof(ifindex)) != 0) {
perror("interface setsockopt() sending interface");
freeaddrinfo(*multicastAddr);
return -1;
}
}
return sock;
}
static void DieWithError(char* errorMessage)
{
fprintf(stderr, "%s\n", errorMessage);
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[])
{
SOCKET sock;
struct addrinfo *multicastAddr;
char* multicastIP; /* Arg: IP Multicast address */
char* multicastPort; /* Arg: Server port */
char* sendString; /* Arg: String to multicast */
int sendStringLen; /* Length of string to multicast */
int multicastTTL; /* Arg: TTL of multicast packets */
int defer_ms; /* miliseconds to defer in between sending */
int i;
if ( argc < 5 || argc > 6 )
{
fprintf(stderr, "Usage: %s <Multicast Address> <Port> <packetsize> <defer_ms> [<TTL>]\n", argv[0]);
exit(EXIT_FAILURE);
}
multicastIP = argv[1]; /* First arg: multicast IP address */
multicastPort = argv[2]; /* Second arg: multicast port */
sendStringLen = atoi(argv[3]);
defer_ms = atoi(argv[4]);
/* just fill this with some byte */
sendString = calloc(sendStringLen, sizeof(char));
for(i = 0; i<sendStringLen; ++i)
sendString[i]= 's';
multicastTTL = (argc == 6 ? /* Fourth arg: If supplied, use command-line */
atoi(argv[5]) : 1); /* specified TTL, else use default TTL of 1 */
sock = mcast_send_socket(multicastIP, multicastPort, multicastTTL, &multicastAddr);
if(sock == -1 )
DieWithError("mcast_send_socket() failed");
int nr=0;
for (;;) /* Run forever */
{
int* p_nr = (int*)sendString;
*p_nr = htonl(nr);
if ( sendto(sock, sendString, sendStringLen, 0,
multicastAddr->ai_addr, multicastAddr->ai_addrlen) != sendStringLen )
DieWithError("sendto() sent a different number of bytes than expected");
fprintf(stderr, "packet %d sent\n", nr);
nr++;
usleep(defer_ms*1000);
}
/* NOT REACHED */
return 0;
}
this C version doesn't work on OS X either, it complains "Can't assign requested address" on setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char*)&ifindex, sizeof(ifindex)), seems OS X doesn't support to choose interface automatically.
EDIT: Adding a scope id(en0) makes the go&C version work on OS X, but python(2.7.6) version still complains: "No route to host".

Related

C socket recv function returning undefined error (errno)

I am trying to make a file transfer program. I am currently programming the C server and using a short Python script as the client. When I try sending the filename from Python to C, the recv function (in C) returns an undefined error. It has received half of the filename once. Here is the code:
C server (problematic recv function is pointed out):
#define BUFFER 2000000
#define HEADERSIZE 20
#define PORT 9342
#define FGET "FGET"
#define UPLD "UPLD"
typedef struct timeval timeval_t;
int i;
fd_set readlist, sockets;
void* sendf(void* sock){
printf("File Descriptor: %d\n", *(int*)sock);
fflush(stdout);
char* filename = (char*) malloc(21*sizeof(char));
ssize_t result = recv(*(int*)sock, filename, 20+1, 0);
if (result != 0){
printf("%s", strerror(errno));
exit(0);
}
printf("Filename: ");
puts(filename);
FILE* sfile = fopen(filename, "rb");
free(filename);
fseek(sfile, 0, SEEK_END);
unsigned long long filesize = ftell(sfile);
fseek(sfile, 0, SEEK_SET);
char* content = malloc(BUFFER);
for(i=0; i<=ceil(filesize/BUFFER); ++i){
if (filesize >= BUFFER){
fread(content, BUFFER, 1, sfile);
filesize-=BUFFER;
fseek(sfile, filesize-1, SEEK_END);
} else{
fread(content, filesize, 1, sfile);
}
content = realloc(content, BUFFER);
}
fclose(sfile);
char* header = malloc(HEADERSIZE);
sprintf(header, "%20llu", filesize);
send(*(int*)sock, header, 20, 0);
send(*(int*)sock, content, filesize, 0);
free(filename);
free(content);
free(header);
return NULL;
}
void* receivef(void* sock){
printf("Function not written yet");
return NULL;
}
int main(){
chdir("/Users/reimeytal/Desktop/Fileserver");
int sock = socket(AF_INET, SOCK_STREAM, 0);
pthread_t thread;
timeval_t timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
struct sockaddr_in server;
server.sin_port = htons(PORT);
server.sin_addr.s_addr = INADDR_ANY;
server.sin_family = AF_INET;
FD_ZERO(&sockets);
FD_SET(sock, &sockets);
bind(sock, (struct sockaddr*)&server, sizeof(server));
listen(sock, 5);
int maxsock = sock;
int clientsock;
char* msghdr = (char*) malloc(5*sizeof(char));
while (1){
readlist = sockets;
select(FD_SETSIZE, &readlist, NULL, NULL, &timeout);
for(i=0; i<=maxsock; i++){
if(FD_ISSET(i, &readlist)){
if(i==sock){
clientsock = accept(sock, NULL, NULL);
FD_SET(clientsock, &sockets);
if(clientsock>sock){
maxsock = clientsock;
}
} else{
printf("Incoming message from %d\n", i);
fflush(stdout);
recv(i, msghdr, 5, 0);
clientsock = i;
if(strcmp(msghdr, FGET) == 0){
pthread_create(&thread, NULL, sendf, (int *)&clientsock);
}/*else if(strcmp(msghdr, UPLD) == 0){
pthread_create(&thread, NULL, receivef, (int*)&i);
}else{
puts("ERROR: Received invalid message header");
}*/
msghdr = (char *) realloc(msghdr, 5*sizeof(char));
}
}
}
}
return 0;
Result when running:
Incoming message from 4
File Descriptor: 4
Incoming message from 4
Incoming message from 4
Undefined error: 0
Python client:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("localhost", 9342))
sock.send(b'FGET\0')
sock.send(b'abcdeftghijklmno.txt\0')
If anyone needs my to clarify/add something, I'd be happy to do so. Thanks
There's a mistake here:
ssize_t result = recv(*(int*)sock, filename, 20+1, 0);
if (result != 0){
printf("%s", strerror(errno));
exit(0);
}
recv returns the number of bytes written, so you should check if (result <= 0).
You are getting a result code 0 because the Python app closed the connection after sending the data. Apart from that all should work.
EDIT: Removed part about timing issue that was incorrect.

Unix Domain Sockets C Server and Python Client

I need to merge the client and server code. I would appreciate your help in this regard. I share C server and client code in the combo Python. Error grapefruit are available in the bottom line.
C Server Code
#include <unistd.h>
#include <stdio.h> // standard input / output functions
#include <stdlib.h>
#include <string.h> // string function definitions
#include <fcntl.h> // File control definitions
#include <errno.h> // Error number definitions
#include <termios.h> // POSIX terminal control definitions
#include <time.h>
#include <stdint.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include "list.h"
#include "pack.h"
#define SOCK_PATH "../sockets/socketNodeServer"
#define DEBUG_FILE "./debug.txt"
#pragma pack(1)
// Structure definitions
typedef struct serialRx_s{
list* llistScatteredRx;
list* llistOrderedRx;
uint8_t scratchpad[SCRATCHPAD_SIZE];
uint8_t remaining;
uint16_t lostPackets;
uint16_t receivedPackets;
int fd;
}serialRx_t;
typedef struct serialTx_s{
list* llistTx;
uint16_t sentPackets;
int fd;
}serialTx_t;
typedef struct monitor_s{
struct serialRx_s *rx_p;
struct serialTx_s *tx_p;
FILE *fp;
}monitor_t;
#pragma pack()
// Public function prototypes
// Private function prototypes
static void *rxSerial_f(void *arg);
static void *txSerial_f(void *arg);
static void *log_f(void *arg);
static void *monitor_f(void *arg);
static int orderScattered_rxData(struct serialRx_s *rx);
static int fillupScratchpad(struct serialRx_s *rx);
static void freeNode(void *data);
static void *prep_TxGoodies(int fd);
static void *prep_RxGoodies(int fd);
static void *prep_monitoring(struct serialRx_s *rx, struct serialTx_s *tx);
static void set_blocking (int fd, int should_block);
static int set_interface_attribs (int fd, int speed, int parity);
static void *form_node_data_packet(void *buf, int len);
static int setNonBlocking(int fd);
static int set_interface_attribs (int fd, int speed, int parity)
{
struct termios tty;
memset (&tty, 0, sizeof tty);
if (tcgetattr (fd, &tty) != 0)
{
printf ("error %d from tcgetattr", errno);
return -1;
}
cfsetospeed (&tty, speed);
cfsetispeed (&tty, speed);
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
// disable IGNBRK for mismatched speed tests; otherwise receive break
// as \000 chars
tty.c_iflag &= ~IGNBRK; // disable break processing
tty.c_lflag = 0; // no signaling chars, no echo,
// no canonical processing
tty.c_oflag = 0; // no remapping, no delays
// For details about blocking in non canonical (binary mode)
// check out http://www.tldp.org/HOWTO/html_single/Serial-HOWTO/
tty.c_cc[VMIN] = 0; // read doesn't block
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
// enable reading
tty.c_cflag &= ~(PARENB | PARODD); // shut off parity
tty.c_cflag |= parity;
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CRTSCTS;
if (tcsetattr (fd, TCSANOW, &tty) != 0)
{
printf ("error %d from tcsetattr", errno);
return -1;
}
return 0;
}
static void set_blocking (int fd, int should_block)
{
struct termios tty;
memset (&tty, 0, sizeof tty);
if (tcgetattr (fd, &tty) != 0)
{
printf ("error %d from tggetattr", errno);
return;
}
tty.c_cc[VMIN] = should_block ? 1 : 0;
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
if (tcsetattr (fd, TCSANOW, &tty) != 0)
printf ("error %d setting term attributes", errno);
}
static void * prep_monitoring(struct serialRx_s *rx, struct serialTx_s *tx)
{
struct monitor_s *monitor_p = NULL;
monitor_p = (struct monitor_s *)malloc(sizeof(struct monitor_s));
if(NULL == monitor_p){
return NULL;
}
monitor_p->rx_p = rx;
monitor_p->tx_p = tx;
monitor_p->fp = fopen(DEBUG_FILE, "w+");
return monitor_p;
}
static void *prep_RxGoodies(int fd)
{
struct serialRx_s *rx = NULL;
rx = (struct serialRx_s *)malloc(sizeof(struct serialRx_s));
rx->llistScatteredRx = create_list();
rx->llistOrderedRx = create_list();
rx->fd = fd;
memset(rx->scratchpad, 0, sizeof(rx->scratchpad));
rx->remaining = 0;
rx->lostPackets = 0;
rx->receivedPackets = 0;
return rx;
}
static void *prep_TxGoodies(int fd)
{
struct serialTx_s *tx = NULL;
tx = (struct serialTx_s *)malloc(sizeof(struct serialTx_s));
tx->llistTx = create_list();
tx->fd = fd;
tx->sentPackets = 0;
return tx;
}
static void freeNode(void *data)
{
free( (uint8_t *)data);
}
static int fillupScratchpad(struct serialRx_s *rx)
{
int targetNodeIndex = -1;
int nodeLen = 0;
uint8_t *nodeData = NULL;
int offset = 0;
uint8_t *pointer = NULL;
targetNodeIndex = payloadLen_2_index(rx->llistScatteredRx, PACKET_SIZE - rx->remaining);
//printf("targetNodeIndex value %d\n", targetNodeIndex);
for(int i=0; i <= targetNodeIndex ; i++){
offset = rx->remaining;
pointer = (uint8_t *)front(rx->llistScatteredRx); // first byte is for length
nodeLen = pointer[0];
//nodeLen = ((uint8_t *)front(rx->llistScatteredRx))[0]; // first byte is for length
//printf("nodeLen in fillupScratchpad %d\n", nodeLen);
nodeData = (uint8_t *)front(rx->llistScatteredRx) + 1; // first byte is for length
memcpy(rx->scratchpad + offset, nodeData, nodeLen);
rx->remaining += nodeLen;
//for(int j=0; j<rx->remaining; j++)
//{
// printf("scratchpad[%d]: %X\n", j, (rx->scratchpad)[j]);
//}
remove_front(rx->llistScatteredRx, freeNode);
}
return targetNodeIndex;
}
static int orderScattered_rxData(struct serialRx_s *rx)
{
int packetBeginIndex = 0;
struct raw_node_data_s *raw = NULL;
// parse the scratchpad buffer until the last remaining byte
// note that since we have a larger buffer size than what we use
// it's safe to do this.
for(int i=0; i < (rx->remaining) ; i++)
{
// Check whether we have a suitable package
if(rx->scratchpad[i] == START_CODE &&
rx->scratchpad[i+PACKET_SIZE-1] == STOP_CODE)
{
//printf("start & stop matches\n");
raw = (struct raw_node_data_s *)malloc(sizeof(struct raw_node_data_s));
memcpy(raw, rx->scratchpad + i, sizeof(struct raw_node_data_s));
//print_raw_node_data(raw);
push_back(rx->llistOrderedRx, raw);
rx->receivedPackets++;
//TODO: Check for CRC
// clear up memory area between beginning of scratchpad and Stop_Code
memset(rx->scratchpad, 0, i+PACKET_SIZE-1);
// move remaining bytes to the beginning of scratchpad buffer
// no overlapping should occur but still, use memmove instead of memcpy
memmove(rx->scratchpad,
rx->scratchpad + i + PACKET_SIZE, // point to right after the healthy packet
rx->remaining - ( i + PACKET_SIZE)); // get remaining bytes after packet end
// update remaining bytes value
rx->remaining = rx->remaining - (i + PACKET_SIZE);
packetBeginIndex = i; // success
break;
}
}
// if no packets can be formed, check whether we are running out of
// scratchpad buffer, clear up memory if this is the case. Make sure
// to increase packet lost counter
//if( !packetBeginIndex && (rx->remaining >= 2 * PACKET_SIZE) )
if( (rx->remaining >= (3 * PACKET_SIZE)) )
{
printf("we are running out of space\n");
printf("scratchpad size: %d\n", rx->remaining);
for(int i=0; i < (rx->remaining) ; i++)
{
if(rx->scratchpad[i] == START_CODE){
// clear up the first packet area and move up the
// remaining bytes to the beginning of buffer
memset(rx->scratchpad, 0, i-1);
memmove(rx->scratchpad,
rx->scratchpad + i,
rx->remaining - i );
rx->remaining -= i;
rx->lostPackets += 1;
}
}
}
// don't care for START_CODE, clear up an area
// big enough to hold a full packet
if((rx->remaining >= 3 * PACKET_SIZE)){
printf("buffer is a complete mess, clear up stuff\n");
// buffer is a complete mess,
// clear up a whole packet
memset(rx->scratchpad, 0, PACKET_SIZE);
memmove(rx->scratchpad,
rx->scratchpad + PACKET_SIZE+1,
rx->remaining - PACKET_SIZE);
rx->remaining -= PACKET_SIZE;
rx->lostPackets += 1;
}
//for(int j=0; j<rx->remaining; j++)
//{
// printf("scratchpad after cleanup[%d]: %X\n", j, (rx->scratchpad)[j]);
//}
return packetBeginIndex;
}
static void *txSerial_f(void *arg)
{
struct serialTx_s *tx = (struct serialTx_s *)arg;
struct raw_node_data_s *txRaw = NULL;
int n = 0;
//txRaw = prep_transaction_data();
//print_raw_node_data(txRaw);
sleep(1);
while(1)
{
//n = write(tx->fd, txRaw, sizeof(txRaw));
if(size(tx->llistTx)){
txRaw = front(tx->llistTx);
n = write(tx->fd, txRaw, PACKET_SIZE);
//printf("sending %d bytes via serial \n", n);
remove_front(tx->llistTx, freeNode);
tx->sentPackets += 1;
}
sleep(1);
}
return NULL;
}
static void *form_node_data_packet(void *buf, int len)
{
struct raw_node_data_s *raw = NULL;
raw = (struct raw_node_data_s *)malloc(sizeof(struct raw_node_data_s));
if(!raw){
fprintf(stderr,"can't allocate memory for raw node\n");
return NULL;
}
memcpy(raw, buf, len);
//print_raw_node_data(raw);
return raw;
}
//TODO: Move this function to a new source file for socket operations
static int setNonBlocking(int fd)
{
int flags;
/* if O_NONBLOCK is defined, use the fcntl function */
if(-1 == (flags = fcntl(fd, F_GETFL, 0))){
flags = 0;
}
return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}
static void *monitor_f(void *arg)
{
struct monitor_s *mon = (struct monitor_s *)arg;
struct raw_node_data_s *txRaw = NULL;
uint8_t rxbuf[100];
// socket operation related variables
int fdBind, fdAccept;
int t, len, status;
struct sockaddr_un local;
struct sockaddr_un remote;
if(-1 == (fdBind = socket(AF_UNIX, SOCK_STREAM, 0)))
{
fprintf(stderr, "can't open socket: %s\n", strerror(errno));
return (void *)NULL;
}
local.sun_family = AF_UNIX;
strcpy(local.sun_path, SOCK_PATH);
unlink(local.sun_path);
len = strlen(local.sun_path) + sizeof(local.sun_family);
if( bind(fdBind, (struct sockaddr *)&local, len) == -1){
fprintf(stderr, "can't bind: %s\n", strerror(errno));
return (void *)NULL;
}
if(-1 == listen(fdBind, 5)){ // number of listenes can actually be less
fprintf(stderr, "can't listen: %s\n", strerror(errno));
return (void *)NULL;
}
for(;;){
socklen_t size = sizeof(remote);
int rcvdBytes = 0;
fprintf(stderr, "waiting for a connection\n");
if( -1 == (fdAccept = accept(fdBind, (struct sockaddr *)&remote, &size)) )
{
fprintf(stderr, "can't accept: %s\n", strerror(errno));
return (void *)NULL;
}
//setNonBlocking(fdAccept);
status = 1;
printf("connected\n");
do{
if( (t = recv(fdAccept, rxbuf, 100, 0)) > 0){
fprintf(stderr, "incoming bytes len from server: %d\n", t);
for(int ii=0; ii < t; ii++){
printf("incoming data[%i]:%X\n", ii, rxbuf[ii]);
}
txRaw = (struct raw_node_data_s *)form_node_data_packet(rxbuf, t);
push_back(mon->tx_p->llistTx, txRaw);
}else if(t < 0){
perror("recv"); // if nonblocking then wouldhaveblocked would come here too
}else{
fprintf(stderr, "server closed connection\n");
status = 0;
}
usleep(200);
}while(status);
sleep(2);
close(fdBind);
} // while(1), thread start
return NULL;
}
static void *log_f(void *arg)
{
struct monitor_s *log = (struct monitor_s *)arg;
struct raw_node_data_s *rxRaw = NULL;
while(1)
{
if( size(log->rx_p->llistOrderedRx)){
rxRaw = front(log->rx_p->llistOrderedRx);
printf("log thread\n");
print_raw_node_data(rxRaw);
remove_front(log->rx_p->llistOrderedRx, freeNode);
//fprintf(mon->fp, "\rSent Packets: %d", i);
fprintf(log->fp, "Sent Packets: %d\n", log->tx_p->sentPackets);
fprintf(log->fp, "Received Packets: %d\n", log->rx_p->receivedPackets);
fprintf(log->fp, "Dropped Packets: %d\n", log->rx_p->lostPackets);
fflush(log->fp);
sleep(1);
}
} // while (1)
return NULL;
}
static void *rxSerial_f(void *arg)
{
struct serialRx_s *rx = (struct serialRx_s *)arg;
int n = 0;
uint8_t buf[100] = {0};
uint8_t *dataPack = NULL;
tcflush(rx->fd, TCIFLUSH); /* Discards old data in the rx buffer */
while(1)
{
n = read(rx->fd, (uint8_t *)buf, sizeof(struct raw_node_data_s));
//for(int ii=0; ii < n; ii++){
// printf("incoming serial data[%i]:%X\n", ii, ((uint8_t *)buf)[ii]);
//}
if(n > 0){
//printf("read %d bytes\n", n);
dataPack = (uint8_t *)malloc(sizeof(uint8_t)* n);
dataPack[0] = n;
memcpy(dataPack + 1, buf, sizeof(uint8_t)*n);
push_back(rx->llistScatteredRx, dataPack);
//printf("linked list size after read: %d\n", size(rx->llistScatteredRx));
//for(int i=0; i<n; i++)
//{
// printf("read data[%d]: %X\n", i, dataPack[i+1]);
//}
dataPack = NULL;
memset(buf, 0, sizeof(buf)); // clear up
// Check whether we have enough data in the
// scratchpad to forma packet
fillupScratchpad(rx);
orderScattered_rxData(rx);
}else if(n < 0){
printf("error in read operation\n");
}else{
//printf("no data - rx\n");
}
sleep(1);
} // while(1)
return NULL;
} //void *rxSerial_f(void *arg)
// *************************************************
// *************************************************
// *************************************************
// ************** TODO *************************
// * Have thread functions in seperate files
// * Implement CRC check mechanism
// * Implement DAC switch mechanism
// * Implement for loop on writes to Serial Device
// to make sure that all data is sent on the tx line
int main(void)
{
pthread_t idThreadSerial[2]; // wr, rd
char *portname = "/dev/ttyS2";
struct serialRx_s *serialRx_p = NULL;
struct serialTx_s *serialTx_p = NULL;
struct monitor_s *monitor_p = NULL;
srand(time(NULL)); // generate seed data for random()
printf("size of raw_node_data_s structure: %ld\n", sizeof(struct raw_node_data_s));
int fd = open (portname, O_RDWR | O_NOCTTY | O_SYNC);
set_interface_attribs (fd, B38400, 0); // set speed to 38400 bps, 8n1 (no parity)
//set_blocking (fd, 0); // set no blocking
serialTx_p = (struct serialTx_s *)prep_TxGoodies(fd);
serialRx_p = (struct serialRx_s *)prep_RxGoodies(fd);
monitor_p = (struct monitor_s *)prep_monitoring(serialRx_p, serialTx_p);
fwrite ("hello!\n", sizeof(uint8_t), 7, stdout);
sleep(1);
pthread_create(&idThreadSerial[3], NULL, log_f, (void *)monitor_p);
pthread_create(&idThreadSerial[2], NULL, monitor_f, (void *)monitor_p);
//pthread_create(&idThreadSerial[1], NULL, rxSerial_f, (void *)serialRx_p);
//pthread_create(&idThreadSerial[0], NULL, txSerial_f, (void *)serialTx_p);
pthread_join(idThreadSerial[0], NULL);
pthread_join(idThreadSerial[1], NULL);
pthread_join(idThreadSerial[2], NULL);
pthread_join(idThreadSerial[3], NULL);
fwrite("all threads returned, exiting now...\n", sizeof(uint8_t), 40, stdout);
return 0;
}
Python Client Code
# -*- coding: utf-8 -*-
import socket
import os, os.path
print "Connecting..."
if os.path.exists( "../sockets/socketNodeServer" ):
client = socket.socket( socket.AF_UNIX, socket.SOCK_DGRAM )
client.connect( "../sockets/socketNodeServer" )
print "Ready."
print "Ctrl-C to quit."
print "Sending 'DONE' shuts down the server and quits."
while True:
try:
x = raw_input( "> " )
if "" != x:
print "SEND:", x
client.send( x )
if "DONE" == x:
print "Shutting down."
break
except KeyboardInterrupt, k:
print "Shutting down."
client.close()
else:
print "Couldn't Connect!"
print "Done
"
Error
Connecting...
Traceback (most recent call last):
File "client.py", line 8, in <module>
client.connect( "../sockets/socketNodeServer" )
File "/usr/lib/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 91] Protocol wrong type for socket
In your C-Code you create a stream
fdBind = socket(AF_UNIX, SOCK_STREAM, 0)
and in Python a datagram:
client = socket.socket( socket.AF_UNIX, socket.SOCK_DGRAM )
Sure, this is a wrong type for socket. Use the same STREAM or DGRAM on both sides.

Python 3 socket client sending data and C++ socket server receiving data with offset?

I have made a small test to send an integer from a python application (client socket) to a c++ application (socket server) both are TCP stream sockets. I have also tested sending the same integer from the client socket in python to a server socket in python.
What I do is I send an array of 4 bytes (char in c++), each char has the integer shifted right (>>) like this (python syntax):
...
[my_int >> i & 0xff for i in (24,16,8,0)]:
...
The problem is that when sending from the client socket in python to the server socket in python the data "arrives ok", for instance if I send the integer 1390248303
the python server socket first prints the bytes stream received then for each byte it prints its ascii code and then I do:
sum([l[3-i] << 8*i for i in (3,2,1,0)])
to "rebuild" the integer and this is the result (which is ok):
RECEIVED: b'R\xdd\x81o'
82
221
129
111
RECEIVED: 1390248303
BUT the C++ server socket, in which I do the same but with more verbose in the code:
...
int sum = 0;
int term = 0;
for(int i = 3;i > -1;i--)
{
printf("%d\n",msg[3-i]);
term = msg[3-i];
//if (term < 0)
// term = 256 + term;
suma += term << 8*i;
};
printf("Received: %d\n",sum);
...
Outputs
82
-35
-127
111
Received: 1373405551
Did you see that the 2 bytes in the middle are different to the 2 bytes in the middle corresponding to what the server socket in python outputs? Not only that but if I add 256 to them they became the same:
-35 + 256 = 221
-127 + 256 = 129
What is the reason of this behaviour? Thanks beforehand for any hint!
Here is the code of the applications:
python client socket:
import socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(("localhost", 7000))
my_int = 1390248303
my_bytes = bytearray()
for e in [my_int >> i & 0xff for i in (24,16,8,0)]:
my_bytes.append(e)
print("To be sent:", my_bytes)
client_socket.send(my_bytes)
print("Sent:", my_bytes)
client_socket.close()
python server socket:
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("", 7000))
server_socket.listen(5)
print("TCPServer Waiting for client on port 7000")
while 1:
client_socket, address = server_socket.accept()
print("I got a connection from ", address)
while 1:
data = client_socket.recv(32)
print("RECEIVED:",data)
l = []
for e in data:
l.append(e)
print(e)
print("RECEIVED:",sum([l[3-i] << 8*i for i in (3,2,1,0)]))
if (data == b''):
break;
break;
C++ server socket:
#define WIN32_LEAN_AND_MEAN
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <stdio.h>
#include <stdlib.h>
// link with Ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")
#define DEFAULT_PORT "7000"
//"27015"
#define DEFAULT_BUFFER_LENGTH 32
//512
int main() {
WSADATA wsaData;
// Initialize Winsock
int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if(iResult != 0)
{
printf("WSAStartup failed: %d\n", iResult);
return 1;
}
struct addrinfo *result = NULL,
hints;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET; // Internet address family is unspecified so that either an IPv6 or IPv4 address can be returned
hints.ai_socktype = SOCK_STREAM; // Requests the socket type to be a stream socket for the TCP protocol
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
// Resolve the local address and port to be used by the server
iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if (iResult != 0)
{
printf("getaddrinfo failed: %d\n", iResult);
WSACleanup();
return 1;
}
SOCKET ListenSocket = INVALID_SOCKET;
// Create a SOCKET for the server to listen for client connections
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET)
{
printf("Error at socket(): %d\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
// Setup the TCP listening socket
iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR)
{
printf("bind failed: %d", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
freeaddrinfo(result);
// To listen on a socket
if ( listen(ListenSocket, SOMAXCONN) == SOCKET_ERROR)
{
printf("listen failed: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
SOCKET ClientSocket;
ClientSocket = INVALID_SOCKET;
// Accept a client socket
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET)
{
printf("accept failed: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
char recvbuf[DEFAULT_BUFFER_LENGTH];
int iSendResult;
// receive until the client shutdown the connection
do {
iResult = recv(ClientSocket, recvbuf, DEFAULT_BUFFER_LENGTH, 0);
if (iResult > 0)
{
char msg[DEFAULT_BUFFER_LENGTH];
memset(&msg, 0, sizeof(msg));
strncpy(msg, recvbuf, iResult);
printf("Received: %s\n", msg);
//Here is where I implement the python code:
//sum([l[3-i] << 8*i for i in (3,2,1,0)]));
int sum = 0;
int term = 0;
for(int i = 3;i > -1;i--)
{
printf("%d\n",msg[3-i]);
term = msg[3-i];
//if (term < 0)
// term = 256 + term;
sum += term << 8*i;
};
printf("Received: %d\n",sum);
iSendResult = send(ClientSocket, recvbuf, iResult, 0);
if (iSendResult == SOCKET_ERROR)
{
printf("send failed: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
getchar();
return 1;
}
printf("Bytes sent: %ld\n", iSendResult);
}
else if (iResult == 0)
printf("Connection closed\n");
else
{
printf("recv failed: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
getchar();
return 1;
}
} while (iResult > 0);
// Free the resouces
closesocket(ListenSocket);
WSACleanup();
getchar();
//while (true){};
return 0;
}
msg[] is declared as char which is not guaranteed to be unsigned. Use unsigned char.
Both of lines
printf("%d\n",msg[3-i]);
term = msg[3-i];
cast to signed integer. %d formats to signed integer, use %u. term is declared as int, make it unsigned int.
Following #Ante advices, I changed the code in C++ server socket, I also changed recvbuf to unsigned char and sum from int to unsigned int for consistency (after all I am waiting to receiving unsigned chars and "rebuild" an unsigned int) but it also worked leaving both recvbuf and sum as they were. I left commented what was before.
The problem was that for representing an integer so big I was actually using an unsigned integer and the bytes that were being sent were ascii codes whose range is 0 - 255 (the same range of unsigned char) and char range is -127 - 126.
Nevertheless, sockets do not care about data types, they just send binary data so I was receiveng unsigned chars that when bein put in a char they "overflow" and go negative (technically it is because of how two's complement works I think).
A few more notes about the corrected code:
1) This
if (term < 0)
term = 256 + term;
is no longer necessary (actually I was fixing manually the issue of the overflow).
2) I had to use cast to char* (char ) in order to be able to use recv,strncpy and send which take char as parameters not unsigned char* . This work and I think it is not hackish because both a pointer to char and a pointer to unsigned char point to a datatype with the same size in memory (8 bits). If this is wrong or could lead to unwanted or unexpected behaviour please correct me.
//char recvbuf[DEFAULT_BUFFER_LENGTH];
unsigned char recvbuf[DEFAULT_BUFFER_LENGTH];
int iSendResult;
// receive until the client shutdown the connection
do {
//iResult = recv(ClientSocket, recvbuf, DEFAULT_BUFFER_LENGTH, 0);
iResult = recv(ClientSocket, (char *)recvbuf, DEFAULT_BUFFER_LENGTH, 0);
if (iResult > 0)
{
//char msg[DEFAULT_BUFFER_LENGTH];
unsigned char msg[DEFAULT_BUFFER_LENGTH];
memset(&msg, 0, sizeof(msg));
//strncpy((msg, recvbuf, iResult);
strncpy((char *)msg, (char *)recvbuf, iResult);
printf("Received: %s\n", msg);
//sum([l[3-i] << 8*i for i in (3,2,1,0)]));
//int sum = 0;
unsigned int sum = 0;
//int term = 0;
unsigned int term = 0;
for(int i = 3;i > -1;i--)
{
//printf("%d\n",msg[3-i]);
printf("%u\n",msg[3-i]);
term = msg[3-i];
sum += term << 8*i;
};
//printf("Received: %d\n",sum);
printf("Received: %u\n",sum);
//iSendResult = send(ClientSocket, recvbuf, iResult, 0);
iSendResult = send(ClientSocket, (char *) recvbuf, iResult, 0);

Passing a string from C to Python, what does the Python server see it as? [duplicate]

How can I convert the input from the client from the server to a string or some other data type. My server can print the recvline from clients but doesn't recognize it as a common data type...
void timing()
{
for (long i = 0; i < 200000000; i ++){
printf("");
}
}
int main(int argc, char **argv){
int i;
int sockfd;
struct sockaddr_in servaddr;
char sendline[MAXLINE];
char recvline[MAXLINE];
time_t start, finish, final;
start = clock();
timing(); // a function that takes a differential time based on the client
finish = clock();
final = (finish - start) / CLOCKS_PER_SEC;
printf("timing: %ld\n", final);
if (argc != 2){
perror("usage: tcpcli <IPaddress>");
exit(-1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
char ** temp = NULL;
char * timing = NULL;
strtol(timing, temp, final); //***Problem here
write(sockfd, timing, 5);
bzero(recvline, MAXLINE);
if (read(sockfd, recvline, MAXLINE) == 0){ //reads from server
perror("Server terminated!");
exit(-1);
}
fputs(recvline, stdout);

web application firewall development

I have an assignment to develop a web application firewall. I have been researching for some source codes about that.My main source was ModSecurity.
Main question is that:
-Which framework or programming language I can use, to develop a web application firewall? Which one would be the most useful?
-Can I use Django & Python?
It would be a starting point for the project research.
OK, so my guess was basically correct, although I thought it was protecting an app with no or bad security, but it's more about protecting against attacks. In that Case, Django is definitely wrong. It's clearly doable in Python, but don't expect to be able to handle 100.000 requests per second. :) But if it's research and development, I think Python can be a great choice, as it's fast to develop in, and with tools like Cython it can be quite fast to run as well. Should you then end up making a finished product that does need extreme performance, you can take the algorithms and translate them to C/C++.
I'd look into Twisted in your case. That may be the correct solution.
"It will be used on the server side to control the user transactions via HTTP."
Most web application frameworks have security settings. These are usually not called "firewalls", and you didn't answer my questions, so I'm going to guess here:
You are writing a web proxy that will act to filter out requests which do not have the correct permission because there is an application which does not have any access control at all. Is this correct?
Yes, you can do that in Python. Django is probably not the correct solution. If you need to implement access control with login pages and user management, then you probably want SQL and templating and a lightweight Python framework could be helpful. Otherwise Twisted or just doing it with the functionality in standard lib might be the correct solution.
this is what you need to do, for start use Linux, much easier to handle then Windows, you have 2 options, the first is to implement NetFilter driver by hooking to the system calls (More Complex!) , the second is to use libnetfilter_queue library and iptables to transfer the packet to a user space application, the main idea is to do deep analysis to the payload beside checking the IP and TCP header, very similar IDS,IPS systems but it's focusing on web application security holes.
i don't think you can do this with python without deeper interfering, what you asking here is pretty tricky, it's involved the lowers levels of the system...
you can start analyze the data using this example:
configure the iptables
#: iptables -A INPUT -j NFQUEUE --queue-balance 0:3
#: iptables -A OUTPUT -j NFQUEUE --queue-balance 4:8
queues 0 to 3 is for all inputs (better to divided to different queue, there is limit for packets the queue can hold),the other are for all outputs
writing application in C (the iptables transfer the packet from the kernel to user space)
filterQueue.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <linux/types.h>
#include <string.h>
/* for ethernet header */
#include<net/ethernet.h>
/* for UDP header */
#include<linux/udp.h>
/* for TCP header */
#include<linux/tcp.h>
/* for IP header */
#include<linux/ip.h>
/* -20 (maximum priority) */
#include <sys/time.h>
#include <sys/resource.h>
/* for NF_ACCEPT */
#include <linux/netfilter.h>
/* for Threads */
#include <pthread.h>
/* for Queue */
#include <libnetfilter_queue/libnetfilter_queue.h>
#define NUM_THREADS 15
pthread_t threads[NUM_THREADS];
void printTCP(unsigned char *buffer) {
unsigned short iphdrlen;
struct iphdr *iph = (struct iphdr *) (buffer + sizeof(struct ethhdr));
iphdrlen = iph->ihl * 4;
struct tcphdr *tcph = (struct tcphdr *) (buffer + iphdrlen
+ sizeof(struct ethhdr));
int header_size = sizeof(struct ethhdr) + iphdrlen + tcph->doff * 4;
printf("| Packet Type: TCP \n");
printf("|-Source Port : %u\n", ntohs(tcph->source));
printf("|-Destination Port : %u\n", ntohs(tcph->dest));
printf("|-Sequence Number : %u\n", ntohl(tcph->seq));
printf("|-Acknowledge Number : %u\n", ntohl(tcph->ack_seq));
printf("|-Header Length : %d DWORDS or %d BYTES\n",
(unsigned int) tcph->doff, (unsigned int) tcph->doff * 4);
printf("|-CWR Flag : %d\n", (unsigned int) tcph->cwr);
printf("|-ECN Flag : %d\n", (unsigned int) tcph->ece);
printf("|-Urgent Flag : %d\n", (unsigned int) tcph->urg);
printf("|-Acknowledgement Flag : %d\n", (unsigned int) tcph->ack);
printf("|-Push Flag : %d\n", (unsigned int) tcph->psh);
printf("|-Reset Flag : %d\n", (unsigned int) tcph->rst);
printf("|-Synchronise Flag : %d\n", (unsigned int) tcph->syn);
printf("|-Finish Flag : %d\n", (unsigned int) tcph->fin);
printf("|-Window : %d\n", ntohs(tcph->window));
printf("|-Checksum : %d\n", ntohs(tcph->check));
printf("|-Urgent Pointer : %d\n", tcph->urg_ptr);
}
void printUDP(unsigned char *buffer) {
unsigned short iphdrlen;
struct iphdr *iph = (struct iphdr *) (buffer + sizeof(struct ethhdr));
iphdrlen = iph->ihl * 4;
struct udphdr *udph = (struct udphdr*) (buffer + iphdrlen
+ sizeof(struct ethhdr));
int header_size = sizeof(struct ethhdr) + iphdrlen + sizeof udph;
printf("| Packet Type: UDP \n");
printf("|-Source Port : %u\n", ntohs(udph->source));
printf("|-Destination Port : %u\n", ntohs(udph->dest));
printf("|-UDP Length : %u\n", ntohs(udph->len));
printf("|-UDP Checksum : %u\n", ntohs(udph->check));
}
char * getText(unsigned char * data, char Size) {
char * text = malloc(Size);
int i = 0;
for (i = 0; i < Size; i++) {
if (data[i] >= 32 && data[i] <= 128)
text[i] = (unsigned char) data[i];
else
text[i] = '.';
}
return text;
}
u_int32_t analyzePacket(struct nfq_data *tb, int *blockFlag) {
//packet id in the queue
int id = 0;
//the queue header
struct nfqnl_msg_packet_hdr *ph;
//the packet
char *data;
//packet size
int ret;
//extracting the queue header
ph = nfq_get_msg_packet_hdr(tb);
//getting the id of the packet in the queue
if (ph)
id = ntohl(ph->packet_id);
//getting the length and the payload of the packet
ret = nfq_get_payload(tb, &data);
if (ret >= 0) {
printf("Packet Received: %d \n", ret);
/* extracting the ipheader from packet */
struct sockaddr_in source, dest;
unsigned short iphdrlen;
struct iphdr *iph = ((struct iphdr *) data);
iphdrlen = iph->ihl * 4;
memset(&source, 0, sizeof(source));
source.sin_addr.s_addr = iph->saddr;
memset(&dest, 0, sizeof(dest));
dest.sin_addr.s_addr = iph->daddr;
printf("|-Source IP: %s\n", inet_ntoa(source.sin_addr));
printf("|-Destination IP: %s\n", inet_ntoa(dest.sin_addr));
printf("|-Checking for Protocol: \n");
if (iph->protocol == 6) {
printTCP(data);
} else if (iph->protocol == 17) {
printUDP(data);
}
printf("|-Extracting Payload: \n");
char * text = getText(data, ret);
//filtering requests for facebook
if (text && text[0] != '\0') {
printf("\n %s \n", text);
ret = strstr(text, "facebook");
if (ret == 0)
//not found in string
*blockFlag = 0;
else
//found in string
*blockFlag = 1;
}
//release the packet
free(text);
}
//return the queue id
return id;
}
int packetHandler(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_data *nfa,
void *data) {
printf("entering callback \n");
//when to drop
int blockFlag = 0;
//analyze the packet and return the packet id in the queue
u_int32_t id = analyzePacket(nfa, &blockFlag);
//this is the point where we decide the destiny of the packet
if (blockFlag == 0)
return nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL);
else
return nfq_set_verdict(qh, id, NF_DROP, 0, NULL);
}
void *QueueThread(void *threadid) {
//thread id
long tid;
tid = (long) threadid;
struct nfq_handle *h;
struct nfq_q_handle *qh;
char buf[128000] __attribute__ ((aligned));
//pointers and descriptors
int fd;
int rv;
int ql;
printf("open handle to the netfilter_queue - > Thread: %d \n", tid);
h = nfq_open();
if (!h) {
fprintf(stderr, "cannot open nfq_open()\n");
return NULL;
}
//unbinding previous procfs
if (nfq_unbind_pf(h, AF_INET) < 0) {
fprintf(stderr, "error during nfq_unbind_pf()\n");
return NULL;
}
//binding the netlink procfs
if (nfq_bind_pf(h, AF_INET) < 0) {
fprintf(stderr, "error during nfq_bind_pf()\n");
return NULL;
}
//connet the thread for specific socket
printf("binding this socket to queue '%d'\n", tid);
qh = nfq_create_queue(h, tid, &packetHandler, NULL);
if (!qh) {
fprintf(stderr, "error during nfq_create_queue()\n");
return NULL;
}
//set queue length before start dropping packages
ql = nfq_set_queue_maxlen(qh, 100000);
//set the queue for copy mode
if (nfq_set_mode(qh, NFQNL_COPY_PACKET, 0xffff) < 0) {
fprintf(stderr, "can't set packet_copy mode\n");
return NULL;
}
//getting the file descriptor
fd = nfq_fd(h);
while ((rv = recv(fd, buf, sizeof(buf), 0)) && rv >= 0) {
printf("pkt received in Thread: %d \n", tid);
nfq_handle_packet(h, buf, rv);
}
printf("unbinding from queue Thread: %d \n", tid);
nfq_destroy_queue(qh);
printf("closing library handle\n");
nfq_close(h);
return NULL;
}
int main(int argc, char *argv[]) {
//set process priority
setpriority(PRIO_PROCESS, 0, -20);
int rc;
long balancerSocket;
for (balancerSocket = 0; balancerSocket < NUM_THREADS; balancerSocket++) {
printf("In main: creating thread %ld\n", balancerSocket);
//send the balancer socket for the queue
rc = pthread_create(&threads[balancerSocket], NULL, QueueThread,
(void *) balancerSocket);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
while (1) {
sleep(10);
}
//destroy all threads
pthread_exit(NULL);
}
Unless this is just some kind of academic exercise and Python helps you get it done fast, I don't think a high level language like Python is the best choice for a firewall (I don't even know if it's possible honestly). If you're planning some sort of proxy/filter application, that might be fine, but Django isn't needed either way.
Django is a web application framework. I don't see anyone writing a firewall implementation using it.
C, C++, Golang, Lua are all optional languages to develop a Web Application Firewall or Gateway, but django is not suitable for it.
C, C++ can develop nginx plugin or backend WAF.
Golang can develop gateway with WAF, such as Janusec Application Gateway.
Lua can extend nginx access control and work as a WAF.

Categories

Resources