This is related to Web Servers

Popular New Releases in Web Servers

No Popular Releases are available at this moment for Web Servers

Popular Libraries in Web Servers

No Trending Libraries are available at this moment for Web Servers

Trending New libraries in Web Servers

No Trending Libraries are available at this moment for Web Servers

Top Authors in Web Servers

No Top Authors are available at this moment for Web Servers.

Trending Kits in Web Servers

No Trending Kits are available at this moment for Web Servers

Trending Discussions on Web Servers

Can't connect front-end (vue) to API (nodeJS), using nginx, EC2 AWS 20.04 Ubuntu

Is there an archive file format that supports being split in multiple parts and can be unpacked natively on MS Windows?

HAProxy doesn't connect to MariaDB Galera cluster backend

How to Configure Pfsense HAProxy HTTP HealthCheck Failover

Ansible Tower for Configuration Drift

Which port of localhost can I select in order to create a docker container?

MongoDB Rust Driver weird behavior

How use multiple socket.io servers with different library version on the same Node.js application

Azure Front Door to Website on IIS VM Host

Why is my non blocking raw sockets program running so slowly?

QUESTION

Can't connect front-end (vue) to API (nodeJS), using nginx, EC2 AWS 20.04 Ubuntu

Asked 2022-Apr-03 at 13:47

I want to set up web servers. First I chose NodeJS with Express for backend, listening in port 3002.

app.js listening at port 3002

Ok, next I set up ubuntu firewall allowing port 3002. Then I've tested with curl a login Endpoint to be sure that backend is working fine;

1curl -d '{"email":"adriel@admin.com","password":"{{mypass}}"}' -H 'Content-Type: application/json' http://{{my-ip}}:3002/user/login 
2

then I got a token response, therefore API is working fine as expected.

Ubuntu firewall, pm2 start app.js, curl API request

Then I moved to front-end (vueJS), cloned vue repository, then I ran:

1curl -d '{"email":"adriel@admin.com","password":"{{mypass}}"}' -H 'Content-Type: application/json' http://{{my-ip}}:3002/user/login 
2sudo npm i
3sudo npm run build
4

I installed Nginx and move dist folder (vue build files) to default nginx folder "/var/www"

and renamed package:

1curl -d '{"email":"adriel@admin.com","password":"{{mypass}}"}' -H 'Content-Type: application/json' http://{{my-ip}}:3002/user/login 
2sudo npm i
3sudo npm run build
4sudo mv ./dist ./html
5

Then I set up nginx config at:

1curl -d '{"email":"adriel@admin.com","password":"{{mypass}}"}' -H 'Content-Type: application/json' http://{{my-ip}}:3002/user/login 
2sudo npm i
3sudo npm run build
4sudo mv ./dist ./html
5sudo nano /etc/nginx/sites-availabe/default
6
1curl -d '{"email":"adriel@admin.com","password":"{{mypass}}"}' -H 'Content-Type: application/json' http://{{my-ip}}:3002/user/login 
2sudo npm i
3sudo npm run build
4sudo mv ./dist ./html
5sudo nano /etc/nginx/sites-availabe/default
6    server {
7        listen 80 default_server;
8        listen [::]:80 default_server;
9
10        root /var/www/html;
11        index index.html index.htm index.nginx-debian.html;
12
13        server_name _;
14
15         location /api/ {
16        proxy_pass http://{{my-ip}}:3002;
17        proxy_http_version 1.1;
18        proxy_set_header Upgrade $http_upgrade;
19        proxy_set_header Connection 'upgrade';
20        proxy_set_header Host $host;
21        proxy_cache_bypass $http_upgrade;
22         }
23
24}
25
1curl -d '{"email":"adriel@admin.com","password":"{{mypass}}"}' -H 'Content-Type: application/json' http://{{my-ip}}:3002/user/login 
2sudo npm i
3sudo npm run build
4sudo mv ./dist ./html
5sudo nano /etc/nginx/sites-availabe/default
6    server {
7        listen 80 default_server;
8        listen [::]:80 default_server;
9
10        root /var/www/html;
11        index index.html index.htm index.nginx-debian.html;
12
13        server_name _;
14
15         location /api/ {
16        proxy_pass http://{{my-ip}}:3002;
17        proxy_http_version 1.1;
18        proxy_set_header Upgrade $http_upgrade;
19        proxy_set_header Connection 'upgrade';
20        proxy_set_header Host $host;
21        proxy_cache_bypass $http_upgrade;
22         }
23
24}
25sudo netstat -plant | grep 80
26sudo systemctl stop apache2
27sudo nginx -t
28sudo systemctl start nginx
29

It should work fine but when I send a login response in the front-end, happens a 404 to my /api/, I even changed the base url to http://localhost:3002 but din't work as well. What should I do ? I don't know how to send a request in front-end, but curl works fine. Any tips?

Sending request to API with AXIOS, 404 NOT FOUND

AWS Security groups

ANSWER

Answered 2021-Sep-13 at 16:25

I could solve the problem with API connection, using this Nginx configuration at /etc/nginx/sites-available/default

1curl -d '{"email":"adriel@admin.com","password":"{{mypass}}"}' -H 'Content-Type: application/json' http://{{my-ip}}:3002/user/login 
2sudo npm i
3sudo npm run build
4sudo mv ./dist ./html
5sudo nano /etc/nginx/sites-availabe/default
6    server {
7        listen 80 default_server;
8        listen [::]:80 default_server;
9
10        root /var/www/html;
11        index index.html index.htm index.nginx-debian.html;
12
13        server_name _;
14
15         location /api/ {
16        proxy_pass http://{{my-ip}}:3002;
17        proxy_http_version 1.1;
18        proxy_set_header Upgrade $http_upgrade;
19        proxy_set_header Connection 'upgrade';
20        proxy_set_header Host $host;
21        proxy_cache_bypass $http_upgrade;
22         }
23
24}
25sudo netstat -plant | grep 80
26sudo systemctl stop apache2
27sudo nginx -t
28sudo systemctl start nginx
29server {
30  listen 80 default_server;
31  server_name _;
32
33  # front end
34  location / {
35    root /myprojects/front-end/dist;
36    try_files $uri /index.html;
37  }
38
39  # node api reverse proxy
40  location /api/ {
41    proxy_pass http://localhost:3002/;
42  }
43}
44

This is the right away to use nodeJS as a proxy reverse server

Source https://stackoverflow.com/questions/69004524

QUESTION

Is there an archive file format that supports being split in multiple parts and can be unpacked natively on MS Windows?

Asked 2022-Mar-27 at 02:18

Some archive file formats, e.g. ZIP (see Section 8 in https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT), support being split into multiple parts of a limited size. ZIP files can be opened natively on recent versions of Microsoft Windows, but it seems that Windows cannot open split ZIP files natively, only with special tools like 7-Zip. I would like to use this "split archive" functionality in a web app that I'm writing in which the created archives should be opened by a large audience of "average" computer users, so my question is: Is there an archive file format (like ZIP) that supports being split in multiple parts and can be unpacked without installing additional software on recent versions of Microsoft Windows? And ideally on other widely used operating systems as well.

Background: My final goal is to export a directory structure that is split over multiple web servers to a single local directory tree. My current idea is to have each web server produce one part of the split archive, provide all of them as some sort of Javascript multi-file download and then have one archive (in multiple parts) on the user's computer that just needs to be unpacked. An alternative idea for this final goal was to use Javascript's File System Access API (https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API), but it is not supported on Firefox, which is a showstopper.

ANSWER

Answered 2022-Mar-27 at 02:18

CAB archives meet this purpose a bit (see this library's page for example, it says that through it, archives can even be extracted directly from a HTTP(S)/FTP server). Since the library relies on .NET, it could even be used on Linux through Mono/Wine, which is a crucial part if your servers aren't running Windows... Because archive must be created on server, right?.

Your major problem is more that a split archive can't be created in parallel on multiple servers, at least because of LZx's dictionnary. Each server should create the whole set of archives and send only the ones it should send, and you don't have ANY guarantee that all these archives' sets would be identical on each server.

Best way is probably to create the whole archive on ONE server, then distribute each part (or the whole splitted archive...) on your various servers, through a replication-like interface.

Otherwise, you can also make individual archives that contains only a subset of the directory tree (you'll have to partition the files across servers), but it won't meet your requirements since it would be a collection of individual archives, and not a big splitted archive.

Some precisions may be required:

  • Do you absolutely need a system without any client besides the browser? Or can you use other protocols, as long as they natively exist on Windows (like FTP / SSH client that are now provided by default)?
  • What is the real purpose behind this request? Distribute load across all servers? Or to avoid too big single file downloads (i.e. a 30 GB archive) in case of transfer failure? Or both?
  • In case of a file size problem, why don't rely on resuming download?

Source https://stackoverflow.com/questions/71631350

QUESTION

HAProxy doesn't connect to MariaDB Galera cluster backend

Asked 2022-Mar-25 at 20:05

I'm new to MariaDB galera cluster load balancing and I'm trying to use HAProxy to do the load balancing. I have set up the MariaDB Galera cluster and it works perfectly.

In Haproxy, I have created a VIP for the DB cluster and if I look at the HAProxy statistics page it shows the VIP and all three nodes are green. This is how I have it configured:

1#---------------------------------------------------------------------
2# frontend_db_domain.com
3#---------------------------------------------------------------------
4frontend db_domain.com
5
6  bind ip:3306
7  mode tcp
8  option mysql-check user haproxy_check
9  default_backend back_db_domain.com
10
11#---------------------------------------------------------------------
12# backend_db_domain.com
13#---------------------------------------------------------------------
14backend back_db_domain.com
15  balance roundrobin
16    server db01.domain.com ip:3306 check
17    server db02.domain.com ip:3306 check
18    server db03.domain.com ip:3306 check
19

I configured a wordpress site to use the VIP address which is db.domain.com and wordpress shows Error establishing a database connection. If I use the db hostname or ip that hits the nodes directly everything works fine.

This is what shows in the HAProxy logs:

1#---------------------------------------------------------------------
2# frontend_db_domain.com
3#---------------------------------------------------------------------
4frontend db_domain.com
5
6  bind ip:3306
7  mode tcp
8  option mysql-check user haproxy_check
9  default_backend back_db_domain.com
10
11#---------------------------------------------------------------------
12# backend_db_domain.com
13#---------------------------------------------------------------------
14backend back_db_domain.com
15  balance roundrobin
16    server db01.domain.com ip:3306 check
17    server db02.domain.com ip:3306 check
18    server db03.domain.com ip:3306 check
19Mar 24 04:07:27 localhost haproxy[22096]: 1.2.3.4:56022 [24/Mar/2022:04:07:16.987] domain.com~ back_domain.com/nginx01.domain.com 68/0/1/10095/10164 500 2842 - - ---- 3/1/0/0/0 0/0 "GET /webdesigns/website1/ HTTP/1.1"
20

This is the nginx logs:

1#---------------------------------------------------------------------
2# frontend_db_domain.com
3#---------------------------------------------------------------------
4frontend db_domain.com
5
6  bind ip:3306
7  mode tcp
8  option mysql-check user haproxy_check
9  default_backend back_db_domain.com
10
11#---------------------------------------------------------------------
12# backend_db_domain.com
13#---------------------------------------------------------------------
14backend back_db_domain.com
15  balance roundrobin
16    server db01.domain.com ip:3306 check
17    server db02.domain.com ip:3306 check
18    server db03.domain.com ip:3306 check
19Mar 24 04:07:27 localhost haproxy[22096]: 1.2.3.4:56022 [24/Mar/2022:04:07:16.987] domain.com~ back_domain.com/nginx01.domain.com 68/0/1/10095/10164 500 2842 - - ---- 3/1/0/0/0 0/0 "GET /webdesigns/website1/ HTTP/1.1"
2045.77.206.174 - - [24/Mar/2022:04:07:27 +0000] "GET /webdesigns/website1/ HTTP/1.1" 500 2539 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:98.0) Gecko/20100101 Firefox/98.0" "1.2.3.4"
21

There is no firewall in place that would block anything between all these hosts. They can all connect to each other. This is how the db nodes are configured:

1#---------------------------------------------------------------------
2# frontend_db_domain.com
3#---------------------------------------------------------------------
4frontend db_domain.com
5
6  bind ip:3306
7  mode tcp
8  option mysql-check user haproxy_check
9  default_backend back_db_domain.com
10
11#---------------------------------------------------------------------
12# backend_db_domain.com
13#---------------------------------------------------------------------
14backend back_db_domain.com
15  balance roundrobin
16    server db01.domain.com ip:3306 check
17    server db02.domain.com ip:3306 check
18    server db03.domain.com ip:3306 check
19Mar 24 04:07:27 localhost haproxy[22096]: 1.2.3.4:56022 [24/Mar/2022:04:07:16.987] domain.com~ back_domain.com/nginx01.domain.com 68/0/1/10095/10164 500 2842 - - ---- 3/1/0/0/0 0/0 "GET /webdesigns/website1/ HTTP/1.1"
2045.77.206.174 - - [24/Mar/2022:04:07:27 +0000] "GET /webdesigns/website1/ HTTP/1.1" 500 2539 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:98.0) Gecko/20100101 Firefox/98.0" "1.2.3.4"
21[mysqld]
22binlog_format=ROW
23default-storage-engine=innodb
24innodb_autoinc_lock_mode=2
25#bind-address=0.0.0.0
26
27# Galera Provider Configuration
28wsrep_on=ON
29wsrep_provider=/usr/lib64/galera-4/libgalera_smm.so
30
31# Galera Cluster Configuration
32wsrep_cluster_name="test_cluster"
33wsrep_cluster_address="gcomm://10.1.96.12,10.1.96.13,10.1.96.14"
34
35# Galera Synchronization Configuration
36wsrep_sst_method=rsync
37
38# Galera Node Configuration
39wsrep_node_address="10.1.96.14"
40wsrep_node_name="db03"
41

Not sure what I am missing but I think I have a misconfiguration on the HAProxy side but not sure what it can be. I have other VIPs but they're for web servers and stuff like that which all work fine. This the first VIP I have issues with. I would appreciate any and all help.

Thank you!

ANSWER

Answered 2022-Mar-24 at 06:09

cli ip a check your vip is work on haproxy hosts\

Source https://stackoverflow.com/questions/71597019

QUESTION

How to Configure Pfsense HAProxy HTTP HealthCheck Failover

Asked 2022-Mar-02 at 18:12

I have two backend web servers, and i need to monitor them using httpcheck by checking the URL and looking for a string to be present in the response of the request. if the string is not available switch the backend to another server.

Status:

  • Server1 - Active
  • Server2 - Backup

Configuration Details:

  • Health Check Method : HTTP
  • HTTP Check Method : GET
  • Url used by http check requests: /jsonp/FreeForm&maxrecords=10&format=XML&ff=223
  • Http check version : HTTP/1.0\r\nAccept:\ XS01

Result of the http Request is

