Lines Matching defs:server
23 #include "sd-dhcp-server.h"
27 #include "dhcp-server-internal.h"
36 /* configures the server's address and subnet, and optionally the pool's size and offset into the subnet
38 * moreover, the server's own address may be in the pool, and is in that case reserved in order not to
40 int sd_dhcp_server_configure_pool(sd_dhcp_server *server, struct in_addr *address, unsigned char prefixlen, uint32_t offset, uint32_t size) {
45 assert_return(server, -EINVAL);
49 assert_return(server->address == INADDR_ANY, -EBUSY);
57 /* the server address cannot be the subnet address */
80 server->bound_leases = new0(DHCPLease*, size);
81 if (!server->bound_leases)
84 server->pool_offset = offset;
85 server->pool_size = size;
87 server->address = address->s_addr;
88 server->netmask = netmask;
89 server->subnet = address->s_addr & netmask;
92 server->bound_leases[server_off - offset] = &server->invalid_lease;
97 int sd_dhcp_server_is_running(sd_dhcp_server *server) {
98 assert_return(server, false);
100 return !!server->receive_message;
103 sd_dhcp_server *sd_dhcp_server_ref(sd_dhcp_server *server) {
105 if (!server)
108 assert(server->n_ref >= 1);
109 server->n_ref++;
111 return server;
153 sd_dhcp_server *sd_dhcp_server_unref(sd_dhcp_server *server) {
156 if (!server)
159 assert(server->n_ref >= 1);
160 server->n_ref--;
162 if (server->n_ref > 0)
165 log_dhcp_server(server, "UNREF");
167 sd_dhcp_server_stop(server);
169 sd_event_unref(server->event);
171 free(server->timezone);
172 free(server->dns);
173 free(server->ntp);
175 while ((lease = hashmap_steal_first(server->leases_by_client_id)))
177 hashmap_free(server->leases_by_client_id);
179 free(server->bound_leases);
180 free(server);
186 _cleanup_(sd_dhcp_server_unrefp) sd_dhcp_server *server = NULL;
191 server = new0(sd_dhcp_server, 1);
192 if (!server)
195 server->n_ref = 1;
196 server->fd_raw = -1;
197 server->fd = -1;
198 server->address = htobe32(INADDR_ANY);
199 server->netmask = htobe32(INADDR_ANY);
200 server->ifindex = ifindex;
201 server->leases_by_client_id = hashmap_new(&client_id_hash_ops);
202 server->default_lease_time = DIV_ROUND_UP(DHCP_DEFAULT_LEASE_TIME_USEC, USEC_PER_SEC);
203 server->max_lease_time = DIV_ROUND_UP(DHCP_MAX_LEASE_TIME_USEC, USEC_PER_SEC);
205 *ret = server;
206 server = NULL;
211 int sd_dhcp_server_attach_event(sd_dhcp_server *server, sd_event *event,
215 assert_return(server, -EINVAL);
216 assert_return(!server->event, -EBUSY);
219 server->event = sd_event_ref(event);
221 r = sd_event_default(&server->event);
226 server->event_priority = priority;
231 int sd_dhcp_server_detach_event(sd_dhcp_server *server) {
232 assert_return(server, -EINVAL);
234 server->event = sd_event_unref(server->event);
239 sd_event *sd_dhcp_server_get_event(sd_dhcp_server *server) {
240 assert_return(server, NULL);
242 return server->event;
245 int sd_dhcp_server_stop(sd_dhcp_server *server) {
246 assert_return(server, -EINVAL);
248 server->receive_message =
249 sd_event_source_unref(server->receive_message);
251 server->fd_raw = safe_close(server->fd_raw);
252 server->fd = safe_close(server->fd);
254 log_dhcp_server(server, "STOPPED");
259 static int dhcp_server_send_unicast_raw(sd_dhcp_server *server,
264 .ll.sll_ifindex = server->ifindex,
268 assert(server);
269 assert(server->ifindex > 0);
270 assert(server->address);
276 dhcp_packet_append_ip_headers(packet, server->address, DHCP_PORT_SERVER,
280 return dhcp_network_send_raw_socket(server->fd_raw, &link, packet, len);
283 static int dhcp_server_send_udp(sd_dhcp_server *server, be32_t destination,
307 assert(server);
308 assert(server->fd > 0);
321 when we gain support for arbitrary number of server addresses
326 pktinfo->ipi_ifindex = server->ifindex;
327 pktinfo->ipi_spec_dst.s_addr = server->address;
329 r = sendmsg(server->fd, &msg, 0);
342 int dhcp_server_send_packet(sd_dhcp_server *server,
348 assert(server);
356 4, &server->address);
368 the server sends any return messages to the ’DHCP server’ port on the
370 field is zero and the ’ciaddr’ field is nonzero, then the server
373 set, then the server broadcasts DHCPOFFER and DHCPACK messages to
375 ’ciaddr’ is zero, then the server unicasts DHCPOFFER and DHCPACK
377 all cases, when ’giaddr’ is zero, the server broadcasts any DHCPNAK
383 different subnet. The server MUST set the broadcast bit in the
396 return dhcp_server_send_udp(server, destination, &packet->dhcp,
399 return dhcp_server_send_udp(server, INADDR_BROADCAST,
406 return dhcp_server_send_unicast_raw(server, packet,
410 static int server_message_init(sd_dhcp_server *server, DHCPPacket **ret,
417 assert(server);
443 static int server_send_offer(sd_dhcp_server *server, DHCPRequest *req,
450 r = server_message_init(server, &packet, DHCP_OFFER, &offset, req);
464 SD_DHCP_OPTION_SUBNET_MASK, 4, &server->netmask);
469 SD_DHCP_OPTION_ROUTER, 4, &server->address);
473 r = dhcp_server_send_packet(server, req, packet, DHCP_OFFER, offset);
480 static int server_send_ack(sd_dhcp_server *server, DHCPRequest *req,
487 r = server_message_init(server, &packet, DHCP_ACK, &offset, req);
501 SD_DHCP_OPTION_SUBNET_MASK, 4, &server->netmask);
506 SD_DHCP_OPTION_ROUTER, 4, &server->address);
510 if (server->n_dns > 0) {
514 sizeof(struct in_addr) * server->n_dns, server->dns);
519 if (server->n_ntp > 0) {
523 sizeof(struct in_addr) * server->n_ntp, server->ntp);
528 if (server->timezone) {
532 strlen(server->timezone), server->timezone);
537 r = dhcp_server_send_packet(server, req, packet, DHCP_ACK, offset);
544 static int server_send_nak(sd_dhcp_server *server, DHCPRequest *req) {
549 r = server_message_init(server, &packet, DHCP_NAK, &offset, req);
553 return dhcp_server_send_packet(server, req, packet, DHCP_NAK, offset);
556 static int server_send_forcerenew(sd_dhcp_server *server, be32_t address,
562 assert(server);
583 r = dhcp_server_send_udp(server, address, &packet->dhcp,
648 static int ensure_sane_request(sd_dhcp_server *server, DHCPRequest *req, DHCPMessage *message) {
674 req->lifetime = MAX(1ULL, server->default_lease_time);
676 if (server->max_lease_time > 0 && req->lifetime > server->max_lease_time)
677 req->lifetime = server->max_lease_time;
682 static int get_pool_offset(sd_dhcp_server *server, be32_t requested_ip) {
683 assert(server);
685 if (!server->pool_size)
688 if (be32toh(requested_ip) < (be32toh(server->subnet) | server->pool_offset) ||
689 be32toh(requested_ip) >= (be32toh(server->subnet) | (server->pool_offset + server->pool_size)))
692 return be32toh(requested_ip & ~server->netmask) - server->pool_offset;
697 int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message,
704 assert(server);
720 r = ensure_sane_request(server, req, message);
725 existing_lease = hashmap_get(server->leases_by_client_id,
734 log_dhcp_server(server, "DISCOVER (0x%x)",
737 if (!server->pool_size)
756 next_offer = hash % server->pool_size;
758 for (i = 0; i < server->pool_size; i++) {
759 if (!server->bound_leases[next_offer]) {
760 address = server->subnet | htobe32(server->pool_offset + next_offer);
763 next_offer = (next_offer + 1) % server->pool_size;
771 r = server_send_offer(server, req, address);
774 log_dhcp_server(server, "could not send offer: %s",
778 log_dhcp_server(server, "OFFER (0x%x)",
786 log_dhcp_server(server, "DECLINE (0x%x): %s", be32toh(req->message->xid), strna(error_message));
800 log_dhcp_server(server, "REQUEST (selecting) (0x%x)",
804 if (req->server_id != server->address)
819 log_dhcp_server(server, "REQUEST (init-reboot) (0x%x)",
831 log_dhcp_server(server, "REQUEST (rebinding/renewing) (0x%x)",
842 pool_offset = get_pool_offset(server, address);
847 server->bound_leases[pool_offset] == existing_lease) {
867 r = sd_event_now(server->event,
878 r = server_send_ack(server, req, address);
881 log_dhcp_server(server, "could not send ack: %s",
889 log_dhcp_server(server, "ACK (0x%x)",
892 server->bound_leases[pool_offset] = lease;
893 hashmap_put(server->leases_by_client_id,
899 r = server_send_nak(server, req);
902 log_dhcp_server(server, "could not send nak: %s",
906 log_dhcp_server(server, "NAK (0x%x)",
918 log_dhcp_server(server, "RELEASE (0x%x)",
927 pool_offset = get_pool_offset(server, req->message->ciaddr);
931 if (server->bound_leases[pool_offset] == existing_lease) {
932 server->bound_leases[pool_offset] = NULL;
933 hashmap_remove(server->leases_by_client_id, existing_lease);
949 sd_dhcp_server *server = userdata;
960 assert(server);
991 if (server->ifindex != info->ipi_ifindex)
998 return dhcp_server_handle_message(server, message, (size_t)len);
1001 int sd_dhcp_server_start(sd_dhcp_server *server) {
1004 assert_return(server, -EINVAL);
1005 assert_return(server->event, -EINVAL);
1006 assert_return(!server->receive_message, -EBUSY);
1007 assert_return(server->fd_raw == -1, -EBUSY);
1008 assert_return(server->fd == -1, -EBUSY);
1009 assert_return(server->address != htobe32(INADDR_ANY), -EUNATCH);
1014 sd_dhcp_server_stop(server);
1017 server->fd_raw = r;
1021 sd_dhcp_server_stop(server);
1024 server->fd = r;
1026 r = sd_event_add_io(server->event, &server->receive_message,
1027 server->fd, EPOLLIN,
1028 server_receive_message, server);
1030 sd_dhcp_server_stop(server);
1034 r = sd_event_source_set_priority(server->receive_message,
1035 server->event_priority);
1037 sd_dhcp_server_stop(server);
1041 log_dhcp_server(server, "STARTED");
1046 int sd_dhcp_server_forcerenew(sd_dhcp_server *server) {
1050 assert_return(server, -EINVAL);
1051 assert(server->bound_leases);
1053 for (i = 0; i < server->pool_size; i++) {
1054 DHCPLease *lease = server->bound_leases[i];
1056 if (!lease || lease == &server->invalid_lease)
1059 r = server_send_forcerenew(server, lease->address,
1065 log_dhcp_server(server, "FORCERENEW");
1071 int sd_dhcp_server_set_timezone(sd_dhcp_server *server, const char *tz) {
1074 assert_return(server, -EINVAL);
1077 if (streq_ptr(tz, server->timezone))
1080 r = free_and_strdup(&server->timezone, tz);
1087 int sd_dhcp_server_set_max_lease_time(sd_dhcp_server *server, uint32_t t) {
1088 assert_return(server, -EINVAL);
1090 if (t == server->max_lease_time)
1093 server->max_lease_time = t;
1097 int sd_dhcp_server_set_default_lease_time(sd_dhcp_server *server, uint32_t t) {
1098 assert_return(server, -EINVAL);
1100 if (t == server->default_lease_time)
1103 server->default_lease_time = t;
1107 int sd_dhcp_server_set_dns(sd_dhcp_server *server, const struct in_addr dns[], unsigned n) {
1108 assert_return(server, -EINVAL);
1111 if (server->n_dns == n &&
1112 memcmp(server->dns, dns, sizeof(struct in_addr) * n) == 0)
1116 server->dns = mfree(server->dns);
1117 server->n_dns = 0;
1125 free(server->dns);
1126 server->dns = c;
1127 server->n_dns = n;
1133 int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr ntp[], unsigned n) {
1134 assert_return(server, -EINVAL);
1137 if (server->n_ntp == n &&
1138 memcmp(server->ntp, ntp, sizeof(struct in_addr) * n) == 0)
1142 server->ntp = mfree(server->ntp);
1143 server->n_ntp = 0;
1151 free(server->ntp);
1152 server->ntp = c;
1153 server->n_ntp = n;