Skip to content

Instantly share code, notes, and snippets.

@pandax381
Last active February 22, 2017 08:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pandax381/05a721ae415d49e362d8c9a3ba021334 to your computer and use it in GitHub Desktop.
Save pandax381/05a721ae415d49e362d8c9a3ba021334 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <errno.h>
#include <poll.h>
#include <sys/epoll.h>
#include <sys/ioctl.h>
#define SRC_PORT 54321
#define DST_PORT 111
#define SRC_HOST "10.10.0.3"
#define DST_HOST "10.10.0.2"
static int counter = 0;
struct pseudo_ip_header {
unsigned int src_ip;
unsigned int dst_ip;
unsigned char zero;
unsigned char protocol;
unsigned short len;
};
struct pseudo_header {
struct pseudo_ip_header iphdr;
struct tcphdr ptcphdr;
};
static unsigned short checksum(unsigned short *buffer, int size)
{
unsigned long cksum = 0;
while (size > 1) {
cksum += *buffer++;
size -= sizeof(unsigned short);
}
if (size)
cksum += *(char *)buffer;
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >> 16);
return (unsigned short)(~cksum);
}
static void check_port_raw_socket(int max)
{
int src_port = SRC_PORT;
int dst_port = DST_PORT;
char srcip[] = SRC_HOST;
char dstip[] = DST_HOST;
struct tcphdr tcphdr;
struct pseudo_header pheader;
struct sockaddr_in peer;
struct sockaddr *peer_ptr;
int sock;
int saddr_size;
int windowsize = 4321;
int tcphdr_size = sizeof(struct tcphdr);
int iphdr_size = sizeof(struct ip);
printf("bench type: %s bench num: %d\n", __func__, max);
tcphdr.source = htons(src_port);
tcphdr.dest = htons(dst_port);
tcphdr.window = htons(windowsize);
tcphdr.seq = 1;
tcphdr.fin = 0;
tcphdr.syn = 1;
tcphdr.doff = 5;
tcphdr.rst = 0;
tcphdr.urg = 0;
tcphdr.urg_ptr = 0;
tcphdr.psh = 0;
tcphdr.ack_seq = 0;
tcphdr.ack = 0;
tcphdr.check = 0;
tcphdr.res1 = 0;
tcphdr.res2 = 0;
inet_aton(srcip, (struct in_addr *)&pheader.iphdr.src_ip);
inet_aton(dstip, (struct in_addr *)&pheader.iphdr.dst_ip);
pheader.iphdr.zero = 0;
pheader.iphdr.protocol = 6;
pheader.iphdr.len = htons(sizeof(struct ip));
inet_aton(dstip, &peer.sin_addr);
peer.sin_port = htons(dst_port);
peer.sin_family = AF_INET;
saddr_size = sizeof(peer);
peer_ptr = (struct sockaddr *)&peer;
bcopy((char *)&tcphdr, (char *)&pheader.ptcphdr, sizeof(struct ip));
tcphdr.check = checksum((unsigned short *)&pheader, 32);
counter = 0;
while (counter < max) {
sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
sendto(sock, &tcphdr, tcphdr_size, 0, peer_ptr, saddr_size);
while (1) {
struct tcphdr *tcp;
unsigned char buffer[4096] = {0};
recvfrom(sock, buffer, 4096, 0, peer_ptr, &saddr_size);
tcp = (struct tcphdr *)(buffer + iphdr_size);
if (tcp->syn == 1 && tcp->ack == 1) {
counter++;
break;
}
}
close(sock);
}
}
static void check_port_sysconnect_so_linger(int max)
{
int src_port = SRC_PORT;
int dst_port = DST_PORT;
char srcip[] = SRC_HOST;
char dstip[] = DST_HOST;
struct linger so_linger;
struct sockaddr_in peer;
struct sockaddr *peer_ptr;
int sock, peer_size;
int so_linger_size = sizeof(so_linger);
printf("bench type: %s bench num: %d\n", __func__, max);
so_linger.l_onoff = 1;
so_linger.l_linger = 0;
inet_aton(dstip, &peer.sin_addr);
peer.sin_port = htons(dst_port);
peer.sin_family = AF_INET;
peer_size = sizeof(peer);
peer_ptr = (struct sockaddr *)&peer;
counter = 0;
while (counter < max) {
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (connect(sock, peer_ptr, peer_size) != -1) {
counter++;
}
setsockopt(sock, SOL_SOCKET, SO_LINGER, &so_linger, so_linger_size);
close(sock);
}
}
static void check_port_sysconnect_so_linger_poll(int max)
{
int src_port = SRC_PORT;
int dst_port = DST_PORT;
char srcip[] = SRC_HOST;
char dstip[] = DST_HOST;
struct linger so_linger;
struct sockaddr_in peer;
struct sockaddr *peer_ptr;
int sock, peer_size;
int so_linger_size = sizeof(so_linger);
int opt = 1;
struct pollfd pfds[1];
printf("bench type: %s bench num: %d\n", __func__, max);
so_linger.l_onoff = 1;
so_linger.l_linger = 0;
inet_aton(dstip, &peer.sin_addr);
peer.sin_port = htons(dst_port);
peer.sin_family = AF_INET;
peer_size = sizeof(peer);
peer_ptr = (struct sockaddr *)&peer;
pfds[0].events = POLLIN | POLLOUT;
counter = 0;
while (counter < max) {
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
ioctl(sock, FIONBIO, &opt);
connect(sock, peer_ptr, peer_size);
setsockopt(sock, SOL_SOCKET, SO_LINGER, &so_linger, so_linger_size);
pfds[0].fd = sock;
if (poll(pfds, 1, -1) > 0) {
counter++;
}
close(sock);
}
}
static void check_port_sysconnect_so_linger_epoll(int max)
{
int src_port = SRC_PORT;
int dst_port = DST_PORT;
char srcip[] = SRC_HOST;
char dstip[] = DST_HOST;
struct linger so_linger;
struct sockaddr_in peer;
struct sockaddr *peer_ptr;
int sock, peer_size;
int so_linger_size = sizeof(so_linger);
int opt = 1;
int epfd;
struct epoll_event ev, events[1];
printf("bench type: %s bench num: %d\n", __func__, max);
so_linger.l_onoff = 1;
so_linger.l_linger = 0;
inet_aton(dstip, &peer.sin_addr);
peer.sin_port = htons(dst_port);
peer.sin_family = AF_INET;
peer_size = sizeof(peer);
peer_ptr = (struct sockaddr *)&peer;
epfd = epoll_create(1);
ev.events = EPOLLIN | EPOLLOUT;
counter = 0;
while (counter < max) {
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
ioctl(sock, FIONBIO, &opt);
connect(sock, peer_ptr, peer_size);
setsockopt(sock, SOL_SOCKET, SO_LINGER, &so_linger, so_linger_size);
epoll_ctl(epfd, EPOLL_CTL_ADD, sock, &ev);
if (epoll_wait(epfd, events, 1, -1) > 0) {
counter++;
}
close(sock);
}
}
static void check_port_sysconnect(int max)
{
int src_port = SRC_PORT;
int dst_port = DST_PORT;
char srcip[] = SRC_HOST;
char dstip[] = DST_HOST;
struct sockaddr_in peer;
struct sockaddr *peer_ptr;
int sock, peer_size;
printf("bench type: %s bench num: %d\n", __func__, max);
inet_aton(dstip, &peer.sin_addr);
peer.sin_port = htons(dst_port);
peer.sin_family = AF_INET;
peer_size = sizeof(peer);
peer_ptr = (struct sockaddr *)&peer;
counter = 0;
while (counter < max) {
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (connect(sock, peer_ptr, peer_size) != -1) {
counter++;
}
close(sock);
}
}
int main(int argc, const char **argv)
{
int max;
if (argc != 3) {
printf("type('raw' or 'connect') check_num\n");
return 1;
}
max = atoi(argv[2]);
if (strcmp(argv[1], "raw") == 0) {
check_port_raw_socket(max);
}
if (strcmp(argv[1], "connect") == 0) {
check_port_sysconnect(max);
}
if (strcmp(argv[1], "so_linger_connect") == 0) {
check_port_sysconnect_so_linger(max);
}
if (strcmp(argv[1], "so_linger_connect_poll") == 0) {
check_port_sysconnect_so_linger_poll(max);
}
if (strcmp(argv[1], "so_linger_connect_epoll") == 0) {
check_port_sysconnect_so_linger_epoll(max);
}
return 0;
}
@pandax381
Copy link
Author

あ、raw socket のやつだけ試行回数が一桁少ない...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment