1 /*-
2 * Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved.
3 *
4 * See the file EXAMPLES-LICENSE for license information.
5 *
6 */
7
8 /*
9 * Firewall Example
10 *
11 * This application shows how Oracle Berkeley DB can be used to implement a
12 * simple firewall using a queue and btree databases.
13 */
14
15 /*
16 * Destination
17 *
18 * This program handles messages that are forwarded by the Firewall.
19 * After every 10,000 messages handled it prints out a message
20 * stating how long it took to handle those messages.
21 */
22
23 #include "firewall_common_utils.h"
24 #include "db.h"
25
26 static int
usage()27 usage()
28 {
29 (void)fprintf(stderr,
30 "usage: message_handler -d db_name -h env_home \n");
31 return (EXIT_FAILURE);
32 }
33
34 #ifdef _WIN32
35 extern int getopt(int, char * const *, const char *);
36 #endif
37
38 /*
39 * Start reading messages from the queue. After 10,000 messages are received
40 * print out how long it took to process those messages.
41 */
process_msgs(dbenv,msg_queue)42 int process_msgs(dbenv, msg_queue)
43 DB_ENV *dbenv;
44 DB *msg_queue;
45 {
46 DBT key, data;
47 #ifdef _WIN32
48 struct timeval2 end_time, start_time;
49 #else
50 struct timeval end_time, start_time;
51 #endif
52 double time_secs;
53 unsigned char msg[MSG_LEN], key_buf[KEY_LEN];
54 int count, first, msg_count, ret;
55
56 /*
57 * Configure the key and data fields to use a user defined memory
58 * buffer instead of having the database get function allocate one.
59 */
60 memset(msg, 0, MSG_LEN);
61 memset(&key, 0, sizeof(DBT));
62 memset(&data, 0, sizeof(DBT));
63 data.flags |= DB_DBT_USERMEM;
64 data.ulen = MSG_LEN;
65 data.data = msg;
66 key.flags |= DB_DBT_USERMEM;
67 key.ulen = KEY_LEN;
68 key.data = key_buf;
69 first = 1;
70 count = msg_count = 0;
71
72 while(msg_count < NUM_MESSAGES) {
73 /*
74 * Read and remove the message at the front of the queue. If
75 * there is no message wait until one arrives.
76 */
77 if ((ret = msg_queue->get(
78 msg_queue, NULL, &key, &data, DB_CONSUME_WAIT)) != 0)
79 return ret;
80
81 /* After getting the first message start the timer. */
82 if (first) {
83 (void)gettimeofday(&start_time, NULL);
84 first = 0;
85 }
86
87 /*
88 * Increment the message counter. After 10,000 messages reset
89 * the counter and print out how long it took.
90 */
91 count++;
92 msg_count++;
93 if (count == 10000) {
94 count = 0;
95 /*
96 * Calculate the time it took to process
97 * 10,000 messages.
98 */
99 (void)gettimeofday(&end_time, NULL);
100 time_secs =
101 (((double)end_time.tv_sec * NS_PER_MS +
102 end_time.tv_usec) -
103 ((double)start_time.tv_sec * NS_PER_MS +
104 start_time.tv_usec))/NS_PER_MS;
105 (void)gettimeofday(&start_time, NULL);
106 /*
107 * Print out the time it took to process
108 * 10,000 messages.
109 */
110 printf(
111 "10,000 messages processed in %f seconds.\n", time_secs);
112 }
113 }
114
115 return ret;
116 }
117
118 /* Open the message queue and start receiving messages. */
process_messages(env_home,dbname)119 int process_messages(env_home, dbname)
120 const char *env_home;
121 const char *dbname;
122 {
123 DB_ENV *dbenv;
124 DB *msg_queue;
125 int ret;
126
127 msg_queue = NULL;
128 dbenv = NULL;
129
130 /* Open the environment and message queue. */
131 if ((ret = open_env(&dbenv, env_home, 1, 1, 0)) != 0) {
132 goto err;
133 }
134 if ((ret = open_queue(dbenv, &msg_queue, dbname, 1, 1, 0)) != 0)
135 goto err;
136
137 /* Start receiving and processing messages. */
138 ret = process_msgs(dbenv, msg_queue);
139
140 err:
141 if (msg_queue != NULL)
142 (void)msg_queue->close(msg_queue, 0);
143 if (dbenv != NULL)
144 (void)dbenv->close(dbenv, 0);
145
146 return ret;
147 }
148
149 /* Receive and process messages. */
main(argc,argv)150 int main(argc, argv)
151 int argc;
152 char *argv[];
153 {
154 extern char *optarg;
155 extern int optind;
156 const char *dbname, *env_home;
157 char ch;
158
159 /*
160 * Get the name of the message queue and the path to the BDB
161 * environment.
162 */
163 while ((ch = getopt(argc, argv, "d:h:")) != EOF) {
164 switch (ch) {
165 case 'd':
166 dbname = optarg;
167 break;
168 case 'h':
169 env_home = optarg;
170 break;
171 case '?':
172 default:
173 return (usage());
174 }
175 }
176
177 return process_messages(env_home, dbname);
178 }
179