You should have received a copy of the GNU General Public License
along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
*/
/**
/**
* Time where we should cut the connection (timeout) if we don't
* make progress in the state machine (or get a KEEPALIVE_RESPONSE
- * if we are in #S_CONNECTED).
+ * if we are in #GNUNET_TRANSPORT_PS_CONNECTED).
*/
struct GNUNET_TIME_Absolute timeout;
n->id = *peer;
n->ack_state = ACK_UNDEFINED;
n->last_util_transmission = GNUNET_TIME_absolute_get();
+ n->neighbour_receive_quota = GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT;
GNUNET_BANDWIDTH_tracker_init (&n->in_tracker,
&inbound_bw_tracker_update,
n,
GST_ats_is_known (n->primary_address.address,
n->primary_address.session));
}
- n->primary_address.bandwidth_in = bandwidth_in;
- n->primary_address.bandwidth_out = bandwidth_out;
- GST_neighbours_set_incoming_quota (&address->peer,
- bandwidth_in);
- bandwidth_min = GNUNET_BANDWIDTH_value_min (bandwidth_out,
- n->neighbour_receive_quota);
- send_outbound_quota_to_clients (&address->peer,
- bandwidth_min);
+ if (n->primary_address.bandwidth_in.value__ != bandwidth_in.value__)
+ {
+ n->primary_address.bandwidth_in = bandwidth_in;
+ GST_neighbours_set_incoming_quota (&address->peer,
+ bandwidth_in);
+ }
+ if (n->primary_address.bandwidth_out.value__ != bandwidth_out.value__)
+ {
+ n->primary_address.bandwidth_out = bandwidth_out;
+ bandwidth_min = GNUNET_BANDWIDTH_value_min (bandwidth_out,
+ n->neighbour_receive_quota);
+ send_outbound_quota_to_clients (&address->peer,
+ bandwidth_min);
+ }
return GNUNET_OK;
}
now wait for the ACK to finally be connected
- If we sent a SYN_ACK to this peer before */
- if ( (GNUNET_TRANSPORT_PS_SYN_RECV_ACK != n->state) &&
- (ACK_SEND_ACK != n->ack_state))
+ if ( ( (GNUNET_TRANSPORT_PS_SYN_RECV_ACK != n->state) &&
+ (ACK_SEND_ACK != n->ack_state) ) ||
+ (NULL == n->primary_address.address) )
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Received unexpected ACK message from peer `%s' in state %s/%s\n",
GNUNET_TRANSPORT_PS_CONNECTED,
GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT));
+ if (NULL == n->primary_address.address) {
+ /* See issue #3693.
+ * We are in state = PSY_SYN_RECV_ACK or ack_state = ACK_SEND_ACK, which
+ * really means we did try (and succeed) to send a SYN and are waiting for
+ * an ACK.
+ * That suggests that the primary_address used to be non-NULL, but maybe it
+ * got reset to NULL without the state being changed appropriately?
+ */
+ GNUNET_break (0);
+ return GNUNET_OK;
+ }
+
/* Reset backoff for primary address */
GST_ats_block_reset (n->primary_address.address,
n->primary_address.session);
/**
- * Change the incoming quota for the given peer.
+ * Change the incoming quota for the given peer. Updates
+ * our own receive rate and informs the neighbour about
+ * the new quota.
*
* @param neighbour identity of peer to change qutoa for
* @param quota new quota
ntohl (quota.value__), GNUNET_i2s (&n->id));
GNUNET_BANDWIDTH_tracker_update_quota (&n->in_tracker, quota);
if (0 != ntohl (quota.value__))
+ {
+ struct SessionQuotaMessage sqm;
+
+ sqm.header.size = htons (sizeof (struct SessionQuotaMessage));
+ sqm.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_QUOTA);
+ sqm.quota = quota.value__;
+ (void) send_with_session (n,
+ &sqm,
+ sizeof (sqm),
+ UINT32_MAX - 1,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ GNUNET_NO,
+ NULL, NULL);
return;
+ }
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Disconnecting peer `%4s' due to SET_QUOTA\n",
GNUNET_i2s (&n->id));
/* gone already */
return;
}
- n->neighbour_receive_quota = GNUNET_BANDWIDTH_value_init (ntohl (sqm->quota));
+ n->neighbour_receive_quota
+ = GNUNET_BANDWIDTH_value_max (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT,
+ GNUNET_BANDWIDTH_value_init (ntohl (sqm->quota)));
bandwidth_min = GNUNET_BANDWIDTH_value_min (n->primary_address.bandwidth_out,
n->neighbour_receive_quota);
GNUNET_break_op (0);
return;
}
- n->delayed_disconnect_task = GNUNET_SCHEDULER_add_now (&delayed_disconnect, n);
+ if (NULL == n->delayed_disconnect_task)
+ {
+ n->delayed_disconnect_task = GNUNET_SCHEDULER_add_now (&delayed_disconnect,
+ n);
+ }
}