--- a/ChangeLog.API Mon Dec 12 01:05:05 2022 -0600
+++ b/ChangeLog.API Mon Dec 12 01:07:16 2022 -0600
@@ -614,6 +614,10 @@
* purple_plugins_unregister_unload_notify_cb
* purple_plugins_unload_all
+ * purple_pmp_create_map + * purple_pmp_destroy_map * purple_pounce_action_get_attribute
* purple_pounce_action_is_enabled
* purple_pounce_action_register
--- a/libpurple/nat-pmp.c Mon Dec 12 01:05:05 2022 -0600
+++ b/libpurple/nat-pmp.c Mon Dec 12 01:07:16 2022 -0600
@@ -63,27 +63,6 @@
-struct _PurplePmpMapResponse {
-typedef struct _PurplePmpMapResponse PurplePmpMapResponse;
PURPLE_PMP_STATUS_UNDISCOVERED = -1,
PURPLE_PMP_STATUS_UNABLE_TO_DISCOVER,
@@ -102,9 +81,6 @@
* Thanks to R. Matthew Emerson for the fixes on this
-#define PMP_MAP_OPCODE_UDP 1
-#define PMP_MAP_OPCODE_TCP 2
#define PMP_TIMEOUT 250000 /* 250000 useconds */
@@ -392,126 +368,6 @@
return inet_ntoa(publicsockaddr->sin_addr);
-purple_pmp_create_map(PurplePmpType type, unsigned short privateport, unsigned short publicport, int lifetime)
- struct sockaddr_in *gateway;
- gboolean success = TRUE;
- struct timeval req_timeout;
- PurplePmpMapRequest req;
- PurplePmpMapResponse *resp;
- gateway = default_gw();
- purple_debug_info("nat-pmp", "Cannot create mapping on a NULL gateway!\n");
- /* Default port for NAT-PMP is 5351 */
- if (gateway->sin_port != PMP_PORT)
- gateway->sin_port = g_htons(PMP_PORT);
- resp = g_new0(PurplePmpMapResponse, 1);
- req_timeout.tv_sec = 0;
- req_timeout.tv_usec = PMP_TIMEOUT;
- sendfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- memset(&req, 0, sizeof(PurplePmpMapRequest));
- req.opcode = ((type == PURPLE_PMP_TYPE_UDP) ? PMP_MAP_OPCODE_UDP : PMP_MAP_OPCODE_TCP);
- req.privateport = g_htons(privateport); /* What a difference byte ordering makes...d'oh! */
- req.publicport = g_htons(publicport);
- req.lifetime = g_htonl(lifetime);
- /* The NAT-PMP spec says we should attempt to contact the gateway 9 times, doubling the time we wait each time.
- * Even starting with a timeout of 0.1 seconds, that means that we have a total waiting of 204.6 seconds.
- * With the recommended timeout of 0.25 seconds, we're talking 511.5 seconds (8.5 minutes).
- * This seems really silly... if this were nonblocking, a couple retries might be in order, but it's not at present.
- * XXX Make this nonblocking.
- * XXX This code looks like the pmp_get_public_ip() code. Can it be consolidated?
- purple_debug_info("nat-pmp", "Attempting to create a NAT-PMP mapping the private port %d, and the public port %d\n", privateport, publicport);
- purple_debug_info("nat-pmp", "\tTimeout: %ds %dus\n", req_timeout.tv_sec, req_timeout.tv_usec);
- /* TODO: Non-blocking! */
- success = (sendto(sendfd, &req, sizeof(req), 0, (struct sockaddr *)(gateway), sizeof(struct sockaddr)) >= 0);
- purple_debug_info("nat-pmp", "There was an error sending the NAT-PMP mapping request! (%s)\n", g_strerror(errno));
- success = (setsockopt(sendfd, SOL_SOCKET, SO_RCVTIMEO, &req_timeout, sizeof(req_timeout)) >= 0);
- purple_debug_info("nat-pmp", "There was an error setting the socket's options! (%s)\n", g_strerror(errno));
- /* The original code treats EAGAIN as a reason to iterate.. but I've removed iteration. This may be a problem */
- /* TODO: Non-blocking! */
- success = ((recvfrom(sendfd, resp, sizeof(PurplePmpMapResponse), 0, NULL, NULL) >= 0) ||
- purple_debug_info("nat-pmp", "There was an error receiving the response from the NAT-PMP device! (%s)\n", g_strerror(errno));
- success = (resp->opcode == (req.opcode + 128));
- purple_debug_info("nat-pmp", "The opcode for the response from the NAT device (%i) does not match the request opcode (%i + 128 = %i)!\n",
- resp->opcode, req.opcode, req.opcode + 128);
- purple_debug_info("nat-pmp", "Response received from NAT-PMP device:\n");
- purple_debug_info("nat-pmp", "version: %d\n", resp->version);
- purple_debug_info("nat-pmp", "opcode: %d\n", resp->opcode);
- purple_debug_info("nat-pmp", "resultcode: %d\n", g_ntohs(resp->resultcode));
- purple_debug_info("nat-pmp", "epoch: %d\n", g_ntohl(resp->epoch));
- purple_debug_info("nat-pmp", "privateport: %d\n", g_ntohs(resp->privateport));
- purple_debug_info("nat-pmp", "publicport: %d\n", g_ntohs(resp->publicport));
- purple_debug_info("nat-pmp", "lifetime: %d\n", g_ntohl(resp->lifetime));
- /* XXX The private port may actually differ from the one we requested, according to the spec.
- * We don't handle that situation at present.
- * TODO: Look at the result and verify it matches what we wanted; either return a failure if it doesn't,
- * or change network.c to know what to do if the desired private port shifts as a result of the nat-pmp operation.
-purple_pmp_destroy_map(PurplePmpType type, unsigned short privateport)
- success = purple_pmp_create_map(((type == PURPLE_PMP_TYPE_UDP) ? PMP_MAP_OPCODE_UDP : PMP_MAP_OPCODE_TCP),
- purple_debug_warning("nat-pmp", "Failed to properly destroy mapping for %s port %d!\n",
- ((type == PURPLE_PMP_TYPE_UDP) ? "UDP" : "TCP"), privateport);
purple_pmp_network_config_changed_cb(GNetworkMonitor *monitor, gboolean available, gpointer data)
@@ -520,14 +376,6 @@
pmp_info.publicip = NULL;
-purple_pmp_get_handle(void)
@@ -543,22 +391,6 @@
-purple_pmp_create_map(G_GNUC_UNUSED PurplePmpType type,
- G_GNUC_UNUSED unsigned short privateport,
- G_GNUC_UNUSED unsigned short publicport,
- G_GNUC_UNUSED int lifetime)
-purple_pmp_destroy_map(G_GNUC_UNUSED PurplePmpType type,
- G_GNUC_UNUSED unsigned short privateport)
--- a/libpurple/nat-pmp.h Mon Dec 12 01:05:05 2022 -0600
+++ b/libpurple/nat-pmp.h Mon Dec 12 01:07:16 2022 -0600
@@ -33,13 +33,6 @@
-#define PURPLE_PMP_LIFETIME 3600 /* 3600 seconds */
@@ -51,32 +44,6 @@
char *purple_pmp_get_public_ip(void);
- * purple_pmp_create_map:
- * @type: The PurplePmpType
- * @privateport: The private port on which we are listening locally
- * @publicport: The public port on which we are expecting a response
- * @lifetime: The lifetime of the mapping. It is recommended that this
- * be PURPLE_PMP_LIFETIME.
- * Remove the NAT-PMP mapping for a specified type on a specified port
- * Returns: TRUE if successful; FALSE if unsuccessful
-gboolean purple_pmp_create_map(PurplePmpType type, unsigned short privateport,
- unsigned short publicport, int lifetime);
- * purple_pmp_destroy_map:
- * @type: The PurplePmpType
- * @privateport: The private port on which the mapping was previously made
- * Remove the NAT-PMP mapping for a specified type on a specified port
- * Returns: TRUE if successful; FALSE if unsuccessful
-gboolean purple_pmp_destroy_map(PurplePmpType type, unsigned short privateport);
#endif /* PURPLE_NAT_PMP_H */