1{"d":{"__type":"Response","Version":"4.5.23.1160","ResultCode":"XS01","ErrorString":"","Results":[{"__type":"Result",
2

so, I am expecting the string ResultCode":"XS01" in the response from the server, if the string found the server1 is up, if not bring the Server2 from the backup.

how can i achieve this in HAProxy Backend Health Check?

ANSWER

Answered 2022-Mar-02 at 18:12

This can be done under Advanced Settings--> Backend Pass thru using the expect string,

http-check expect string XS01

Source https://stackoverflow.com/questions/71281104

QUESTION

Ansible Tower for Configuration Drift

Asked 2022-Feb-24 at 12:34

We've set up an Ansible Tower and have written several job templates and jobs, created our hosts and groups, all of that. Right now we're scheduling jobs to run to apply the playbooks assigned to groups, such as our web servers, to keep them from running into configuration drift. But we've been told not to use Tower for configuration drift, but if we don't do that, what's the best practice on how to use Ansible to ensure the playbooks run on a regular basis?

ANSWER

Answered 2022-Feb-24 at 12:34

But we've been told not to use Tower for configuration drift

Probably because of infrastructure and resource consumption since i.e. Control with Ansible Tower or verify compliance is a common use case.

but if we don't do that, what's the best practice on how to use Ansible to ensure the playbooks run on a regular basis?

This will highly depend on your environment, amount of hosts and groups, the content and runtime of playbooks, (configuration) change rate in your environment, network utilization, amount of data transferd and so on.

Except from general available Ansible documentation recommendations some more Best Practices might be

In other words, it is most about Ansible Performance Tuning. You may have also a look into Strategy plugins like Mitogen .

Source https://stackoverflow.com/questions/71228052

QUESTION

Which port of localhost can I select in order to create a docker container?

Asked 2022-Feb-05 at 21:38

I'm learning Kurbernetes and Docker at the moment, KinD in particular. To start with, I just want to run docker run --rm --name <container's name> -p 8080:80 -d <image name> to create a container from the image.

I know that ports are used in the TCP/IP protocol (or Internet Protocol) to address a specific program (software). Port 80 is a default port to run web servers.

Now, my question is why 8080 or why 5000? How to determine which port should be an OUTSIDE port in this case? Is it just random or are there any rule/restrictions?

ANSWER

Answered 2022-Feb-05 at 15:12

port 8080 is normally used to host your personal webserver/service and it is alternate of port 80 you can also use other ports instead of 8080. when some one try to connect to your webserver from outside, and if you use port 8080, they don't need to specify port number because by default it will look for port 8080.

If you use any other port number, when someone try to connect to your webservice/server from outside, they should specify the custom port number you specified to access your webservice/server

Source https://stackoverflow.com/questions/70999144

QUESTION

MongoDB Rust Driver weird behavior

Asked 2022-Jan-31 at 16:32

There is this weird thing, I have installed the MongoDB Compass and made a aggregation query that works in the Aggregation tab but now when I use the same query in my rust web server it behaves very weirdly

Original message:

1{&quot;_id&quot;:{&quot;$oid&quot;:&quot;61efd41c56ffe6b1b4a15c7a&quot;},&quot;time&quot;:{&quot;$date&quot;:&quot;2022-01-25T10:42:36.175Z&quot;},&quot;edited_time&quot;:{&quot;$date&quot;:&quot;2022-01-30T14:29:54.361Z&quot;},&quot;changes&quot;:[],&quot;content&quot;:&quot;LORA&quot;,&quot;author&quot;:{&quot;$oid&quot;:&quot;61df3cab3087579f8767a38d&quot;}}
2

Message in MongoDB compass after the query:

1{&quot;_id&quot;:{&quot;$oid&quot;:&quot;61efd41c56ffe6b1b4a15c7a&quot;},&quot;time&quot;:{&quot;$date&quot;:&quot;2022-01-25T10:42:36.175Z&quot;},&quot;edited_time&quot;:{&quot;$date&quot;:&quot;2022-01-30T14:29:54.361Z&quot;},&quot;changes&quot;:[],&quot;content&quot;:&quot;LORA&quot;,&quot;author&quot;:{&quot;$oid&quot;:&quot;61df3cab3087579f8767a38d&quot;}}
2{
3    &quot;_id&quot;: {
4        &quot;$oid&quot;: &quot;61efd41c56ffe6b1b4a15c7a&quot;
5    },
6    &quot;time&quot;: {
7        &quot;$date&quot;: &quot;2022-01-25T10:42:36.175Z&quot;
8    },
9    &quot;edited_time&quot;: {
10        &quot;$date&quot;: &quot;2021-12-17T09:55:45.856Z&quot;
11    },
12    &quot;changes&quot;: [{
13        &quot;time&quot;: {
14            &quot;$date&quot;: &quot;2021-12-17T09:55:45.856Z&quot;
15        },
16        &quot;change&quot;: {
17            &quot;ChangedContent&quot;: &quot;LORA&quot;
18        }
19    }],
20    &quot;content&quot;: &quot;LMAO&quot;,
21    &quot;author&quot;: {
22        &quot;$oid&quot;: &quot;61df3cab3087579f8767a38d&quot;
23    }
24}
25

Message after the Web Servers query:

1{&quot;_id&quot;:{&quot;$oid&quot;:&quot;61efd41c56ffe6b1b4a15c7a&quot;},&quot;time&quot;:{&quot;$date&quot;:&quot;2022-01-25T10:42:36.175Z&quot;},&quot;edited_time&quot;:{&quot;$date&quot;:&quot;2022-01-30T14:29:54.361Z&quot;},&quot;changes&quot;:[],&quot;content&quot;:&quot;LORA&quot;,&quot;author&quot;:{&quot;$oid&quot;:&quot;61df3cab3087579f8767a38d&quot;}}
2{
3    &quot;_id&quot;: {
4        &quot;$oid&quot;: &quot;61efd41c56ffe6b1b4a15c7a&quot;
5    },
6    &quot;time&quot;: {
7        &quot;$date&quot;: &quot;2022-01-25T10:42:36.175Z&quot;
8    },
9    &quot;edited_time&quot;: {
10        &quot;$date&quot;: &quot;2021-12-17T09:55:45.856Z&quot;
11    },
12    &quot;changes&quot;: [{
13        &quot;time&quot;: {
14            &quot;$date&quot;: &quot;2021-12-17T09:55:45.856Z&quot;
15        },
16        &quot;change&quot;: {
17            &quot;ChangedContent&quot;: &quot;LORA&quot;
18        }
19    }],
20    &quot;content&quot;: &quot;LMAO&quot;,
21    &quot;author&quot;: {
22        &quot;$oid&quot;: &quot;61df3cab3087579f8767a38d&quot;
23    }
24}
25{
26    &quot;_id&quot;: {
27        &quot;$oid&quot;: &quot;61efd41c56ffe6b1b4a15c7a&quot;
28    },
29    &quot;time&quot;: {
30        &quot;$date&quot;: &quot;2022-01-25T10:42:36.175Z&quot;
31    },
32    &quot;edited_time&quot;: {
33        &quot;$date&quot;: &quot;2022-01-30T14:40:57.152Z&quot;
34    },
35    &quot;changes&quot;: {
36        &quot;$concatArrays&quot;: [&quot;$changes&quot;, [{
37            &quot;time&quot;: {
38                &quot;$date&quot;: &quot;2022-01-30T14:40:57.152Z&quot;
39            },
40            &quot;change&quot;: {
41                &quot;ChangedContent&quot;: &quot;$content&quot;
42            }
43        }]]
44    },
45    &quot;content&quot;: &quot;LMAO&quot;,
46    &quot;author&quot;: {
47        &quot;$oid&quot;: &quot;61df3cab3087579f8767a38d&quot;
48    }
49}
50

Pure query in MongoDB Compass: $set stage

1{&quot;_id&quot;:{&quot;$oid&quot;:&quot;61efd41c56ffe6b1b4a15c7a&quot;},&quot;time&quot;:{&quot;$date&quot;:&quot;2022-01-25T10:42:36.175Z&quot;},&quot;edited_time&quot;:{&quot;$date&quot;:&quot;2022-01-30T14:29:54.361Z&quot;},&quot;changes&quot;:[],&quot;content&quot;:&quot;LORA&quot;,&quot;author&quot;:{&quot;$oid&quot;:&quot;61df3cab3087579f8767a38d&quot;}}
2{
3    &quot;_id&quot;: {
4        &quot;$oid&quot;: &quot;61efd41c56ffe6b1b4a15c7a&quot;
5    },
6    &quot;time&quot;: {
7        &quot;$date&quot;: &quot;2022-01-25T10:42:36.175Z&quot;
8    },
9    &quot;edited_time&quot;: {
10        &quot;$date&quot;: &quot;2021-12-17T09:55:45.856Z&quot;
11    },
12    &quot;changes&quot;: [{
13        &quot;time&quot;: {
14            &quot;$date&quot;: &quot;2021-12-17T09:55:45.856Z&quot;
15        },
16        &quot;change&quot;: {
17            &quot;ChangedContent&quot;: &quot;LORA&quot;
18        }
19    }],
20    &quot;content&quot;: &quot;LMAO&quot;,
21    &quot;author&quot;: {
22        &quot;$oid&quot;: &quot;61df3cab3087579f8767a38d&quot;
23    }
24}
25{
26    &quot;_id&quot;: {
27        &quot;$oid&quot;: &quot;61efd41c56ffe6b1b4a15c7a&quot;
28    },
29    &quot;time&quot;: {
30        &quot;$date&quot;: &quot;2022-01-25T10:42:36.175Z&quot;
31    },
32    &quot;edited_time&quot;: {
33        &quot;$date&quot;: &quot;2022-01-30T14:40:57.152Z&quot;
34    },
35    &quot;changes&quot;: {
36        &quot;$concatArrays&quot;: [&quot;$changes&quot;, [{
37            &quot;time&quot;: {
38                &quot;$date&quot;: &quot;2022-01-30T14:40:57.152Z&quot;
39            },
40            &quot;change&quot;: {
41                &quot;ChangedContent&quot;: &quot;$content&quot;
42            }
43        }]]
44    },
45    &quot;content&quot;: &quot;LMAO&quot;,
46    &quot;author&quot;: {
47        &quot;$oid&quot;: &quot;61df3cab3087579f8767a38d&quot;
48    }
49}
50{
51  &quot;changes&quot;: { $concatArrays: [ &quot;$changes&quot;,  [ { &quot;time&quot;: ISODate('2021-12-17T09:55:45.856+00:00'), &quot;change&quot;: { &quot;ChangedContent&quot;: &quot;$content&quot; } } ] ] },
52  &quot;edited_time&quot;: ISODate('2021-12-17T09:55:45.856+00:00'),
53  &quot;content&quot;: &quot;LMAO&quot;,
54}
55

Pure query in Web Server:

1{&quot;_id&quot;:{&quot;$oid&quot;:&quot;61efd41c56ffe6b1b4a15c7a&quot;},&quot;time&quot;:{&quot;$date&quot;:&quot;2022-01-25T10:42:36.175Z&quot;},&quot;edited_time&quot;:{&quot;$date&quot;:&quot;2022-01-30T14:29:54.361Z&quot;},&quot;changes&quot;:[],&quot;content&quot;:&quot;LORA&quot;,&quot;author&quot;:{&quot;$oid&quot;:&quot;61df3cab3087579f8767a38d&quot;}}
2{
3    &quot;_id&quot;: {
4        &quot;$oid&quot;: &quot;61efd41c56ffe6b1b4a15c7a&quot;
5    },
6    &quot;time&quot;: {
7        &quot;$date&quot;: &quot;2022-01-25T10:42:36.175Z&quot;
8    },
9    &quot;edited_time&quot;: {
10        &quot;$date&quot;: &quot;2021-12-17T09:55:45.856Z&quot;
11    },
12    &quot;changes&quot;: [{
13        &quot;time&quot;: {
14            &quot;$date&quot;: &quot;2021-12-17T09:55:45.856Z&quot;
15        },
16        &quot;change&quot;: {
17            &quot;ChangedContent&quot;: &quot;LORA&quot;
18        }
19    }],
20    &quot;content&quot;: &quot;LMAO&quot;,
21    &quot;author&quot;: {
22        &quot;$oid&quot;: &quot;61df3cab3087579f8767a38d&quot;
23    }
24}
25{
26    &quot;_id&quot;: {
27        &quot;$oid&quot;: &quot;61efd41c56ffe6b1b4a15c7a&quot;
28    },
29    &quot;time&quot;: {
30        &quot;$date&quot;: &quot;2022-01-25T10:42:36.175Z&quot;
31    },
32    &quot;edited_time&quot;: {
33        &quot;$date&quot;: &quot;2022-01-30T14:40:57.152Z&quot;
34    },
35    &quot;changes&quot;: {
36        &quot;$concatArrays&quot;: [&quot;$changes&quot;, [{
37            &quot;time&quot;: {
38                &quot;$date&quot;: &quot;2022-01-30T14:40:57.152Z&quot;
39            },
40            &quot;change&quot;: {
41                &quot;ChangedContent&quot;: &quot;$content&quot;
42            }
43        }]]
44    },
45    &quot;content&quot;: &quot;LMAO&quot;,
46    &quot;author&quot;: {
47        &quot;$oid&quot;: &quot;61df3cab3087579f8767a38d&quot;
48    }
49}
50{
51  &quot;changes&quot;: { $concatArrays: [ &quot;$changes&quot;,  [ { &quot;time&quot;: ISODate('2021-12-17T09:55:45.856+00:00'), &quot;change&quot;: { &quot;ChangedContent&quot;: &quot;$content&quot; } } ] ] },
52  &quot;edited_time&quot;: ISODate('2021-12-17T09:55:45.856+00:00'),
53  &quot;content&quot;: &quot;LMAO&quot;,
54}
55    let update_doc = doc! {
56        &quot;$set&quot;: {
57            &quot;changes&quot;: {
58                &quot;$concatArrays&quot;: [
59                    &quot;$changes&quot;, [
60                        {
61                            &quot;time&quot;: now,
62                            &quot;change&quot;: {
63                                &quot;ChangedContent&quot;: &quot;$content&quot;
64                            }
65                        }
66                    ]
67                ]
68            },
69            &quot;edited_time&quot;: now,
70            &quot;content&quot;: content
71        }
72    };
73

I am using update_one method, like this

1{&quot;_id&quot;:{&quot;$oid&quot;:&quot;61efd41c56ffe6b1b4a15c7a&quot;},&quot;time&quot;:{&quot;$date&quot;:&quot;2022-01-25T10:42:36.175Z&quot;},&quot;edited_time&quot;:{&quot;$date&quot;:&quot;2022-01-30T14:29:54.361Z&quot;},&quot;changes&quot;:[],&quot;content&quot;:&quot;LORA&quot;,&quot;author&quot;:{&quot;$oid&quot;:&quot;61df3cab3087579f8767a38d&quot;}}
2{
3    &quot;_id&quot;: {
4        &quot;$oid&quot;: &quot;61efd41c56ffe6b1b4a15c7a&quot;
5    },
6    &quot;time&quot;: {
7        &quot;$date&quot;: &quot;2022-01-25T10:42:36.175Z&quot;
8    },
9    &quot;edited_time&quot;: {
10        &quot;$date&quot;: &quot;2021-12-17T09:55:45.856Z&quot;
11    },
12    &quot;changes&quot;: [{
13        &quot;time&quot;: {
14            &quot;$date&quot;: &quot;2021-12-17T09:55:45.856Z&quot;
15        },
16        &quot;change&quot;: {
17            &quot;ChangedContent&quot;: &quot;LORA&quot;
18        }
19    }],
20    &quot;content&quot;: &quot;LMAO&quot;,
21    &quot;author&quot;: {
22        &quot;$oid&quot;: &quot;61df3cab3087579f8767a38d&quot;
23    }
24}
25{
26    &quot;_id&quot;: {
27        &quot;$oid&quot;: &quot;61efd41c56ffe6b1b4a15c7a&quot;
28    },
29    &quot;time&quot;: {
30        &quot;$date&quot;: &quot;2022-01-25T10:42:36.175Z&quot;
31    },
32    &quot;edited_time&quot;: {
33        &quot;$date&quot;: &quot;2022-01-30T14:40:57.152Z&quot;
34    },
35    &quot;changes&quot;: {
36        &quot;$concatArrays&quot;: [&quot;$changes&quot;, [{
37            &quot;time&quot;: {
38                &quot;$date&quot;: &quot;2022-01-30T14:40:57.152Z&quot;
39            },
40            &quot;change&quot;: {
41                &quot;ChangedContent&quot;: &quot;$content&quot;
42            }
43        }]]
44    },
45    &quot;content&quot;: &quot;LMAO&quot;,
46    &quot;author&quot;: {
47        &quot;$oid&quot;: &quot;61df3cab3087579f8767a38d&quot;
48    }
49}
50{
51  &quot;changes&quot;: { $concatArrays: [ &quot;$changes&quot;,  [ { &quot;time&quot;: ISODate('2021-12-17T09:55:45.856+00:00'), &quot;change&quot;: { &quot;ChangedContent&quot;: &quot;$content&quot; } } ] ] },
52  &quot;edited_time&quot;: ISODate('2021-12-17T09:55:45.856+00:00'),
53  &quot;content&quot;: &quot;LMAO&quot;,
54}
55    let update_doc = doc! {
56        &quot;$set&quot;: {
57            &quot;changes&quot;: {
58                &quot;$concatArrays&quot;: [
59                    &quot;$changes&quot;, [
60                        {
61                            &quot;time&quot;: now,
62                            &quot;change&quot;: {
63                                &quot;ChangedContent&quot;: &quot;$content&quot;
64                            }
65                        }
66                    ]
67                ]
68            },
69            &quot;edited_time&quot;: now,
70            &quot;content&quot;: content
71        }
72    };
73 messages.update_one(message_filter, update_doc, None).await?;
74

I don't really understand, and this happens often, sometimes it fixes it self when I add somewhere randomly some scope in the doc eg.: { } but this time I couldn't figure it out, I had version of the query with $push but that didn't work too Is there some fault in the rust driver or am I doing something wrong, are there some rules about formatting when using rust driver that I am missing?

ANSWER

Answered 2022-Jan-31 at 16:32

The $set aggregation pipeline stage is different from the $set update operator. And the only difference that I can tell, is the pipeline stage handles $concatArrays while the update operator does not.

$set Aggregation Pipeline Stage

$set appends new fields to existing documents. You can include one or more $set stages in an aggregation operation.

To add field or fields to embedded documents (including documents in arrays) use the dot notation.

To add an element to an existing array field with $set, use with $concatArrays.

$set Update Operator

Starting in MongoDB 5.0, update operators process document fields with string-based names in lexicographic order. Fields with numeric names are processed in numeric order.

If the field does not exist, $set will add a new field with the specified value, provided that the new field does not violate a type constraint. If you specify a dotted path for a non-existent field, $set will create the embedded documents as needed to fulfill the dotted path to the field.

If you specify multiple field-value pairs, $set will update or create each field.

So if you want to update an existing document by inserting elements into an array field, use the $push update operator (potentially with $each if you're inserting multiple elements):

1{&quot;_id&quot;:{&quot;$oid&quot;:&quot;61efd41c56ffe6b1b4a15c7a&quot;},&quot;time&quot;:{&quot;$date&quot;:&quot;2022-01-25T10:42:36.175Z&quot;},&quot;edited_time&quot;:{&quot;$date&quot;:&quot;2022-01-30T14:29:54.361Z&quot;},&quot;changes&quot;:[],&quot;content&quot;:&quot;LORA&quot;,&quot;author&quot;:{&quot;$oid&quot;:&quot;61df3cab3087579f8767a38d&quot;}}
2{
3    &quot;_id&quot;: {
4        &quot;$oid&quot;: &quot;61efd41c56ffe6b1b4a15c7a&quot;
5    },
6    &quot;time&quot;: {
7        &quot;$date&quot;: &quot;2022-01-25T10:42:36.175Z&quot;
8    },
9    &quot;edited_time&quot;: {
10        &quot;$date&quot;: &quot;2021-12-17T09:55:45.856Z&quot;
11    },
12    &quot;changes&quot;: [{
13        &quot;time&quot;: {
14            &quot;$date&quot;: &quot;2021-12-17T09:55:45.856Z&quot;
15        },
16        &quot;change&quot;: {
17            &quot;ChangedContent&quot;: &quot;LORA&quot;
18        }
19    }],
20    &quot;content&quot;: &quot;LMAO&quot;,
21    &quot;author&quot;: {
22        &quot;$oid&quot;: &quot;61df3cab3087579f8767a38d&quot;
23    }
24}
25{
26    &quot;_id&quot;: {
27        &quot;$oid&quot;: &quot;61efd41c56ffe6b1b4a15c7a&quot;
28    },
29    &quot;time&quot;: {
30        &quot;$date&quot;: &quot;2022-01-25T10:42:36.175Z&quot;
31    },
32    &quot;edited_time&quot;: {
33        &quot;$date&quot;: &quot;2022-01-30T14:40:57.152Z&quot;
34    },
35    &quot;changes&quot;: {
36        &quot;$concatArrays&quot;: [&quot;$changes&quot;, [{
37            &quot;time&quot;: {
38                &quot;$date&quot;: &quot;2022-01-30T14:40:57.152Z&quot;
39            },
40            &quot;change&quot;: {
41                &quot;ChangedContent&quot;: &quot;$content&quot;
42            }
43        }]]
44    },
45    &quot;content&quot;: &quot;LMAO&quot;,
46    &quot;author&quot;: {
47        &quot;$oid&quot;: &quot;61df3cab3087579f8767a38d&quot;
48    }
49}
50{
51  &quot;changes&quot;: { $concatArrays: [ &quot;$changes&quot;,  [ { &quot;time&quot;: ISODate('2021-12-17T09:55:45.856+00:00'), &quot;change&quot;: { &quot;ChangedContent&quot;: &quot;$content&quot; } } ] ] },
52  &quot;edited_time&quot;: ISODate('2021-12-17T09:55:45.856+00:00'),
53  &quot;content&quot;: &quot;LMAO&quot;,
54}
55    let update_doc = doc! {
56        &quot;$set&quot;: {
57            &quot;changes&quot;: {
58                &quot;$concatArrays&quot;: [
59                    &quot;$changes&quot;, [
60                        {
61                            &quot;time&quot;: now,
62                            &quot;change&quot;: {
63                                &quot;ChangedContent&quot;: &quot;$content&quot;
64                            }
65                        }
66                    ]
67                ]
68            },
69            &quot;edited_time&quot;: now,
70            &quot;content&quot;: content
71        }
72    };
73 messages.update_one(message_filter, update_doc, None).await?;
74let update_doc = doc! {
75    &quot;$set&quot;: {
76        &quot;edited_time&quot;: now,
77        &quot;content&quot;: content
78    },
79    &quot;$push&quot;: {
80        &quot;changes&quot;: {
81            &quot;time&quot;: now,
82            &quot;change&quot;: {
83                &quot;ChangedContent&quot;: &quot;$content&quot;
84            }
85        }
86    }
87};
88

Edit: I missed that $content was supposed to be mapped from the existing field as well. That is not supported by an update document, however MongoDB has support for using an aggregation pipeline to update the document. See: Update MongoDB field using value of another field So you can use the original $set just in a different way:

1{&quot;_id&quot;:{&quot;$oid&quot;:&quot;61efd41c56ffe6b1b4a15c7a&quot;},&quot;time&quot;:{&quot;$date&quot;:&quot;2022-01-25T10:42:36.175Z&quot;},&quot;edited_time&quot;:{&quot;$date&quot;:&quot;2022-01-30T14:29:54.361Z&quot;},&quot;changes&quot;:[],&quot;content&quot;:&quot;LORA&quot;,&quot;author&quot;:{&quot;$oid&quot;:&quot;61df3cab3087579f8767a38d&quot;}}
2{
3    &quot;_id&quot;: {
4        &quot;$oid&quot;: &quot;61efd41c56ffe6b1b4a15c7a&quot;
5    },
6    &quot;time&quot;: {
7        &quot;$date&quot;: &quot;2022-01-25T10:42:36.175Z&quot;
8    },
9    &quot;edited_time&quot;: {
10        &quot;$date&quot;: &quot;2021-12-17T09:55:45.856Z&quot;
11    },
12    &quot;changes&quot;: [{
13        &quot;time&quot;: {
14            &quot;$date&quot;: &quot;2021-12-17T09:55:45.856Z&quot;
15        },
16        &quot;change&quot;: {
17            &quot;ChangedContent&quot;: &quot;LORA&quot;
18        }
19    }],
20    &quot;content&quot;: &quot;LMAO&quot;,
21    &quot;author&quot;: {
22        &quot;$oid&quot;: &quot;61df3cab3087579f8767a38d&quot;
23    }
24}
25{
26    &quot;_id&quot;: {
27        &quot;$oid&quot;: &quot;61efd41c56ffe6b1b4a15c7a&quot;
28    },
29    &quot;time&quot;: {
30        &quot;$date&quot;: &quot;2022-01-25T10:42:36.175Z&quot;
31    },
32    &quot;edited_time&quot;: {
33        &quot;$date&quot;: &quot;2022-01-30T14:40:57.152Z&quot;
34    },
35    &quot;changes&quot;: {
36        &quot;$concatArrays&quot;: [&quot;$changes&quot;, [{
37            &quot;time&quot;: {
38                &quot;$date&quot;: &quot;2022-01-30T14:40:57.152Z&quot;
39            },
40            &quot;change&quot;: {
41                &quot;ChangedContent&quot;: &quot;$content&quot;
42            }
43        }]]
44    },
45    &quot;content&quot;: &quot;LMAO&quot;,
46    &quot;author&quot;: {
47        &quot;$oid&quot;: &quot;61df3cab3087579f8767a38d&quot;
48    }
49}
50{
51  &quot;changes&quot;: { $concatArrays: [ &quot;$changes&quot;,  [ { &quot;time&quot;: ISODate('2021-12-17T09:55:45.856+00:00'), &quot;change&quot;: { &quot;ChangedContent&quot;: &quot;$content&quot; } } ] ] },
52  &quot;edited_time&quot;: ISODate('2021-12-17T09:55:45.856+00:00'),
53  &quot;content&quot;: &quot;LMAO&quot;,
54}
55    let update_doc = doc! {
56        &quot;$set&quot;: {
57            &quot;changes&quot;: {
58                &quot;$concatArrays&quot;: [
59                    &quot;$changes&quot;, [
60                        {
61                            &quot;time&quot;: now,
62                            &quot;change&quot;: {
63                                &quot;ChangedContent&quot;: &quot;$content&quot;
64                            }
65                        }
66                    ]
67                ]
68            },
69            &quot;edited_time&quot;: now,
70            &quot;content&quot;: content
71        }
72    };
73 messages.update_one(message_filter, update_doc, None).await?;
74let update_doc = doc! {
75    &quot;$set&quot;: {
76        &quot;edited_time&quot;: now,
77        &quot;content&quot;: content
78    },
79    &quot;$push&quot;: {
80        &quot;changes&quot;: {
81            &quot;time&quot;: now,
82            &quot;change&quot;: {
83                &quot;ChangedContent&quot;: &quot;$content&quot;
84            }
85        }
86    }
87};
88let update_pipeline = vec![
89    doc! {
90        &quot;$set&quot;: {
91            &quot;changes&quot;: {
92                &quot;$concatArrays&quot;: [
93                    &quot;$changes&quot;, [
94                        {
95                            &quot;time&quot;: now,
96                            &quot;change&quot;: {
97                                &quot;ChangedContent&quot;: &quot;$content&quot;
98                            }
99                        }
100                    ]
101                ]
102            },
103            &quot;edited_time&quot;: now,
104            &quot;content&quot;: content
105        }
106    }
107];
108
109messages.update_one(message_filter, update_pipeline, None).await?;
110

Source https://stackoverflow.com/questions/70915798

QUESTION

How use multiple socket.io servers with different library version on the same Node.js application

Asked 2022-Jan-29 at 12:35

As the title suggests I'm trying to use in the same application two different socket.io servers, one with socket.ioV4 and the other with socket.ioV2, the servers go up but I fail to get the sockets to connect.

A bit of context: the reason I'm trying to do this is because two clients need to exchange data using the Node.js application as a bridge, and each of them requires a different version of the socket.io package (as mentioned, V4 vs V2).

What I managed to do: I installed the V4 version as usual and the V2 version using an alias

1npm install socket.io@^4.4.1
2
3npm install socket.io-v2@npm:socket.io@2.0.1
4

and I created the two servers with

1npm install socket.io@^4.4.1
2
3npm install socket.io-v2@npm:socket.io@2.0.1
4const express = require('express');
5const http = require('http');
6const { Server } = require('socket.io');
7
8const app = express();
9const server = http.createServer(app);
10const io = new Server(server);
11
12const v2_server = require('http').Server(app);
13const iov2 = require('socket.io-v2')(v2_server);
14

The socket.io servers are defined as such

1npm install socket.io@^4.4.1
2
3npm install socket.io-v2@npm:socket.io@2.0.1
4const express = require('express');
5const http = require('http');
6const { Server } = require('socket.io');
7
8const app = express();
9const server = http.createServer(app);
10const io = new Server(server);
11
12const v2_server = require('http').Server(app);
13const iov2 = require('socket.io-v2')(v2_server);
14io.on('connection', (socket) =&gt; {
15    // DEBUG
16    console.log(&quot;V4 data received&quot;);
17})
18
19iov2.on('connection', (socket) =&gt; {
20    // DEBUG
21    console.log(&quot;V2 data received&quot;);
22})
23

Then I spin up the two servers on two different ports

1npm install socket.io@^4.4.1
2
3npm install socket.io-v2@npm:socket.io@2.0.1
4const express = require('express');
5const http = require('http');
6const { Server } = require('socket.io');
7
8const app = express();
9const server = http.createServer(app);
10const io = new Server(server);
11
12const v2_server = require('http').Server(app);
13const iov2 = require('socket.io-v2')(v2_server);
14io.on('connection', (socket) =&gt; {
15    // DEBUG
16    console.log(&quot;V4 data received&quot;);
17})
18
19iov2.on('connection', (socket) =&gt; {
20    // DEBUG
21    console.log(&quot;V2 data received&quot;);
22})
23app.get(&quot;&quot;, (req, res)=&gt;{
24res.sendFile(__dirname + '/static/test.html')
25})
26
27
28server.listen(conn_port, () =&gt; {
29    console.log(&quot;V4 server started.&quot;)
30})
31
32
33v2_server.listen(v2_conn_port, () =&gt; {
34    console.log(&quot;V2 server started.&quot;)
35})
36

and they do appear running as both logs are printed.

However, as I try to connect to the localhost on both ports, while I do see the html page provided, the socket.io connection doesn't seem to go through, as neither of the "Vx data received" logs appear (and buttons on the test page used to exchange data are unresponsive).

I'm pretty sure there might be a plethora of misplaced or misunderstood things here, as I'm just moving my first steps on node.js and web servers in general, so thanks in advance for the help and the patience!

ANSWER

Answered 2022-Jan-28 at 07:27

You cannot create two servers on the same HTTP port. However you can do something like this without attaching it to HTTP port:

1npm install socket.io@^4.4.1
2
3npm install socket.io-v2@npm:socket.io@2.0.1
4const express = require('express');
5const http = require('http');
6const { Server } = require('socket.io');
7
8const app = express();
9const server = http.createServer(app);
10const io = new Server(server);
11
12const v2_server = require('http').Server(app);
13const iov2 = require('socket.io-v2')(v2_server);
14io.on('connection', (socket) =&gt; {
15    // DEBUG
16    console.log(&quot;V4 data received&quot;);
17})
18
19iov2.on('connection', (socket) =&gt; {
20    // DEBUG
21    console.log(&quot;V2 data received&quot;);
22})
23app.get(&quot;&quot;, (req, res)=&gt;{
24res.sendFile(__dirname + '/static/test.html')
25})
26
27
28server.listen(conn_port, () =&gt; {
29    console.log(&quot;V4 server started.&quot;)
30})
31
32
33v2_server.listen(v2_conn_port, () =&gt; {
34    console.log(&quot;V2 server started.&quot;)
35})
36const { Server } = require('socket.io');
37const firstServer = new Server();
38firstServer.listen(3000);
39
40const secondServer = new Server();
41firstServer.listen(4000);
42

Source https://stackoverflow.com/questions/70882617

QUESTION

Azure Front Door to Website on IIS VM Host

Asked 2022-Jan-25 at 19:14

I've got an Azure Front Door that has been set up to link to 2 Windows VM's running IIS, I'm trying to add a Frontend Domain that I can then use to access websites on the VM's. Azure Frontend Domain

Then I have the backend pool which links to the 2 servers. Back End Pool

I then have a route to the web servers, which should (as far as I can tell) just forward the request onwards. Routing Rule

Then I have my web servers which I have set up the bindings on for the website Website Bindings

However whenever I try to browse to the website I just see the IIS landing page rather than the website I have setup. How do I get to my actual website?

ANSWER

Answered 2022-Jan-17 at 05:10

if you get the IIS landing page it means the traffic is forwarded correctly from the AFD, your problem is likely with the local IIS setup like the default page or something like that.

Source https://stackoverflow.com/questions/70420797

QUESTION

Why is my non blocking raw sockets program running so slowly?

Asked 2022-Jan-11 at 20:59

I have a program which uses PF_PACKET raw sockets to send TCP SYN packets to a list of web servers. The program reads in a file which has an IPv4 address on each line of a web server. The program is the beginnings of an attempt to connect to multiple servers in a high performance manner. However, currently the program is only sending about 10 packets/second. This despite the program using non blocking socket. It should be running orders of magnitude faster. Any ideas why it could be running so slowly.

I include a full code listing below. Warning - the code is quite long. That's because it takes a surprisingly large amount of code to get the IP and MAC address of the gateway router. The good news is you can skip all the functions before main because they just do the necessary work of getting the IP and MAC address of the router as well as the local IP address. Anyway, here's the code:

1#include &lt;sys/types.h&gt;
2#include &lt;sys/socket.h&gt;
3#include &lt;arpa/inet.h&gt;
4#include &lt;linux/if_packet.h&gt;
5#include &lt;net/ethernet.h&gt;
6#include &lt;stdlib.h&gt;
7#include &lt;stdio.h&gt;
8#include &lt;errno.h&gt;
9#include &lt;string.h&gt;
10#include &lt;sys/mman.h&gt;
11#include &lt;unistd.h&gt;
12#include &lt;sys/ioctl.h&gt;
13#include &lt;net/if.h&gt;
14#include &lt;netinet/tcp.h&gt;    //Provides declarations for tcp header
15#include &lt;netinet/ip.h&gt; //Provides declarations for ip header
16#include &lt;netinet/ether.h&gt;
17#include &lt;ifaddrs.h&gt;
18#include &lt;asm/types.h&gt;
19#include &lt;linux/if_ether.h&gt;
20//#include &lt;linux/if_arp.h&gt;
21#include &lt;arpa/inet.h&gt;  //htons etc
22#include &lt;time.h&gt;
23#include &lt;linux/rtnetlink.h&gt;
24#include &lt;sys/resource.h&gt;
25
26#define PROTO_ARP 0x0806
27#define ETH2_HEADER_LEN 14
28#define HW_TYPE 1
29#define MAC_LENGTH 6
30#define IPV4_LENGTH 4
31#define ARP_REQUEST 0x01
32#define ARP_REPLY 0x02
33#define BUF_SIZE 60
34#define MAX_CONNECTIONS 10000
35
36#define debug(x...) printf(x);printf(&quot;\n&quot;);
37#define info(x...) printf(x);printf(&quot;\n&quot;);
38#define warn(x...) printf(x);printf(&quot;\n&quot;);
39#define err(x...) printf(x);printf(&quot;\n&quot;);
40
41static char * str_devname= NULL;
42static int mode_loss     = 0;
43static int c_packet_sz   = 150;
44static int c_buffer_sz   = 1024*8;
45static int c_buffer_nb   = 1024;
46static int c_sndbuf_sz   = 0;
47static int c_send_mask   = 127;
48static int c_error       = 0;
49static int c_mtu         = 0;
50static int mode_thread   = 0;
51
52volatile int fd_socket;
53volatile int data_offset = 0;
54volatile struct tpacket_hdr * ps_header_start;
55volatile struct sockaddr_ll *ps_sockaddr = NULL;
56volatile int shutdown_flag = 0;
57int done = 0;
58struct tpacket_req s_packet_req;
59unsigned char buffer[BUF_SIZE];
60struct arp_header *arp_resp = (struct arp_header *) (buffer + ETH2_HEADER_LEN);
61char ifname[512];
62char ip[512];
63
64/* 
65    96 bit (12 bytes) pseudo header needed for tcp header checksum calculation 
66*/
67struct pseudo_header
68{
69    u_int32_t source_address;
70    u_int32_t dest_address;
71    u_int8_t placeholder;
72    u_int8_t protocol;
73    u_int16_t tcp_length;
74};
75
76
77struct arp_header {
78    unsigned short hardware_type;
79    unsigned short protocol_type;
80    unsigned char hardware_len;
81    unsigned char protocol_len;
82    unsigned short opcode;
83    unsigned char sender_mac[MAC_LENGTH];
84    unsigned char sender_ip[IPV4_LENGTH];
85    unsigned char target_mac[MAC_LENGTH];
86    unsigned char target_ip[IPV4_LENGTH];
87};
88
89int rtnl_receive(int fd, struct msghdr *msg, int flags)
90{
91    int len;
92
93    do { 
94        len = recvmsg(fd, msg, flags);
95    } while (len &lt; 0 &amp;&amp; (errno == EINTR || errno == EAGAIN));
96
97    if (len &lt; 0) {
98        perror(&quot;Netlink receive failed&quot;);
99        return -errno;
100    }
101
102    if (len == 0) { 
103        perror(&quot;EOF on netlink&quot;);
104        return -ENODATA;
105    }
106
107    return len;
108}
109
110static int rtnl_recvmsg(int fd, struct msghdr *msg, char **answer)
111{
112    struct iovec *iov = msg-&gt;msg_iov;
113    char *buf;
114    int len;
115
116    iov-&gt;iov_base = NULL;
117    iov-&gt;iov_len = 0;
118
119    len = rtnl_receive(fd, msg, MSG_PEEK | MSG_TRUNC);
120
121    if (len &lt; 0) {
122        return len;
123    }
124
125    buf = malloc(len);
126
127    if (!buf) {
128        perror(&quot;malloc failed&quot;);
129        return -ENOMEM;
130    }
131
132    iov-&gt;iov_base = buf;
133    iov-&gt;iov_len = len;
134
135    len = rtnl_receive(fd, msg, 0);
136
137    if (len &lt; 0) {
138        free(buf);
139        return len;
140    }
141
142    *answer = buf;
143
144    return len;
145}
146
147void parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len)
148{
149    memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
150
151    while (RTA_OK(rta, len)) {
152        if (rta-&gt;rta_type &lt;= max) {
153            tb[rta-&gt;rta_type] = rta;
154        }
155
156        rta = RTA_NEXT(rta,len);
157    }
158}
159
160static inline int rtm_get_table(struct rtmsg *r, struct rtattr **tb)
161{
162    __u32 table = r-&gt;rtm_table;
163
164    if (tb[RTA_TABLE]) {
165        table = *(__u32 *)RTA_DATA(tb[RTA_TABLE]);
166    }
167
168    return table;
169}
170
171void print_route(struct nlmsghdr* nl_header_answer)
172{
173    struct rtmsg* r = NLMSG_DATA(nl_header_answer);
174    int len = nl_header_answer-&gt;nlmsg_len;
175    struct rtattr* tb[RTA_MAX+1];
176    int table;
177    char buf[256];
178
179    len -= NLMSG_LENGTH(sizeof(*r));
180
181    if (len &lt; 0) {
182        perror(&quot;Wrong message length&quot;);
183        return;
184    }
185    
186    parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
187
188    table = rtm_get_table(r, tb);
189
190    if (r-&gt;rtm_family != AF_INET &amp;&amp; table != RT_TABLE_MAIN) {
191        return;
192    }
193
194    if (tb[RTA_DST]) {
195        if ((r-&gt;rtm_dst_len != 24) &amp;&amp; (r-&gt;rtm_dst_len != 16)) {
196            return;
197        }
198
199        printf(&quot;%s/%u &quot;, inet_ntop(r-&gt;rtm_family, RTA_DATA(tb[RTA_DST]), buf, sizeof(buf)), r-&gt;rtm_dst_len);
200
201    } else if (r-&gt;rtm_dst_len) {
202        printf(&quot;0/%u &quot;, r-&gt;rtm_dst_len);
203    } else {
204        printf(&quot;default &quot;);
205    }
206
207    if (tb[RTA_GATEWAY]) {
208        printf(&quot;via %s&quot;, inet_ntop(r-&gt;rtm_family, RTA_DATA(tb[RTA_GATEWAY]), buf, sizeof(buf)));
209        strcpy(ip, inet_ntop(r-&gt;rtm_family, RTA_DATA(tb[RTA_GATEWAY]), buf, sizeof(buf)));
210    }
211
212    if (tb[RTA_OIF]) {
213        char if_nam_buf[IF_NAMESIZE];
214        int ifidx = *(__u32 *)RTA_DATA(tb[RTA_OIF]);
215
216        printf(&quot; dev %s&quot;, if_indextoname(ifidx, if_nam_buf));
217    }
218
219    if (tb[RTA_GATEWAY] &amp;&amp; tb[RTA_OIF]) {
220        char if_nam_buf[IF_NAMESIZE];
221        int ifidx = *(__u32 *)RTA_DATA(tb[RTA_OIF]);
222
223        strcpy(ifname, if_indextoname(ifidx, if_nam_buf));
224    }
225
226    if (tb[RTA_SRC]) {
227        printf(&quot;src %s&quot;, inet_ntop(r-&gt;rtm_family, RTA_DATA(tb[RTA_SRC]), buf, sizeof(buf)));
228    }
229
230    printf(&quot;\n&quot;);
231}
232
233int open_netlink()
234{
235    struct sockaddr_nl saddr;
236
237    int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
238
239    if (sock &lt; 0) {
240        perror(&quot;Failed to open netlink socket&quot;);
241        return -1;
242    }
243
244    memset(&amp;saddr, 0, sizeof(saddr));
245
246    saddr.nl_family = AF_NETLINK;
247    saddr.nl_pid = getpid();
248
249    if (bind(sock, (struct sockaddr *)&amp;saddr, sizeof(saddr)) &lt; 0) {
250        perror(&quot;Failed to bind to netlink socket&quot;);
251        close(sock);
252        return -1;
253    }
254
255    return sock;
256}
257
258int do_route_dump_requst(int sock)
259{
260    struct {
261        struct nlmsghdr nlh;
262        struct rtmsg rtm;
263    } nl_request;
264
265    nl_request.nlh.nlmsg_type = RTM_GETROUTE;
266    nl_request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
267    nl_request.nlh.nlmsg_len = sizeof(nl_request);
268    nl_request.nlh.nlmsg_seq = time(NULL);
269    nl_request.rtm.rtm_family = AF_INET;
270
271    return send(sock, &amp;nl_request, sizeof(nl_request), 0);
272}
273
274int get_route_dump_response(int sock)
275{
276    struct sockaddr_nl nladdr;
277    struct iovec iov;
278    struct msghdr msg = {
279        .msg_name = &amp;nladdr,
280        .msg_namelen = sizeof(nladdr),
281        .msg_iov = &amp;iov,
282        .msg_iovlen = 1,
283    };
284
285    char *buf;
286    int dump_intr = 0;
287
288    int status = rtnl_recvmsg(sock, &amp;msg, &amp;buf);
289
290    struct nlmsghdr *h = (struct nlmsghdr *)buf;
291    int msglen = status;
292
293    printf(&quot;Main routing table IPv4\n&quot;);
294
295    while (NLMSG_OK(h, msglen)) {
296        if (h-&gt;nlmsg_flags &amp; NLM_F_DUMP_INTR) {
297            fprintf(stderr, &quot;Dump was interrupted\n&quot;);
298            free(buf);
299            return -1;
300        }
301
302        if (nladdr.nl_pid != 0) {
303            continue;
304        }
305
306        if (h-&gt;nlmsg_type == NLMSG_ERROR) {
307            perror(&quot;netlink reported error&quot;);
308            free(buf);
309        }
310
311        print_route(h);
312
313        h = NLMSG_NEXT(h, msglen);
314    }
315
316    free(buf);
317
318    return status;
319}
320
321
322/*
323 * Converts struct sockaddr with an IPv4 address to network byte order uin32_t.
324 * Returns 0 on success.
325 */
326int int_ip4(struct sockaddr *addr, uint32_t *ip)
327{
328    if (addr-&gt;sa_family == AF_INET) {
329        struct sockaddr_in *i = (struct sockaddr_in *) addr;
330        *ip = i-&gt;sin_addr.s_addr;
331        return 0;
332    } else {
333        err(&quot;Not AF_INET&quot;);
334        return 1;
335    }
336}
337
338/*
339 * Formats sockaddr containing IPv4 address as human readable string.
340 * Returns 0 on success.
341 */
342int format_ip4(struct sockaddr *addr, char *out)
343{
344    if (addr-&gt;sa_family == AF_INET) {
345        struct sockaddr_in *i = (struct sockaddr_in *) addr;
346        const char *ip = inet_ntoa(i-&gt;sin_addr);
347        if (!ip) {
348            return -2;
349        } else {
350            strcpy(out, ip);
351            return 0;
352        }
353    } else {
354        return -1;
355    }
356}
357
358/*
359 * Writes interface IPv4 address as network byte order to ip.
360 * Returns 0 on success.
361 */
362int get_if_ip4(int fd, const char *ifname, uint32_t *ip) {
363    int err = -1;
364    struct ifreq ifr;
365    memset(&amp;ifr, 0, sizeof(struct ifreq));
366    if (strlen(ifname) &gt; (IFNAMSIZ - 1)) {
367        err(&quot;Too long interface name&quot;);
368        goto out;
369    }
370
371    strcpy(ifr.ifr_name, ifname);
372    if (ioctl(fd, SIOCGIFADDR, &amp;ifr) == -1) {
373        perror(&quot;SIOCGIFADDR&quot;);
374        goto out;
375    }
376
377    if (int_ip4(&amp;ifr.ifr_addr, ip)) {
378        goto out;
379    }
380    err = 0;
381out:
382    return err;
383}
384
385/*
386 * Sends an ARP who-has request to dst_ip
387 * on interface ifindex, using source mac src_mac and source ip src_ip.
388 */
389int send_arp(int fd, int ifindex, const unsigned char *src_mac, uint32_t src_ip, uint32_t dst_ip)
390{
391    int err = -1;
392    unsigned char buffer[BUF_SIZE];
393    memset(buffer, 0, sizeof(buffer));
394
395    struct sockaddr_ll socket_address;
396    socket_address.sll_family = AF_PACKET;
397    socket_address.sll_protocol = htons(ETH_P_ARP);
398    socket_address.sll_ifindex = ifindex;
399    socket_address.sll_hatype = htons(ARPHRD_ETHER);
400    socket_address.sll_pkttype = (PACKET_BROADCAST);
401    socket_address.sll_halen = MAC_LENGTH;
402    socket_address.sll_addr[6] = 0x00;
403    socket_address.sll_addr[7] = 0x00;
404
405    struct ethhdr *send_req = (struct ethhdr *) buffer;
406    struct arp_header *arp_req = (struct arp_header *) (buffer + ETH2_HEADER_LEN);
407    int index;
408    ssize_t ret, length = 0;
409
410    //Broadcast
411    memset(send_req-&gt;h_dest, 0xff, MAC_LENGTH);
412
413    //Target MAC zero
414    memset(arp_req-&gt;target_mac, 0x00, MAC_LENGTH);
415
416    //Set source mac to our MAC address
417    memcpy(send_req-&gt;h_source, src_mac, MAC_LENGTH);
418    memcpy(arp_req-&gt;sender_mac, src_mac, MAC_LENGTH);
419    memcpy(socket_address.sll_addr, src_mac, MAC_LENGTH);
420
421    /* Setting protocol of the packet */
422    send_req-&gt;h_proto = htons(ETH_P_ARP);
423
424    /* Creating ARP request */
425    arp_req-&gt;hardware_type = htons(HW_TYPE);
426    arp_req-&gt;protocol_type = htons(ETH_P_IP);
427    arp_req-&gt;hardware_len = MAC_LENGTH;
428    arp_req-&gt;protocol_len = IPV4_LENGTH;
429    arp_req-&gt;opcode = htons(ARP_REQUEST);
430
431    debug(&quot;Copy IP address to arp_req&quot;);
432    memcpy(arp_req-&gt;sender_ip, &amp;src_ip, sizeof(uint32_t));
433    memcpy(arp_req-&gt;target_ip, &amp;dst_ip, sizeof(uint32_t));
434
435    ret = sendto(fd, buffer, 42, 0, (struct sockaddr *) &amp;socket_address, sizeof(socket_address));
436    if (ret == -1) {
437        perror(&quot;sendto():&quot;);
438        goto out;
439    }
440    err = 0;
441out:
442    return err;
443}
444
445/*
446 * Gets interface information by name:
447 * IPv4
448 * MAC
449 * ifindex
450 */
451int get_if_info(const char *ifname, uint32_t *ip, char *mac, int *ifindex)
452{
453    debug(&quot;get_if_info for %s&quot;, ifname);
454    int err = -1;
455    struct ifreq ifr;
456    int sd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ARP));
457    if (sd &lt;= 0) {
458        perror(&quot;socket()&quot;);
459        goto out;
460    }
461    if (strlen(ifname) &gt; (IFNAMSIZ - 1)) {
462        printf(&quot;Too long interface name, MAX=%i\n&quot;, IFNAMSIZ - 1);
463        goto out;
464    }
465
466    strcpy(ifr.ifr_name, ifname);
467
468    //Get interface index using name
469    if (ioctl(sd, SIOCGIFINDEX, &amp;ifr) == -1) {
470        perror(&quot;SIOCGIFINDEX&quot;);
471        goto out;
472    }
473    *ifindex = ifr.ifr_ifindex;
474    printf(&quot;interface index is %d\n&quot;, *ifindex);
475
476    //Get MAC address of the interface
477    if (ioctl(sd, SIOCGIFHWADDR, &amp;ifr) == -1) {
478        perror(&quot;SIOCGIFINDEX&quot;);
479        goto out;
480    }
481
482    //Copy mac address to output
483    memcpy(mac, ifr.ifr_hwaddr.sa_data, MAC_LENGTH);
484
485    if (get_if_ip4(sd, ifname, ip)) {
486        goto out;
487    }
488    debug(&quot;get_if_info OK&quot;);
489
490    err = 0;
491out:
492    if (sd &gt; 0) {
493        debug(&quot;Clean up temporary socket&quot;);
494        close(sd);
495    }
496    return err;
497}
498
499/*
500 * Creates a raw socket that listens for ARP traffic on specific ifindex.
501 * Writes out the socket's FD.
502 * Return 0 on success.
503 */
504int bind_arp(int ifindex, int *fd)
505{
506    debug(&quot;bind_arp: ifindex=%i&quot;, ifindex);
507    int ret = -1;
508
509    // Submit request for a raw socket descriptor.
510    *fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ARP));
511    if (*fd &lt; 1) {
512        perror(&quot;socket()&quot;);
513        goto out;
514    }
515
516    debug(&quot;Binding to ifindex %i&quot;, ifindex);
517    struct sockaddr_ll sll;
518    memset(&amp;sll, 0, sizeof(struct sockaddr_ll));
519    sll.sll_family = AF_PACKET;
520    sll.sll_ifindex = ifindex;
521    if (bind(*fd, (struct sockaddr*) &amp;sll, sizeof(struct sockaddr_ll)) &lt; 0) {
522        perror(&quot;bind&quot;);
523        goto out;
524    }
525
526    ret = 0;
527out:
528    if (ret &amp;&amp; *fd &gt; 0) {
529        debug(&quot;Cleanup socket&quot;);
530        close(*fd);
531    }
532    return ret;
533}
534
535/*
536 * Reads a single ARP reply from fd.
537 * Return 0 on success.
538 */
539int read_arp(int fd)
540{
541    debug(&quot;read_arp&quot;);
542    int ret = -1;
543    ssize_t length = recvfrom(fd, buffer, BUF_SIZE, 0, NULL, NULL);
544    int index;
545    if (length == -1) {
546        perror(&quot;recvfrom()&quot;);
547        goto out;
548    }
549    struct ethhdr *rcv_resp = (struct ethhdr *) buffer;
550    if (ntohs(rcv_resp-&gt;h_proto) != PROTO_ARP) {
551        debug(&quot;Not an ARP packet&quot;);
552        goto out;
553    }
554    if (ntohs(arp_resp-&gt;opcode) != ARP_REPLY) {
555        debug(&quot;Not an ARP reply&quot;);
556        goto out;
557    }
558    debug(&quot;received ARP len=%ld&quot;, length);
559    struct in_addr sender_a;
560    memset(&amp;sender_a, 0, sizeof(struct in_addr));
561    memcpy(&amp;sender_a.s_addr, arp_resp-&gt;sender_ip, sizeof(uint32_t));
562    debug(&quot;Sender IP: %s&quot;, inet_ntoa(sender_a));
563
564    debug(&quot;Sender MAC: %02X:%02X:%02X:%02X:%02X:%02X&quot;,
565          arp_resp-&gt;sender_mac[0],
566          arp_resp-&gt;sender_mac[1],
567          arp_resp-&gt;sender_mac[2],
568          arp_resp-&gt;sender_mac[3],
569          arp_resp-&gt;sender_mac[4],
570          arp_resp-&gt;sender_mac[5]);
571
572    ret = 0;
573
574out:
575    return ret;
576}
577
578/*
579 *
580 * Sample code that sends an ARP who-has request on
581 * interface &lt;ifname&gt; to IPv4 address &lt;ip&gt;.
582 * Returns 0 on success.
583 */
584int test_arping(const char *ifname, const char *ip) {
585    int ret = -1;
586    uint32_t dst = inet_addr(ip);
587    if (dst == 0 || dst == 0xffffffff) {
588        printf(&quot;Invalid source IP\n&quot;);
589        return 1;
590    }
591
592    int src;
593    int ifindex;
594    char mac[MAC_LENGTH];
595    if (get_if_info(ifname, &amp;src, mac, &amp;ifindex)) {
596        err(&quot;get_if_info failed, interface %s not found or no IP set?&quot;, ifname);
597        goto out;
598    }
599    int arp_fd;
600    if (bind_arp(ifindex, &amp;arp_fd)) {
601        err(&quot;Failed to bind_arp()&quot;);
602        goto out;
603    }
604
605    if (send_arp(arp_fd, ifindex, mac, src, dst)) {
606        err(&quot;Failed to send_arp&quot;);
607        goto out;
608    }
609
610    while(1) {
611        int r = read_arp(arp_fd);
612        if (r == 0) {
613            info(&quot;Got reply, break out&quot;);
614            break;
615        }
616    }
617
618    ret = 0;
619out:
620    if (arp_fd) {
621        close(arp_fd);
622        arp_fd = 0;
623    }
624    return ret;
625}
626
627unsigned short checksum2(const char *buf, unsigned size)
628{
629    unsigned long long sum = 0;
630    const unsigned long long *b = (unsigned long long *) buf;
631
632    unsigned t1, t2;
633    unsigned short t3, t4;
634
635    /* Main loop - 8 bytes at a time */
636    while (size &gt;= sizeof(unsigned long long))
637    {
638        unsigned long long s = *b++;
639        sum += s;
640        if (sum &lt; s) sum++;
641        size -= 8;
642    }
643
644    /* Handle tail less than 8-bytes long */
645    buf = (const char *) b;
646    if (size &amp; 4)
647    {
648        unsigned s = *(unsigned *)buf;
649        sum += s;
650        if (sum &lt; s) sum++;
651        buf += 4;
652    }
653
654    if (size &amp; 2)
655    {
656        unsigned short s = *(unsigned short *) buf;
657        sum += s;
658        if (sum &lt; s) sum++;
659        buf += 2;
660    }
661
662    if (size)
663    {
664        unsigned char s = *(unsigned char *) buf;
665        sum += s;
666        if (sum &lt; s) sum++;
667    }
668
669    /* Fold down to 16 bits */
670    t1 = sum;
671    t2 = sum &gt;&gt; 32;
672    t1 += t2;
673    if (t1 &lt; t2) t1++;
674    t3 = t1;
675    t4 = t1 &gt;&gt; 16;
676    t3 += t4;
677    if (t3 &lt; t4) t3++;
678
679    return ~t3;
680}
681
682int main( int argc, char ** argv )
683{
684    uint32_t size;
685    size_t len;
686    struct sockaddr_ll my_addr, peer_addr;
687    int i_ifindex;
688    int ec;
689    struct ifreq s_ifr; /* points to one interface returned from ioctl */
690    int tmp;
691    FILE * fp;
692    char server[254];
693    int count = 0;
694    int first_time = 1;
695    int z;
696    int first_mmap = 1;
697    
698    #define HWADDR_len 6
699    #define IP_len 4
700    int s,s2,i;
701    struct ifreq ifr,ifr2;
702    int ret = -1;
703    struct rlimit lim;
704    
705    if (argc != 2) {
706        printf(&quot;Usage: %s &lt;INPUT_FILE&gt;\n&quot;, argv[0]);
707        return 1;
708    }
709
710    getrlimit(RLIMIT_NOFILE, &amp;lim);
711    printf(&quot;Soft: %d Hard: %d\n&quot;, (int)lim.rlim_cur, (int)lim.rlim_max);
712    lim.rlim_cur = lim.rlim_max;
713    
714    
715    if (setrlimit(RLIMIT_NOFILE, &amp;lim) == -1) {
716        printf(&quot;rlimit failed\n&quot;);
717        return -1;
718    }
719    getrlimit(RLIMIT_NOFILE, &amp;lim);
720    printf(&quot;New Soft: %d New Hard: %d\n&quot;, (int)lim.rlim_cur, (int)lim.rlim_max);
721    
722    int nl_sock = open_netlink();
723
724    if (do_route_dump_requst(nl_sock) &lt; 0) {
725        perror(&quot;Failed to perfom request&quot;);
726        close(nl_sock);
727        return -1;
728    }
729
730    get_route_dump_response(nl_sock);
731
732    close (nl_sock);
733    
734    test_arping(ifname, ip);
735
736    
737    s = socket(AF_INET, SOCK_DGRAM, 0);
738    s2 = socket(AF_INET, SOCK_DGRAM, 0);
739    strcpy(ifr.ifr_name, ifname);
740    strcpy(ifr2.ifr_name, ifname);
741    ioctl(s, SIOCGIFHWADDR, &amp;ifr);
742    ioctl(s2, SIOCGIFADDR, &amp;ifr2);
743    struct sockaddr_in* ipaddr = (struct sockaddr_in*)&amp;ifr2.ifr_addr;
744    close(s);
745
746    fp = fopen(argv[1], &quot;r&quot;);
747    if (!fp)
748        exit(EXIT_FAILURE);
749
750
751    while (!done)
752    {   
753        fd_socket = socket(PF_PACKET, SOCK_RAW|SOCK_NONBLOCK, htons(ETH_P_ALL));
754        if(fd_socket == -1)
755        {
756            perror(&quot;socket&quot;);
757            return EXIT_FAILURE;
758        }
759    
760        /* clear structure */
761        memset(&amp;my_addr, 0, sizeof(struct sockaddr_ll));
762        my_addr.sll_family = PF_PACKET;
763        my_addr.sll_protocol = htons(ETH_P_ALL);
764    
765        str_devname = ifname;
766        //strcpy (str_devname, ifname);
767        
768        /* initialize interface struct */
769        strncpy (s_ifr.ifr_name, str_devname, sizeof(s_ifr.ifr_name));
770    
771        /* Get the broad cast address */
772        ec = ioctl(fd_socket, SIOCGIFINDEX, &amp;s_ifr);
773        if(ec == -1)
774        {
775            perror(&quot;iotcl&quot;);
776            return EXIT_FAILURE;
777        }
778    
779        /* update with interface index */
780        i_ifindex = s_ifr.ifr_ifindex;
781    
782        s_ifr.ifr_mtu = 7200;
783        /* update the mtu through ioctl */
784        ec = ioctl(fd_socket, SIOCSIFMTU, &amp;s_ifr);
785        if(ec == -1)
786        {
787            perror(&quot;iotcl&quot;);
788            return EXIT_FAILURE;
789        }
790    
791        /* set sockaddr info */
792        memset(&amp;my_addr, 0, sizeof(struct sockaddr_ll));
793        my_addr.sll_family = AF_PACKET;
794        my_addr.sll_protocol = ETH_P_ALL;
795        my_addr.sll_ifindex = i_ifindex;
796    
797        /* bind port */
798        if (bind(fd_socket, (struct sockaddr *)&amp;my_addr, sizeof(struct sockaddr_ll)) == -1)
799        {
800            perror(&quot;bind&quot;);
801            return EXIT_FAILURE;
802        }
803    
804        /* prepare Tx ring request */
805        s_packet_req.tp_block_size = c_buffer_sz;
806        s_packet_req.tp_frame_size = c_buffer_sz;
807        s_packet_req.tp_block_nr = c_buffer_nb;
808        s_packet_req.tp_frame_nr = c_buffer_nb;
809    
810        /* calculate memory to mmap in the kernel */
811        size = s_packet_req.tp_block_size * s_packet_req.tp_block_nr;
812    
813        /* set packet loss option */
814        tmp = mode_loss;
815        if (setsockopt(fd_socket, SOL_PACKET, PACKET_LOSS, (char *)&amp;tmp, sizeof(tmp))&lt;0)
816        {
817            perror(&quot;setsockopt: PACKET_LOSS&quot;);
818            return EXIT_FAILURE;
819        }
820        
821        /* send TX ring request */
822        if (setsockopt(fd_socket, SOL_PACKET, PACKET_TX_RING, (char *)&amp;s_packet_req, sizeof(s_packet_req))&lt;0)
823        {
824            perror(&quot;setsockopt: PACKET_TX_RING&quot;);
825            return EXIT_FAILURE;
826        }
827    
828        /* change send buffer size */
829        if(c_sndbuf_sz) {
830            printf(&quot;send buff size = %d\n&quot;, c_sndbuf_sz);
831            if (setsockopt(fd_socket, SOL_SOCKET, SO_SNDBUF, &amp;c_sndbuf_sz, sizeof(c_sndbuf_sz))&lt; 0)
832            {
833                perror(&quot;getsockopt: SO_SNDBUF&quot;);
834                return EXIT_FAILURE;
835            }
836        }
837    
838        /* get data offset */
839        data_offset = TPACKET_HDRLEN - sizeof(struct sockaddr_ll);
840    
841        /* mmap Tx ring buffers memory */
842        ps_header_start = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd_socket, 0);
843        if (ps_header_start == (void*)-1)
844        {
845            perror(&quot;mmap&quot;);
846            return EXIT_FAILURE;
847        }
848    
849    
850        int i,j;
851        int i_index = 0;
852        char * data;
853        int first_loop = 1;
854        struct tpacket_hdr * ps_header;
855        int ec_send = 0;
856 
857        int i_index_start = i_index;
858        
859        ps_header = ((struct tpacket_hdr *)((void *)ps_header_start + (c_buffer_sz*i_index)));
860        data = ((void*) ps_header) + data_offset;
861        //Datagram to represent the packet
862        char datagram[4096] , source_ip[32] , *pseudogram;
863    
864        //zero out the packet buffer
865        memset (datagram, 0, 4096);
866    
867        //Ethernet header
868        struct ether_header *eh = (struct ether_header *) datagram;
869        
870        //IP header
871        struct iphdr *iph = (struct iphdr *) (datagram + sizeof (struct ether_header));
872    
873        //TCP header
874        struct tcphdr *tcph = (struct tcphdr *) (datagram + sizeof (struct ether_header) + sizeof (struct ip));
875        struct sockaddr_in sin;
876        struct pseudo_header psh;
877    
878        //some address resolution
879        strcpy(source_ip , inet_ntoa(ipaddr-&gt;sin_addr));
880        sin.sin_family = AF_INET;
881        sin.sin_port = htons(80);
882        if (fscanf(fp, &quot;%253s&quot;, server) == 1)
883            sin.sin_addr.s_addr = inet_addr (server);   
884        else
885        {
886            done = 1;
887            break;
888        }
889                        
890        //Fill in the Ethernet Header
891        eh-&gt;ether_dhost[0] = arp_resp-&gt;sender_mac[0];
892        eh-&gt;ether_dhost[1] = arp_resp-&gt;sender_mac[1];
893        eh-&gt;ether_dhost[2] = arp_resp-&gt;sender_mac[2];
894        eh-&gt;ether_dhost[3] = arp_resp-&gt;sender_mac[3];
895        eh-&gt;ether_dhost[4] = arp_resp-&gt;sender_mac[4];
896        eh-&gt;ether_dhost[5] = arp_resp-&gt;sender_mac[5];
897
898        memcpy(eh-&gt;ether_shost, ifr.ifr_hwaddr.sa_data, HWADDR_len);
899        eh-&gt;ether_type = htons(0x0800);
900                        
901        //Fill in the IP Header
902        iph-&gt;ihl = 5;
903        iph-&gt;version = 4;
904        iph-&gt;tos = 0;
905        iph-&gt;tot_len = htons(sizeof (struct iphdr) + sizeof (struct tcphdr));
906        iph-&gt;id = htons (54321);    //Id of this packet
907        iph-&gt;frag_off = 0;
908        iph-&gt;ttl = 255;
909        iph-&gt;protocol = IPPROTO_TCP;
910        iph-&gt;check = 0;     //Set to 0 before calculating checksum
911        iph-&gt;saddr = inet_addr ( source_ip );
912        iph-&gt;daddr = sin.sin_addr.s_addr;
913    
914        //Ip checksum
915        iph-&gt;check = checksum2 (datagram + sizeof (struct ether_header), sizeof (struct iphdr));
916    
917        //TCP Header
918        tcph-&gt;source = htons (1234);
919        tcph-&gt;dest = htons (80);
920        tcph-&gt;seq = 0;
921        tcph-&gt;ack_seq = 0;
922        tcph-&gt;doff = 5; //tcp header size
923        tcph-&gt;fin=0;
924        tcph-&gt;syn=1;
925        tcph-&gt;rst=0;
926        tcph-&gt;psh=0;
927        tcph-&gt;ack=0;
928        tcph-&gt;urg=0;
929        tcph-&gt;window = htons (5840);    // maximum allowed window size 
930        tcph-&gt;check = 0;    //leave checksum 0 now, filled later by pseudo header
931        tcph-&gt;urg_ptr = 0;
932
933        //Now the TCP checksum
934        psh.source_address = inet_addr( source_ip );
935        psh.dest_address = sin.sin_addr.s_addr;
936        psh.placeholder = 0;
937        psh.protocol = IPPROTO_TCP;
938        psh.tcp_length = htons(sizeof(struct tcphdr));
939    
940        int psize = sizeof(struct pseudo_header) + sizeof(struct tcphdr);
941        pseudogram = malloc(psize);
942    
943        memcpy(pseudogram , (char*) &amp;psh , sizeof (struct pseudo_header));
944        memcpy(pseudogram + sizeof(struct pseudo_header) , tcph , sizeof(struct tcphdr));
945    
946        tcph-&gt;check = checksum2(pseudogram , psize);
947                        
948        memcpy(data, datagram, (sizeof(struct ether_header) + sizeof(struct iphdr) + sizeof(struct tcphdr)));
949        free(pseudogram);
950        len = sizeof(struct ether_header) + sizeof(struct iphdr) + sizeof(struct tcphdr);
951        
952        i_index ++;
953        if(i_index &gt;= c_buffer_nb)
954        {
955            i_index = 0;
956            first_loop = 0;
957        }
958 
959        /* update packet len */
960        //ps_header-&gt;tp_len = c_packet_sz;
961        ps_header-&gt;tp_len = len;
962        /* set header flag to USER (trigs xmit)*/
963        ps_header-&gt;tp_status = TP_STATUS_SEND_REQUEST;
964        
965        //int ec_send;
966        static int total=0;
967        //int blocking = 1;
968        
969        /* send all buffers with TP_STATUS_SEND_REQUEST */
970        /* Wait end of transfer */
971        //ec_send = sendto(fd_socket,NULL,0,(blocking? 0 : MSG_DONTWAIT),(struct sockaddr *) ps_sockaddr,sizeof(struct sockaddr_ll));
972        ec_send = sendto(fd_socket,NULL,len,MSG_DONTWAIT,(struct sockaddr *) ps_sockaddr,sizeof(struct sockaddr_ll));
973        
974        if(ec_send &lt; 0) {
975            perror(&quot;sendto&quot;);
976        }
977        else if ( ec_send == 0 ) {
978            /* nothing to do =&gt; schedule : useful if no SMP */
979            printf(&quot;Sleeping\n&quot;);
980            usleep(0);
981        }
982        else {
983            total += ec_send/(len);
984            printf(&quot;send %d packets (+%d bytes)\n&quot;,total, ec_send);
985            fflush(0);
986        }
987        //ps_header_start = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd_socket, 0);
988        if (munmap(ps_header_start, size) == -1)
989        {
990            perror(&quot;munmap&quot;);
991            exit(EXIT_FAILURE);
992        }       
993    
994        close(fd_socket);
995    }
996    return 1;
997}
998

