Tuesday, August 11, 2009

dnss.c

// linux code
// no syn with multiple threads: sema for shared
// global structures: peers[] and requests[]
//

// infoblox: platform
// DNS--DHCP--IPMP-HTTP
// sercices: reduancy, power, 4 disk RAID, hot swappable
// lan1
// lan2 Ge
// HA port Ge
// MGMT port Ge
// RAID10 (4)--automatically resync
//
// IPAM connector:

#include
#include
#include
#include
#include
#include
#include
#include
#include

#include
#include
#include
#include
#include
#include
#include


#define DEBUG 0
#define DEFAULT_BIND_IP "127.0.0.1"

#define DEFAULT_PORT 53

//169.254.0.0/16: link local
//224.0.0.1: mcast
//192.88.99.0/24: v6 in v4 relay
#define HELP_STR "" \
"syntax: error\n" \
"\n"
typedef struct peer_s {
struct sockaddr_in tcp;
int tcp_fd;
time_t timeout;
int con; //con state: 0=dead, 1 = conn, 3 = connected
unsigned char b[1502];


int bl; // number of bytes
} peer_t;

typedef struct request_s {
struct sockaddr_in a;
socklen_t al;
unsigned char b[1502];
int bl;
int id;
int rid; // dns req id
int active;
time_t timeout;
} request_t;

unsigned long int *nameservers; // nameserver pool, use linklist?
int num_nameservers;

peer_t peers[MAX_PEERS]; // tcp peers
request_t requests[MAX_REQUESTS]; // req queue: use que/vector/linklist
int udp_fd; // port 53 socket

int f(int x, int y, int z) {
}

int request_find(int id) {
int pos = id % MAX_REQUESTS;
for (;;) {
if (requests[pos].id == id) {
//found
return pos;
} else {
pos++;
pos %= MAX_REQUESTS;
if (pos == (id % MAX_REQUESTS)) {
// can not find
return -1;
}
}
}
}

int peer_connect(int peer, int ns) {
peer_t *p = &peers[peer];
int r = 1;
int cs;


if ((p->tcp_fd = socket(AF_INET, SOCKET_STREAM, 0)) < 0) {
return 0;
}

if (setsockopt(p->tcp_fd, SOL_SOCKET, SO_REUSEADDR, &r, sizeof(int)))
perror("setsockopt failed: \n");
if (fcntl(p->tcp_fd, F_SETFL, O_NONBLOCK))
perror("setting o_nonblock failed\n");

p->tcp.sin_family = AF_INET;
p->tcp.sin_port = htons(DEFAULT_PORT);
p->tcp.sin_addr.s_addr = nameservers[ns]; // name server pool

#ifdef DEBUG
printf("connecting to: %s\n", inet_ntoa(p->tcp.sin_addr));
#endif

cs = connect(p->tcp_fd, (struct sockaddr *)&(p->tcp),
sizeof(struct sockaddr_in));
// select?
if (cs != 0)
perror("connect failed\n");
else
printf("connect return 0\n");

p->bl = 0;
p->con = 1;

return 1; // done
}

int peer_connected(int peer) {
peer_t *p = &peers[peer];
int cs;


cs = connect(p->tcp_fd, (struct sockaddr *)&p->tcp, sizeof(struct sockaddr_in));
if (cs == 0) {
p->con = 3; // failed
return 1;
} else {
printf("connection failed\n");
close(p->tcpfd);

p->tcp_fd = -1;
p->con = 0;

return 0;
}
}

int peer_keepalive(int peer) {
return 1;
}

int peer_sendreq(int peer, int req) {
peer_t *p = &peers[peer];
request_t *r = &requests[req];
int ret;

printf("%s, %d\n", __FUNCTION__, __LINE__);
while((ret = write(p->tcp_fd, r->b, (r->bl+2))) < 0
&& errno = EAGAIN); // incase loop forever: + timer or select()

if (ret ==0) {
close(p->tcp_fd);
p->tcp_fd = -1;
p->con = 0;
printf("peer %d got disconnectedn", peer);
return 2;
}

return 1;
}

int peer_readres(int peer) {
peer_t *p = &peers[peer];
request_t *r;
int ret;
unsigned short int *ul;
int id;
int req;
int len;


while((ret = read(p->tcp_fd, (p->b + p->bl),
(1502-p->bl))) < 0
&& errno = EAGAIN); // loop forever

if (ret == 0) {
close(p->tcp_fd);
p->tcp_fd = -1;
printf("peer %d got disconnected\n", peer);
p->con = 0;
return 3;
}
p->bl += ret;
processanswer:

if (p->bl < 2) {
return 2;
} else {
len = ntohs(*l);
if ((len + 2) > p->bl)
return 2;
}

printf("recv answer %d bytes\n", p->bl);
ul = (unsigned short int *) (p->bl + 2);
id = ntohs(*ul); // u16
if ((req = request_find(id)) == -1) {
memmove(p->b, (p->b + len + 2), (p->bl - len - 2));
p->bl -= len + 2;
return 0;
}

r = &requests[req];
// write back real id;
*ul = htons(r->rid);
r->a.sin_family = AF_INET;
while(sendto(udp_fd, (p->b + 2), len, 0,
(struct sockaddr *)&r->a,
sizeof(struct sockaddr_in)) < 0
&& errno == EAGAIN);

printf("forwarding answer %d bytes\n", len);

memmove(p->b, p->b + 2 + len, p->bl-len-2);
p->bl -= len + 2;

// mark as handled unused
r->id = 0;
if (p->bl > 0) goto processanswer;

return 1;
}

void peer_handleoutstanding(int peer) {
int i ;
printf("%s\n", __FUNCTION__);
for (i = 0; i < MAX_REQUESTS; i++) {
if (requests[i].id != 0
&&
requests[i].active == 0) {
requests[i].active = 1;
peer_sendreq(peer, i);
}
}
}


int peer_select() {
return 0;
}

it ns_select( ) {
return (rand() >> 16) % num_nameservers;
}



int request_add(request_t *r) {

}


int main() {
//f(5);
//f(4, 5);
f(4,5,6);
printf(" --done\n");

return 0;

}

~

No comments:

Post a Comment