Here is the output of strace -c for just over 5,000 packets sent:

1#include &lt;sys/types.h&gt;
2#include &lt;sys/socket.h&gt;
3#include &lt;arpa/inet.h&gt;
4#include &lt;linux/if_packet.h&gt;
5#include &lt;net/ethernet.h&gt;
6#include &lt;stdlib.h&gt;
7#include &lt;stdio.h&gt;
8#include &lt;errno.h&gt;
9#include &lt;string.h&gt;
10#include &lt;sys/mman.h&gt;
11#include &lt;unistd.h&gt;
12#include &lt;sys/ioctl.h&gt;
13#include &lt;net/if.h&gt;
14#include &lt;netinet/tcp.h&gt;    //Provides declarations for tcp header
15#include &lt;netinet/ip.h&gt; //Provides declarations for ip header
16#include &lt;netinet/ether.h&gt;
17#include &lt;ifaddrs.h&gt;
18#include &lt;asm/types.h&gt;
19#include &lt;linux/if_ether.h&gt;
20//#include &lt;linux/if_arp.h&gt;
21#include &lt;arpa/inet.h&gt;  //htons etc
22#include &lt;time.h&gt;
23#include &lt;linux/rtnetlink.h&gt;
24#include &lt;sys/resource.h&gt;
25
26#define PROTO_ARP 0x0806
27#define ETH2_HEADER_LEN 14
28#define HW_TYPE 1
29#define MAC_LENGTH 6
30#define IPV4_LENGTH 4
31#define ARP_REQUEST 0x01
32#define ARP_REPLY 0x02
33#define BUF_SIZE 60
34#define MAX_CONNECTIONS 10000
35
36#define debug(x...) printf(x);printf(&quot;\n&quot;);
37#define info(x...) printf(x);printf(&quot;\n&quot;);
38#define warn(x...) printf(x);printf(&quot;\n&quot;);
39#define err(x...) printf(x);printf(&quot;\n&quot;);
40
41static char * str_devname= NULL;
42static int mode_loss     = 0;
43static int c_packet_sz   = 150;
44static int c_buffer_sz   = 1024*8;
45static int c_buffer_nb   = 1024;
46static int c_sndbuf_sz   = 0;
47static int c_send_mask   = 127;
48static int c_error       = 0;
49static int c_mtu         = 0;
50static int mode_thread   = 0;
51
52volatile int fd_socket;
53volatile int data_offset = 0;
54volatile struct tpacket_hdr * ps_header_start;
55volatile struct sockaddr_ll *ps_sockaddr = NULL;
56volatile int shutdown_flag = 0;
57int done = 0;
58struct tpacket_req s_packet_req;
59unsigned char buffer[BUF_SIZE];
60struct arp_header *arp_resp = (struct arp_header *) (buffer + ETH2_HEADER_LEN);
61char ifname[512];
62char ip[512];
63
64/* 
65    96 bit (12 bytes) pseudo header needed for tcp header checksum calculation 
66*/
67struct pseudo_header
68{
69    u_int32_t source_address;
70    u_int32_t dest_address;
71    u_int8_t placeholder;
72    u_int8_t protocol;
73    u_int16_t tcp_length;
74};
75
76
77struct arp_header {
78    unsigned short hardware_type;
79    unsigned short protocol_type;
80    unsigned char hardware_len;
81    unsigned char protocol_len;
82    unsigned short opcode;
83    unsigned char sender_mac[MAC_LENGTH];
84    unsigned char sender_ip[IPV4_LENGTH];
85    unsigned char target_mac[MAC_LENGTH];
86    unsigned char target_ip[IPV4_LENGTH];
87};
88
89int rtnl_receive(int fd, struct msghdr *msg, int flags)
90{
91    int len;
92
93    do { 
94        len = recvmsg(fd, msg, flags);
95    } while (len &lt; 0 &amp;&amp; (errno == EINTR || errno == EAGAIN));
96
97    if (len &lt; 0) {
98        perror(&quot;Netlink receive failed&quot;);
99        return -errno;
100    }
101
102    if (len == 0) { 
103        perror(&quot;EOF on netlink&quot;);
104        return -ENODATA;
105    }
106
107    return len;
108}
109
110static int rtnl_recvmsg(int fd, struct msghdr *msg, char **answer)
111{
112    struct iovec *iov = msg-&gt;msg_iov;
113    char *buf;
114    int len;
115
116    iov-&gt;iov_base = NULL;
117    iov-&gt;iov_len = 0;
118
119    len = rtnl_receive(fd, msg, MSG_PEEK | MSG_TRUNC);
120
121    if (len &lt; 0) {
122        return len;
123    }
124
125    buf = malloc(len);
126
127    if (!buf) {
128        perror(&quot;malloc failed&quot;);
129        return -ENOMEM;
130    }
131
132    iov-&gt;iov_base = buf;
133    iov-&gt;iov_len = len;
134
135    len = rtnl_receive(fd, msg, 0);
136
137    if (len &lt; 0) {
138        free(buf);
139        return len;
140    }
141
142    *answer = buf;
143
144    return len;
145}
146
147void parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len)
148{
149    memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
150
151    while (RTA_OK(rta, len)) {
152        if (rta-&gt;rta_type &lt;= max) {
153            tb[rta-&gt;rta_type] = rta;
154        }
155
156        rta = RTA_NEXT(rta,len);
157    }
158}
159
160static inline int rtm_get_table(struct rtmsg *r, struct rtattr **tb)
161{
162    __u32 table = r-&gt;rtm_table;
163
164    if (tb[RTA_TABLE]) {
165        table = *(__u32 *)RTA_DATA(tb[RTA_TABLE]);
166    }
167
168    return table;
169}
170
171void print_route(struct nlmsghdr* nl_header_answer)
172{
173    struct rtmsg* r = NLMSG_DATA(nl_header_answer);
174    int len = nl_header_answer-&gt;nlmsg_len;
175    struct rtattr* tb[RTA_MAX+1];
176    int table;
177    char buf[256];
178
179    len -= NLMSG_LENGTH(sizeof(*r));
180
181    if (len &lt; 0) {
182        perror(&quot;Wrong message length&quot;);
183        return;
184    }
185    
186    parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
187
188    table = rtm_get_table(r, tb);
189
190    if (r-&gt;rtm_family != AF_INET &amp;&amp; table != RT_TABLE_MAIN) {
191        return;
192    }
193
194    if (tb[RTA_DST]) {
195        if ((r-&gt;rtm_dst_len != 24) &amp;&amp; (r-&gt;rtm_dst_len != 16)) {
196            return;
197        }
198
199        printf(&quot;%s/%u &quot;, inet_ntop(r-&gt;rtm_family, RTA_DATA(tb[RTA_DST]), buf, sizeof(buf)), r-&gt;rtm_dst_len);
200
201    } else if (r-&gt;rtm_dst_len) {
202        printf(&quot;0/%u &quot;, r-&gt;rtm_dst_len);
203    } else {
204        printf(&quot;default &quot;);
205    }
206
207    if (tb[RTA_GATEWAY]) {
208        printf(&quot;via %s&quot;, inet_ntop(r-&gt;rtm_family, RTA_DATA(tb[RTA_GATEWAY]), buf, sizeof(buf)));
209        strcpy(ip, inet_ntop(r-&gt;rtm_family, RTA_DATA(tb[RTA_GATEWAY]), buf, sizeof(buf)));
210    }
211
212    if (tb[RTA_OIF]) {
213        char if_nam_buf[IF_NAMESIZE];
214        int ifidx = *(__u32 *)RTA_DATA(tb[RTA_OIF]);
215
216        printf(&quot; dev %s&quot;, if_indextoname(ifidx, if_nam_buf));
217    }
218
219    if (tb[RTA_GATEWAY] &amp;&amp; tb[RTA_OIF]) {
220        char if_nam_buf[IF_NAMESIZE];
221        int ifidx = *(__u32 *)RTA_DATA(tb[RTA_OIF]);
222
223        strcpy(ifname, if_indextoname(ifidx, if_nam_buf));
224    }
225
226    if (tb[RTA_SRC]) {
227        printf(&quot;src %s&quot;, inet_ntop(r-&gt;rtm_family, RTA_DATA(tb[RTA_SRC]), buf, sizeof(buf)));
228    }
229
230    printf(&quot;\n&quot;);
231}
232
233int open_netlink()
234{
235    struct sockaddr_nl saddr;
236
237    int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
238
239    if (sock &lt; 0) {
240        perror(&quot;Failed to open netlink socket&quot;);
241        return -1;
242    }
243
244    memset(&amp;saddr, 0, sizeof(saddr));
245
246    saddr.nl_family = AF_NETLINK;
247    saddr.nl_pid = getpid();
248
249    if (bind(sock, (struct sockaddr *)&amp;saddr, sizeof(saddr)) &lt; 0) {
250        perror(&quot;Failed to bind to netlink socket&quot;);
251        close(sock);
252        return -1;
253    }
254
255    return sock;
256}
257
258int do_route_dump_requst(int sock)
259{
260    struct {
261        struct nlmsghdr nlh;
262        struct rtmsg rtm;
263    } nl_request;
264
265    nl_request.nlh.nlmsg_type = RTM_GETROUTE;
266    nl_request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
267    nl_request.nlh.nlmsg_len = sizeof(nl_request);
268    nl_request.nlh.nlmsg_seq = time(NULL);
269    nl_request.rtm.rtm_family = AF_INET;
270
271    return send(sock, &amp;nl_request, sizeof(nl_request), 0);
272}
273
274int get_route_dump_response(int sock)
275{
276    struct sockaddr_nl nladdr;
277    struct iovec iov;
278    struct msghdr msg = {
279        .msg_name = &amp;nladdr,
280        .msg_namelen = sizeof(nladdr),
281        .msg_iov = &amp;iov,
282        .msg_iovlen = 1,
283    };
284
285    char *buf;
286    int dump_intr = 0;
287
288    int status = rtnl_recvmsg(sock, &amp;msg, &amp;buf);
289
290    struct nlmsghdr *h = (struct nlmsghdr *)buf;
291    int msglen = status;
292
293    printf(&quot;Main routing table IPv4\n&quot;);
294
295    while (NLMSG_OK(h, msglen)) {
296        if (h-&gt;nlmsg_flags &amp; NLM_F_DUMP_INTR) {
297            fprintf(stderr, &quot;Dump was interrupted\n&quot;);
298            free(buf);
299            return -1;
300        }
301
302        if (nladdr.nl_pid != 0) {
303            continue;
304        }
305
306        if (h-&gt;nlmsg_type == NLMSG_ERROR) {
307            perror(&quot;netlink reported error&quot;);
308            free(buf);
309        }
310
311        print_route(h);
312
313        h = NLMSG_NEXT(h, msglen);
314    }
315
316    free(buf);
317
318    return status;
319}
320
321
322/*
323 * Converts struct sockaddr with an IPv4 address to network byte order uin32_t.
324 * Returns 0 on success.
325 */
326int int_ip4(struct sockaddr *addr, uint32_t *ip)
327{
328    if (addr-&gt;sa_family == AF_INET) {
329        struct sockaddr_in *i = (struct sockaddr_in *) addr;
330        *ip = i-&gt;sin_addr.s_addr;
331        return 0;
332    } else {
333        err(&quot;Not AF_INET&quot;);
334        return 1;
335    }
336}
337
338/*
339 * Formats sockaddr containing IPv4 address as human readable string.
340 * Returns 0 on success.
341 */
342int format_ip4(struct sockaddr *addr, char *out)
343{
344    if (addr-&gt;sa_family == AF_INET) {
345        struct sockaddr_in *i = (struct sockaddr_in *) addr;
346        const char *ip = inet_ntoa(i-&gt;sin_addr);
347        if (!ip) {
348            return -2;
349        } else {
350            strcpy(out, ip);
351            return 0;
352        }
353    } else {
354        return -1;
355    }
356}
357
358/*
359 * Writes interface IPv4 address as network byte order to ip.
360 * Returns 0 on success.
361 */
362int get_if_ip4(int fd, const char *ifname, uint32_t *ip) {
363    int err = -1;
364    struct ifreq ifr;
365    memset(&amp;ifr, 0, sizeof(struct ifreq));
366    if (strlen(ifname) &gt; (IFNAMSIZ - 1)) {
367        err(&quot;Too long interface name&quot;);
368        goto out;
369    }
370
371    strcpy(ifr.ifr_name, ifname);
372    if (ioctl(fd, SIOCGIFADDR, &amp;ifr) == -1) {
373        perror(&quot;SIOCGIFADDR&quot;);
374        goto out;
375    }
376
377    if (int_ip4(&amp;ifr.ifr_addr, ip)) {
378        goto out;
379    }
380    err = 0;
381out:
382    return err;
383}
384
385/*
386 * Sends an ARP who-has request to dst_ip
387 * on interface ifindex, using source mac src_mac and source ip src_ip.
388 */
389int send_arp(int fd, int ifindex, const unsigned char *src_mac, uint32_t src_ip, uint32_t dst_ip)
390{
391    int err = -1;
392    unsigned char buffer[BUF_SIZE];
393    memset(buffer, 0, sizeof(buffer));
394
395    struct sockaddr_ll socket_address;
396    socket_address.sll_family = AF_PACKET;
397    socket_address.sll_protocol = htons(ETH_P_ARP);
398    socket_address.sll_ifindex = ifindex;
399    socket_address.sll_hatype = htons(ARPHRD_ETHER);
400    socket_address.sll_pkttype = (PACKET_BROADCAST);
401    socket_address.sll_halen = MAC_LENGTH;
402    socket_address.sll_addr[6] = 0x00;
403    socket_address.sll_addr[7] = 0x00;
404
405    struct ethhdr *send_req = (struct ethhdr *) buffer;
406    struct arp_header *arp_req = (struct arp_header *) (buffer + ETH2_HEADER_LEN);
407    int index;
408    ssize_t ret, length = 0;
409
410    //Broadcast
411    memset(send_req-&gt;h_dest, 0xff, MAC_LENGTH);
412
413    //Target MAC zero
414    memset(arp_req-&gt;target_mac, 0x00, MAC_LENGTH);
415
416    //Set source mac to our MAC address
417    memcpy(send_req-&gt;h_source, src_mac, MAC_LENGTH);
418    memcpy(arp_req-&gt;sender_mac, src_mac, MAC_LENGTH);
419    memcpy(socket_address.sll_addr, src_mac, MAC_LENGTH);
420
421    /* Setting protocol of the packet */
422    send_req-&gt;h_proto = htons(ETH_P_ARP);
423
424    /* Creating ARP request */
425    arp_req-&gt;hardware_type = htons(HW_TYPE);
426    arp_req-&gt;protocol_type = htons(ETH_P_IP);
427    arp_req-&gt;hardware_len = MAC_LENGTH;
428    arp_req-&gt;protocol_len = IPV4_LENGTH;
429    arp_req-&gt;opcode = htons(ARP_REQUEST);
430
431    debug(&quot;Copy IP address to arp_req&quot;);
432    memcpy(arp_req-&gt;sender_ip, &amp;src_ip, sizeof(uint32_t));
433    memcpy(arp_req-&gt;target_ip, &amp;dst_ip, sizeof(uint32_t));
434
435    ret = sendto(fd, buffer, 42, 0, (struct sockaddr *) &amp;socket_address, sizeof(socket_address));
436    if (ret == -1) {
437        perror(&quot;sendto():&quot;);
438        goto out;
439    }
440    err = 0;
441out:
442    return err;
443}
444
445/*
446 * Gets interface information by name:
447 * IPv4
448 * MAC
449 * ifindex
450 */
451int get_if_info(const char *ifname, uint32_t *ip, char *mac, int *ifindex)
452{
453    debug(&quot;get_if_info for %s&quot;, ifname);
454    int err = -1;
455    struct ifreq ifr;
456    int sd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ARP));
457    if (sd &lt;= 0) {
458        perror(&quot;socket()&quot;);
459        goto out;
460    }
461    if (strlen(ifname) &gt; (IFNAMSIZ - 1)) {
462        printf(&quot;Too long interface name, MAX=%i\n&quot;, IFNAMSIZ - 1);
463        goto out;
464    }
465
466    strcpy(ifr.ifr_name, ifname);
467
468    //Get interface index using name
469    if (ioctl(sd, SIOCGIFINDEX, &amp;ifr) == -1) {
470        perror(&quot;SIOCGIFINDEX&quot;);
471        goto out;
472    }
473    *ifindex = ifr.ifr_ifindex;
474    printf(&quot;interface index is %d\n&quot;, *ifindex);
475
476    //Get MAC address of the interface
477    if (ioctl(sd, SIOCGIFHWADDR, &amp;ifr) == -1) {
478        perror(&quot;SIOCGIFINDEX&quot;);
479        goto out;
480    }
481
482    //Copy mac address to output
483    memcpy(mac, ifr.ifr_hwaddr.sa_data, MAC_LENGTH);
484
485    if (get_if_ip4(sd, ifname, ip)) {
486        goto out;
487    }
488    debug(&quot;get_if_info OK&quot;);
489
490    err = 0;
491out:
492    if (sd &gt; 0) {
493        debug(&quot;Clean up temporary socket&quot;);
494        close(sd);
495    }
496    return err;
497}
498
499/*
500 * Creates a raw socket that listens for ARP traffic on specific ifindex.
501 * Writes out the socket's FD.
502 * Return 0 on success.
503 */
504int bind_arp(int ifindex, int *fd)
505{
506    debug(&quot;bind_arp: ifindex=%i&quot;, ifindex);
507    int ret = -1;
508
509    // Submit request for a raw socket descriptor.
510    *fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ARP));
511    if (*fd &lt; 1) {
512        perror(&quot;socket()&quot;);
513        goto out;
514    }
515
516    debug(&quot;Binding to ifindex %i&quot;, ifindex);
517    struct sockaddr_ll sll;
518    memset(&amp;sll, 0, sizeof(struct sockaddr_ll));
519    sll.sll_family = AF_PACKET;
520    sll.sll_ifindex = ifindex;
521    if (bind(*fd, (struct sockaddr*) &amp;sll, sizeof(struct sockaddr_ll)) &lt; 0) {
522        perror(&quot;bind&quot;);
523        goto out;
524    }
525
526    ret = 0;
527out:
528    if (ret &amp;&amp; *fd &gt; 0) {
529        debug(&quot;Cleanup socket&quot;);
530        close(*fd);
531    }
532    return ret;
533}
534
535/*
536 * Reads a single ARP reply from fd.
537 * Return 0 on success.
538 */
539int read_arp(int fd)
540{
541    debug(&quot;read_arp&quot;);
542    int ret = -1;
543    ssize_t length = recvfrom(fd, buffer, BUF_SIZE, 0, NULL, NULL);
544    int index;
545    if (length == -1) {
546        perror(&quot;recvfrom()&quot;);
547        goto out;
548    }
549    struct ethhdr *rcv_resp = (struct ethhdr *) buffer;
550    if (ntohs(rcv_resp-&gt;h_proto) != PROTO_ARP) {
551        debug(&quot;Not an ARP packet&quot;);
552        goto out;
553    }
554    if (ntohs(arp_resp-&gt;opcode) != ARP_REPLY) {
555        debug(&quot;Not an ARP reply&quot;);
556        goto out;
557    }
558    debug(&quot;received ARP len=%ld&quot;, length);
559    struct in_addr sender_a;
560    memset(&amp;sender_a, 0, sizeof(struct in_addr));
561    memcpy(&amp;sender_a.s_addr, arp_resp-&gt;sender_ip, sizeof(uint32_t));
562    debug(&quot;Sender IP: %s&quot;, inet_ntoa(sender_a));
563
564    debug(&quot;Sender MAC: %02X:%02X:%02X:%02X:%02X:%02X&quot;,
565          arp_resp-&gt;sender_mac[0],
566          arp_resp-&gt;sender_mac[1],
567          arp_resp-&gt;sender_mac[2],
568          arp_resp-&gt;sender_mac[3],
569          arp_resp-&gt;sender_mac[4],
570          arp_resp-&gt;sender_mac[5]);
571
572    ret = 0;
573
574out:
575    return ret;
576}
577
578/*
579 *
580 * Sample code that sends an ARP who-has request on
581 * interface &lt;ifname&gt; to IPv4 address &lt;ip&gt;.
582 * Returns 0 on success.
583 */
584int test_arping(const char *ifname, const char *ip) {
585    int ret = -1;
586    uint32_t dst = inet_addr(ip);
587    if (dst == 0 || dst == 0xffffffff) {
588        printf(&quot;Invalid source IP\n&quot;);
589        return 1;
590    }
591
592    int src;
593    int ifindex;
594    char mac[MAC_LENGTH];
595    if (get_if_info(ifname, &amp;src, mac, &amp;ifindex)) {
596        err(&quot;get_if_info failed, interface %s not found or no IP set?&quot;, ifname);
597        goto out;
598    }
599    int arp_fd;
600    if (bind_arp(ifindex, &amp;arp_fd)) {
601        err(&quot;Failed to bind_arp()&quot;);
602        goto out;
603    }
604
605    if (send_arp(arp_fd, ifindex, mac, src, dst)) {
606        err(&quot;Failed to send_arp&quot;);
607        goto out;
608    }
609
610    while(1) {
611        int r = read_arp(arp_fd);
612        if (r == 0) {
613            info(&quot;Got reply, break out&quot;);
614            break;
615        }
616    }
617
618    ret = 0;
619out:
620    if (arp_fd) {
621        close(arp_fd);
622        arp_fd = 0;
623    }
624    return ret;
625}
626
627unsigned short checksum2(const char *buf, unsigned size)
628{
629    unsigned long long sum = 0;
630    const unsigned long long *b = (unsigned long long *) buf;
631
632    unsigned t1, t2;
633    unsigned short t3, t4;
634
635    /* Main loop - 8 bytes at a time */
636    while (size &gt;= sizeof(unsigned long long))
637    {
638        unsigned long long s = *b++;
639        sum += s;
640        if (sum &lt; s) sum++;
641        size -= 8;
642    }
643
644    /* Handle tail less than 8-bytes long */
645    buf = (const char *) b;
646    if (size &amp; 4)
647    {
648        unsigned s = *(unsigned *)buf;
649        sum += s;
650        if (sum &lt; s) sum++;
651        buf += 4;
652    }
653
654    if (size &amp; 2)
655    {
656        unsigned short s = *(unsigned short *) buf;
657        sum += s;
658        if (sum &lt; s) sum++;
659        buf += 2;
660    }
661
662    if (size)
663    {
664        unsigned char s = *(unsigned char *) buf;
665        sum += s;
666        if (sum &lt; s) sum++;
667    }
668
669    /* Fold down to 16 bits */
670    t1 = sum;
671    t2 = sum &gt;&gt; 32;
672    t1 += t2;
673    if (t1 &lt; t2) t1++;
674    t3 = t1;
675    t4 = t1 &gt;&gt; 16;
676    t3 += t4;
677    if (t3 &lt; t4) t3++;
678
679    return ~t3;
680}
681
682int main( int argc, char ** argv )
683{
684    uint32_t size;
685    size_t len;
686    struct sockaddr_ll my_addr, peer_addr;
687    int i_ifindex;
688    int ec;
689    struct ifreq s_ifr; /* points to one interface returned from ioctl */
690    int tmp;
691    FILE * fp;
692    char server[254];
693    int count = 0;
694    int first_time = 1;
695    int z;
696    int first_mmap = 1;
697    
698    #define HWADDR_len 6
699    #define IP_len 4
700    int s,s2,i;
701    struct ifreq ifr,ifr2;
702    int ret = -1;
703    struct rlimit lim;
704    
705    if (argc != 2) {
706        printf(&quot;Usage: %s &lt;INPUT_FILE&gt;\n&quot;, argv[0]);
707        return 1;
708    }
709
710    getrlimit(RLIMIT_NOFILE, &amp;lim);
711    printf(&quot;Soft: %d Hard: %d\n&quot;, (int)lim.rlim_cur, (int)lim.rlim_max);
712    lim.rlim_cur = lim.rlim_max;
713    
714    
715    if (setrlimit(RLIMIT_NOFILE, &amp;lim) == -1) {
716        printf(&quot;rlimit failed\n&quot;);
717        return -1;
718    }
719    getrlimit(RLIMIT_NOFILE, &amp;lim);
720    printf(&quot;New Soft: %d New Hard: %d\n&quot;, (int)lim.rlim_cur, (int)lim.rlim_max);
721    
722    int nl_sock = open_netlink();
723
724    if (do_route_dump_requst(nl_sock) &lt; 0) {
725        perror(&quot;Failed to perfom request&quot;);
726        close(nl_sock);
727        return -1;
728    }
729
730    get_route_dump_response(nl_sock);
731
732    close (nl_sock);
733    
734    test_arping(ifname, ip);
735
736    
737    s = socket(AF_INET, SOCK_DGRAM, 0);
738    s2 = socket(AF_INET, SOCK_DGRAM, 0);
739    strcpy(ifr.ifr_name, ifname);
740    strcpy(ifr2.ifr_name, ifname);
741    ioctl(s, SIOCGIFHWADDR, &amp;ifr);
742    ioctl(s2, SIOCGIFADDR, &amp;ifr2);
743    struct sockaddr_in* ipaddr = (struct sockaddr_in*)&amp;ifr2.ifr_addr;
744    close(s);
745
746    fp = fopen(argv[1], &quot;r&quot;);
747    if (!fp)
748        exit(EXIT_FAILURE);
749
750
751    while (!done)
752    {   
753        fd_socket = socket(PF_PACKET, SOCK_RAW|SOCK_NONBLOCK, htons(ETH_P_ALL));
754        if(fd_socket == -1)
755        {
756            perror(&quot;socket&quot;);
757            return EXIT_FAILURE;
758        }
759    
760        /* clear structure */
761        memset(&amp;my_addr, 0, sizeof(struct sockaddr_ll));
762        my_addr.sll_family = PF_PACKET;
763        my_addr.sll_protocol = htons(ETH_P_ALL);
764    
765        str_devname = ifname;
766        //strcpy (str_devname, ifname);
767        
768        /* initialize interface struct */
769        strncpy (s_ifr.ifr_name, str_devname, sizeof(s_ifr.ifr_name));
770    
771        /* Get the broad cast address */
772        ec = ioctl(fd_socket, SIOCGIFINDEX, &amp;s_ifr);
773        if(ec == -1)
774        {
775            perror(&quot;iotcl&quot;);
776            return EXIT_FAILURE;
777        }
778    
779        /* update with interface index */
780        i_ifindex = s_ifr.ifr_ifindex;
781    
782        s_ifr.ifr_mtu = 7200;
783        /* update the mtu through ioctl */
784        ec = ioctl(fd_socket, SIOCSIFMTU, &amp;s_ifr);
785        if(ec == -1)
786        {
787            perror(&quot;iotcl&quot;);
788            return EXIT_FAILURE;
789        }
790    
791        /* set sockaddr info */
792        memset(&amp;my_addr, 0, sizeof(struct sockaddr_ll));
793        my_addr.sll_family = AF_PACKET;
794        my_addr.sll_protocol = ETH_P_ALL;
795        my_addr.sll_ifindex = i_ifindex;
796    
797        /* bind port */
798        if (bind(fd_socket, (struct sockaddr *)&amp;my_addr, sizeof(struct sockaddr_ll)) == -1)
799        {
800            perror(&quot;bind&quot;);
801            return EXIT_FAILURE;
802        }
803    
804        /* prepare Tx ring request */
805        s_packet_req.tp_block_size = c_buffer_sz;
806        s_packet_req.tp_frame_size = c_buffer_sz;
807        s_packet_req.tp_block_nr = c_buffer_nb;
808        s_packet_req.tp_frame_nr = c_buffer_nb;
809    
810        /* calculate memory to mmap in the kernel */
811        size = s_packet_req.tp_block_size * s_packet_req.tp_block_nr;
812    
813        /* set packet loss option */
814        tmp = mode_loss;
815        if (setsockopt(fd_socket, SOL_PACKET, PACKET_LOSS, (char *)&amp;tmp, sizeof(tmp))&lt;0)
816        {
817            perror(&quot;setsockopt: PACKET_LOSS&quot;);
818            return EXIT_FAILURE;
819        }
820        
821        /* send TX ring request */
822        if (setsockopt(fd_socket, SOL_PACKET, PACKET_TX_RING, (char *)&amp;s_packet_req, sizeof(s_packet_req))&lt;0)
823        {
824            perror(&quot;setsockopt: PACKET_TX_RING&quot;);
825            return EXIT_FAILURE;
826        }
827    
828        /* change send buffer size */
829        if(c_sndbuf_sz) {
830            printf(&quot;send buff size = %d\n&quot;, c_sndbuf_sz);
831            if (setsockopt(fd_socket, SOL_SOCKET, SO_SNDBUF, &amp;c_sndbuf_sz, sizeof(c_sndbuf_sz))&lt; 0)
832            {
833                perror(&quot;getsockopt: SO_SNDBUF&quot;);
834                return EXIT_FAILURE;
835            }
836        }
837    
838        /* get data offset */
839        data_offset = TPACKET_HDRLEN - sizeof(struct sockaddr_ll);
840    
841        /* mmap Tx ring buffers memory */
842        ps_header_start = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd_socket, 0);
843        if (ps_header_start == (void*)-1)
844        {
845            perror(&quot;mmap&quot;);
846            return EXIT_FAILURE;
847        }
848    
849    
850        int i,j;
851        int i_index = 0;
852        char * data;
853        int first_loop = 1;
854        struct tpacket_hdr * ps_header;
855        int ec_send = 0;
856 
857        int i_index_start = i_index;
858        
859        ps_header = ((struct tpacket_hdr *)((void *)ps_header_start + (c_buffer_sz*i_index)));
860        data = ((void*) ps_header) + data_offset;
861        //Datagram to represent the packet
862        char datagram[4096] , source_ip[32] , *pseudogram;
863    
864        //zero out the packet buffer
865        memset (datagram, 0, 4096);
866    
867        //Ethernet header
868        struct ether_header *eh = (struct ether_header *) datagram;
869        
870        //IP header
871        struct iphdr *iph = (struct iphdr *) (datagram + sizeof (struct ether_header));
872    
873        //TCP header
874        struct tcphdr *tcph = (struct tcphdr *) (datagram + sizeof (struct ether_header) + sizeof (struct ip));
875        struct sockaddr_in sin;
876        struct pseudo_header psh;
877    
878        //some address resolution
879        strcpy(source_ip , inet_ntoa(ipaddr-&gt;sin_addr));
880        sin.sin_family = AF_INET;
881        sin.sin_port = htons(80);
882        if (fscanf(fp, &quot;%253s&quot;, server) == 1)
883            sin.sin_addr.s_addr = inet_addr (server);   
884        else
885        {
886            done = 1;
887            break;
888        }
889                        
890        //Fill in the Ethernet Header
891        eh-&gt;ether_dhost[0] = arp_resp-&gt;sender_mac[0];
892        eh-&gt;ether_dhost[1] = arp_resp-&gt;sender_mac[1];
893        eh-&gt;ether_dhost[2] = arp_resp-&gt;sender_mac[2];
894        eh-&gt;ether_dhost[3] = arp_resp-&gt;sender_mac[3];
895        eh-&gt;ether_dhost[4] = arp_resp-&gt;sender_mac[4];
896        eh-&gt;ether_dhost[5] = arp_resp-&gt;sender_mac[5];
897
898        memcpy(eh-&gt;ether_shost, ifr.ifr_hwaddr.sa_data, HWADDR_len);
899        eh-&gt;ether_type = htons(0x0800);
900                        
901        //Fill in the IP Header
902        iph-&gt;ihl = 5;
903        iph-&gt;version = 4;
904        iph-&gt;tos = 0;
905        iph-&gt;tot_len = htons(sizeof (struct iphdr) + sizeof (struct tcphdr));
906        iph-&gt;id = htons (54321);    //Id of this packet
907        iph-&gt;frag_off = 0;
908        iph-&gt;ttl = 255;
909        iph-&gt;protocol = IPPROTO_TCP;
910        iph-&gt;check = 0;     //Set to 0 before calculating checksum
911        iph-&gt;saddr = inet_addr ( source_ip );
912        iph-&gt;daddr = sin.sin_addr.s_addr;
913    
914        //Ip checksum
915        iph-&gt;check = checksum2 (datagram + sizeof (struct ether_header), sizeof (struct iphdr));
916    
917        //TCP Header
918        tcph-&gt;source = htons (1234);
919        tcph-&gt;dest = htons (80);
920        tcph-&gt;seq = 0;
921        tcph-&gt;ack_seq = 0;
922        tcph-&gt;doff = 5; //tcp header size
923        tcph-&gt;fin=0;
924        tcph-&gt;syn=1;
925        tcph-&gt;rst=0;
926        tcph-&gt;psh=0;
927        tcph-&gt;ack=0;
928        tcph-&gt;urg=0;
929        tcph-&gt;window = htons (5840);    // maximum allowed window size 
930        tcph-&gt;check = 0;    //leave checksum 0 now, filled later by pseudo header
931        tcph-&gt;urg_ptr = 0;
932
933        //Now the TCP checksum
934        psh.source_address = inet_addr( source_ip );
935        psh.dest_address = sin.sin_addr.s_addr;
936        psh.placeholder = 0;
937        psh.protocol = IPPROTO_TCP;
938        psh.tcp_length = htons(sizeof(struct tcphdr));
939    
940        int psize = sizeof(struct pseudo_header) + sizeof(struct tcphdr);
941        pseudogram = malloc(psize);
942    
943        memcpy(pseudogram , (char*) &amp;psh , sizeof (struct pseudo_header));
944        memcpy(pseudogram + sizeof(struct pseudo_header) , tcph , sizeof(struct tcphdr));
945    
946        tcph-&gt;check = checksum2(pseudogram , psize);
947                        
948        memcpy(data, datagram, (sizeof(struct ether_header) + sizeof(struct iphdr) + sizeof(struct tcphdr)));
949        free(pseudogram);
950        len = sizeof(struct ether_header) + sizeof(struct iphdr) + sizeof(struct tcphdr);
951        
952        i_index ++;
953        if(i_index &gt;= c_buffer_nb)
954        {
955            i_index = 0;
956            first_loop = 0;
957        }
958 
959        /* update packet len */
960        //ps_header-&gt;tp_len = c_packet_sz;
961        ps_header-&gt;tp_len = len;
962        /* set header flag to USER (trigs xmit)*/
963        ps_header-&gt;tp_status = TP_STATUS_SEND_REQUEST;
964        
965        //int ec_send;
966        static int total=0;
967        //int blocking = 1;
968        
969        /* send all buffers with TP_STATUS_SEND_REQUEST */
970        /* Wait end of transfer */
971        //ec_send = sendto(fd_socket,NULL,0,(blocking? 0 : MSG_DONTWAIT),(struct sockaddr *) ps_sockaddr,sizeof(struct sockaddr_ll));
972        ec_send = sendto(fd_socket,NULL,len,MSG_DONTWAIT,(struct sockaddr *) ps_sockaddr,sizeof(struct sockaddr_ll));
973        
974        if(ec_send &lt; 0) {
975            perror(&quot;sendto&quot;);
976        }
977        else if ( ec_send == 0 ) {
978            /* nothing to do =&gt; schedule : useful if no SMP */
979            printf(&quot;Sleeping\n&quot;);
980            usleep(0);
981        }
982        else {
983            total += ec_send/(len);
984            printf(&quot;send %d packets (+%d bytes)\n&quot;,total, ec_send);
985            fflush(0);
986        }
987        //ps_header_start = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd_socket, 0);
988        if (munmap(ps_header_start, size) == -1)
989        {
990            perror(&quot;munmap&quot;);
991            exit(EXIT_FAILURE);
992        }       
993    
994        close(fd_socket);
995    }
996    return 1;
997}
998% time     seconds  usecs/call     calls    errors syscall
999------ ----------- ----------- --------- --------- ----------------
1000 48.11    3.962165         395     10012           setsockopt
1001 16.69    1.374748         274      5014           mmap
1002 14.85    1.222565         244      5007           munmap
1003 10.91    0.898695         179      5016           close
1004  3.15    0.259055          25     10022           ioctl
1005  2.04    0.167613          33      5016           socket
1006  1.70    0.139623          27      5008           sendto
1007  1.41    0.116430          23      5025           write
1008  1.14    0.093826          18      5008           bind
1009  0.01    0.000505          26        19           read
1010  0.00    0.000000           0         4           mprotect
1011  0.00    0.000000           0         3           brk
1012  0.00    0.000000           0         4           pread64
1013  0.00    0.000000           0         3         1 access
1014  0.00    0.000000           0         1           getpid
1015  0.00    0.000000           0         1           recvfrom
1016  0.00    0.000000           0         2           recvmsg
1017  0.00    0.000000           0         1           execve
1018  0.00    0.000000           0         2         1 arch_prctl
1019  0.00    0.000000           0         1           set_tid_address
1020  0.00    0.000000           0         3           openat
1021  0.00    0.000000           0         4           newfstatat
1022  0.00    0.000000           0         1           set_robust_list
1023  0.00    0.000000           0         4           prlimit64
1024  0.00    0.000000           0         1           getrandom
1025------ ----------- ----------- --------- --------- ----------------
1026100.00    8.235225         149     55182         2 total
1027

ANSWER

Answered 2022-Jan-11 at 20:59

If I follow the code correctly, you're redoing a ton of work for every IP address that doesn't need to be redone. Every time through the main loop you're:

  • creating a new packet socket
  • binding it
  • setting up a tx packet ring buffer
  • mmap'ing it
  • sending a single packet
  • unmapping
  • closing the socket

That's a huge amount of work you're causing the system to do for one packet.

You should only create one packet socket at the beginning, set up the tx buffer and mmap once, and leave it open until the program is done. You can send any number of packets through the interface without closing/re-opening.

This is why your top time users are setsockopt, mmap, unmap, etc. All of those operations are heavy in the kernel.

Also, the point of PACKET_TX_RING is that you can set up a large buffer and create one packet after another within the buffer without making a send system call for each packet. By using the packet header's tp_status field you're telling the kernel that this frame is ready to be sent. You then advance your pointer within the ring buffer to the next available slot and build another packet. When you have no more packets to build (or you've filled the available space in the buffer [i.e. wrapped around to your oldest still-in-flight frame]), you can then make one send/sendto call to tell the kernel to go look at your buffer and (start) sending all those packets.

You can then start building more packets (being careful to ensure they are not still in use by the kernel -- through the tp_status field).

That said, if this were a project I were doing, I would simplify a lot - at least for the first pass: create a packet socket, bind it to the interface, build packets one at a time, and use send once per frame (i.e. not bothering with PACKET_TX_RING). If (and only if) performance requirements are so tight that it needs to send faster would I bother setting up and using the ring buffer. I doubt you'll need that. This should go a ton faster without the excess setsockopt and mmap calls.

Finally, a non-blocking socket is only useful if you have something else to do while you're waiting. In this case, if you have the socket set to be non-blocking and the packet can't be sent because the call would block, the send call will fail and if you don't do something about that (enqueue the packet somewhere, and retry later, say), the packet will be lost. In this program, I can't see any benefit whatsoever to using a non-blocking socket. If the socket blocks, it's because the device transmit queue is full. After that, there's no point in you continuing to produce packets to be sent, you won't be able send those packets either. Much simpler to just block at that point until the queue drains.

Source https://stackoverflow.com/questions/70644332

Community Discussions contain sources that include Stack Exchange Network

Tutorials and Learning Resources in Web Servers

Tutorials and Learning Resources are not available at this moment for Web Servers

Share this Page

share link

Get latest updates on Web Servers